diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2009-06-01 18:16:10 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2009-06-01 18:16:10 +0000 |
commit | 9f545e245bfb295d27244f41e6a927614b5680c0 (patch) | |
tree | 7b38bdc75edd61a80a8dd1846005185534667ae9 /target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch | |
parent | 2dfc42c43808bfc118206d8c181b97ceea592ce1 (diff) |
remove 2.6.23 support, as the last target using that has been nuked, too
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16275 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch')
-rw-r--r-- | target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch | 7563 |
1 files changed, 0 insertions, 7563 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch b/target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch deleted file mode 100644 index 6527fcedf..000000000 --- a/target/linux/generic-2.6/patches-2.6.23/300-add-mmc-spi-driver.patch +++ /dev/null @@ -1,7563 +0,0 @@ -This is a port of the MMC-SPI driver from 2.6.24.3 ---mb - - ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -100,3 +100,16 @@ config MMC_TIFM_SD - To compile this driver as a module, choose M here: the - module will be called tifm_sd. - -+config MMC_SPI -+ tristate "MMC/SD over SPI (EXPERIMENTAL)" -+ depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL -+ select CRC7 -+ select CRC_ITU_T -+ help -+ Some systems accss MMC/SD cards using a SPI controller instead of -+ using a "native" MMC/SD controller. This has a disadvantage of -+ being relatively high overhead, but a compensating advantage of -+ working on many systems without dedicated MMC/SD controllers. -+ -+ If unsure, or if your system has no SPI master driver, say N. -+ ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -15,4 +15,5 @@ obj-$(CONFIG_MMC_AU1X) += au1xmmc.o - obj-$(CONFIG_MMC_OMAP) += omap.o - obj-$(CONFIG_MMC_AT91) += at91_mci.o - obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o -+obj-$(CONFIG_MMC_SPI) += mmc_spi.o - ---- /dev/null -+++ b/drivers/mmc/host/mmc_spi.c -@@ -0,0 +1,1419 @@ -+/* -+ * mmc_spi.c - Access SD/MMC cards through SPI master controllers -+ * -+ * (C) Copyright 2005, Intec Automation, -+ * Mike Lavender (mike@steroidmicros) -+ * (C) Copyright 2006-2007, David Brownell -+ * (C) Copyright 2007, Axis Communications, -+ * Hans-Peter Nilsson (hp@axis.com) -+ * (C) Copyright 2007, ATRON electronic GmbH, -+ * Jan Nikitenko <jan.nikitenko@gmail.com> -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include <linux/hrtimer.h> -+#include <linux/delay.h> -+#include <linux/bio.h> -+#include <linux/dma-mapping.h> -+#include <linux/crc7.h> -+#include <linux/crc-itu-t.h> -+#include <linux/scatterlist.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/mmc.h> /* for R1_SPI_* bit values */ -+ -+#include <linux/spi/spi.h> -+#include <linux/spi/mmc_spi.h> -+ -+#include <asm/unaligned.h> -+ -+ -+#define sg_page(sg) (sg)->page -+ -+ -+/* NOTES: -+ * -+ * - For now, we won't try to interoperate with a real mmc/sd/sdio -+ * controller, although some of them do have hardware support for -+ * SPI protocol. The main reason for such configs would be mmc-ish -+ * cards like DataFlash, which don't support that "native" protocol. -+ * -+ * We don't have a "DataFlash/MMC/SD/SDIO card slot" abstraction to -+ * switch between driver stacks, and in any case if "native" mode -+ * is available, it will be faster and hence preferable. -+ * -+ * - MMC depends on a different chipselect management policy than the -+ * SPI interface currently supports for shared bus segments: it needs -+ * to issue multiple spi_message requests with the chipselect active, -+ * using the results of one message to decide the next one to issue. -+ * -+ * Pending updates to the programming interface, this driver expects -+ * that it not share the bus with other drivers (precluding conflicts). -+ * -+ * - We tell the controller to keep the chipselect active from the -+ * beginning of an mmc_host_ops.request until the end. So beware -+ * of SPI controller drivers that mis-handle the cs_change flag! -+ * -+ * However, many cards seem OK with chipselect flapping up/down -+ * during that time ... at least on unshared bus segments. -+ */ -+ -+ -+/* -+ * Local protocol constants, internal to data block protocols. -+ */ -+ -+/* Response tokens used to ack each block written: */ -+#define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f) -+#define SPI_RESPONSE_ACCEPTED ((2 << 1)|1) -+#define SPI_RESPONSE_CRC_ERR ((5 << 1)|1) -+#define SPI_RESPONSE_WRITE_ERR ((6 << 1)|1) -+ -+/* Read and write blocks start with these tokens and end with crc; -+ * on error, read tokens act like a subset of R2_SPI_* values. -+ */ -+#define SPI_TOKEN_SINGLE 0xfe /* single block r/w, multiblock read */ -+#define SPI_TOKEN_MULTI_WRITE 0xfc /* multiblock write */ -+#define SPI_TOKEN_STOP_TRAN 0xfd /* terminate multiblock write */ -+ -+#define MMC_SPI_BLOCKSIZE 512 -+ -+ -+/* These fixed timeouts come from the latest SD specs, which say to ignore -+ * the CSD values. The R1B value is for card erase (e.g. the "I forgot the -+ * card's password" scenario); it's mostly applied to STOP_TRANSMISSION after -+ * reads which takes nowhere near that long. Older cards may be able to use -+ * shorter timeouts ... but why bother? -+ */ -+#define readblock_timeout ktime_set(0, 100 * 1000 * 1000) -+#define writeblock_timeout ktime_set(0, 250 * 1000 * 1000) -+#define r1b_timeout ktime_set(3, 0) -+ -+ -+/****************************************************************************/ -+ -+/* -+ * Local Data Structures -+ */ -+ -+/* "scratch" is per-{command,block} data exchanged with the card */ -+struct scratch { -+ u8 status[29]; -+ u8 data_token; -+ __be16 crc_val; -+}; -+ -+struct mmc_spi_host { -+ struct mmc_host *mmc; -+ struct spi_device *spi; -+ -+ unsigned char power_mode; -+ u16 powerup_msecs; -+ -+ struct mmc_spi_platform_data *pdata; -+ -+ /* for bulk data transfers */ -+ struct spi_transfer token, t, crc, early_status; -+ struct spi_message m; -+ -+ /* for status readback */ -+ struct spi_transfer status; -+ struct spi_message readback; -+ -+ /* underlying DMA-aware controller, or null */ -+ struct device *dma_dev; -+ -+ /* buffer used for commands and for message "overhead" */ -+ struct scratch *data; -+ dma_addr_t data_dma; -+ -+ /* Specs say to write ones most of the time, even when the card -+ * has no need to read its input data; and many cards won't care. -+ * This is our source of those ones. -+ */ -+ void *ones; -+ dma_addr_t ones_dma; -+}; -+ -+ -+/****************************************************************************/ -+ -+/* -+ * MMC-over-SPI protocol glue, used by the MMC stack interface -+ */ -+ -+static inline int mmc_cs_off(struct mmc_spi_host *host) -+{ -+ /* chipselect will always be inactive after setup() */ -+ return spi_setup(host->spi); -+} -+ -+static int -+mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len) -+{ -+ int status; -+ -+ if (len > sizeof(*host->data)) { -+ WARN_ON(1); -+ return -EIO; -+ } -+ -+ host->status.len = len; -+ -+ if (host->dma_dev) -+ dma_sync_single_for_device(host->dma_dev, -+ host->data_dma, sizeof(*host->data), -+ DMA_FROM_DEVICE); -+ -+ status = spi_sync(host->spi, &host->readback); -+ -+ if (host->dma_dev) -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*host->data), -+ DMA_FROM_DEVICE); -+ -+ return status; -+} -+ -+static int -+mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte) -+{ -+ u8 *cp = host->data->status; -+ -+ timeout = ktime_add(timeout, ktime_get()); -+ -+ while (1) { -+ int status; -+ unsigned i; -+ -+ status = mmc_spi_readbytes(host, n); -+ if (status < 0) -+ return status; -+ -+ for (i = 0; i < n; i++) { -+ if (cp[i] != byte) -+ return cp[i]; -+ } -+ -+ /* REVISIT investigate msleep() to avoid busy-wait I/O -+ * in at least some cases. -+ */ -+ if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0) -+ break; -+ } -+ return -ETIMEDOUT; -+} -+ -+static inline int -+mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout) -+{ -+ return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0); -+} -+ -+static int mmc_spi_readtoken(struct mmc_spi_host *host) -+{ -+ return mmc_spi_skip(host, readblock_timeout, 1, 0xff); -+} -+ -+ -+/* -+ * Note that for SPI, cmd->resp[0] is not the same data as "native" protocol -+ * hosts return! The low byte holds R1_SPI bits. The next byte may hold -+ * R2_SPI bits ... for SEND_STATUS, or after data read errors. -+ * -+ * cmd->resp[1] holds any four-byte response, for R3 (READ_OCR) and on -+ * newer cards R7 (IF_COND). -+ */ -+ -+static char *maptype(struct mmc_command *cmd) -+{ -+ switch (mmc_spi_resp_type(cmd)) { -+ case MMC_RSP_SPI_R1: return "R1"; -+ case MMC_RSP_SPI_R1B: return "R1B"; -+ case MMC_RSP_SPI_R2: return "R2/R5"; -+ case MMC_RSP_SPI_R3: return "R3/R4/R7"; -+ default: return "?"; -+ } -+} -+ -+/* return zero, else negative errno after setting cmd->error */ -+static int mmc_spi_response_get(struct mmc_spi_host *host, -+ struct mmc_command *cmd, int cs_on) -+{ -+ u8 *cp = host->data->status; -+ u8 *end = cp + host->t.len; -+ int value = 0; -+ char tag[32]; -+ -+ snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", -+ cmd->opcode, maptype(cmd)); -+ -+ /* Except for data block reads, the whole response will already -+ * be stored in the scratch buffer. It's somewhere after the -+ * command and the first byte we read after it. We ignore that -+ * first byte. After STOP_TRANSMISSION command it may include -+ * two data bits, but otherwise it's all ones. -+ */ -+ cp += 8; -+ while (cp < end && *cp == 0xff) -+ cp++; -+ -+ /* Data block reads (R1 response types) may need more data... */ -+ if (cp == end) { -+ unsigned i; -+ -+ cp = host->data->status; -+ -+ /* Card sends N(CR) (== 1..8) bytes of all-ones then one -+ * status byte ... and we already scanned 2 bytes. -+ * -+ * REVISIT block read paths use nasty byte-at-a-time I/O -+ * so it can always DMA directly into the target buffer. -+ * It'd probably be better to memcpy() the first chunk and -+ * avoid extra i/o calls... -+ */ -+ for (i = 2; i < 9; i++) { -+ value = mmc_spi_readbytes(host, 1); -+ if (value < 0) -+ goto done; -+ if (*cp != 0xff) -+ goto checkstatus; -+ } -+ value = -ETIMEDOUT; -+ goto done; -+ } -+ -+checkstatus: -+ if (*cp & 0x80) { -+ dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n", -+ tag, *cp); -+ value = -EBADR; -+ goto done; -+ } -+ -+ cmd->resp[0] = *cp++; -+ cmd->error = 0; -+ -+ /* Status byte: the entire seven-bit R1 response. */ -+ if (cmd->resp[0] != 0) { -+ if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS -+ | R1_SPI_ILLEGAL_COMMAND) -+ & cmd->resp[0]) -+ value = -EINVAL; -+ else if (R1_SPI_COM_CRC & cmd->resp[0]) -+ value = -EILSEQ; -+ else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET) -+ & cmd->resp[0]) -+ value = -EIO; -+ /* else R1_SPI_IDLE, "it's resetting" */ -+ } -+ -+ switch (mmc_spi_resp_type(cmd)) { -+ -+ /* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads) -+ * and less-common stuff like various erase operations. -+ */ -+ case MMC_RSP_SPI_R1B: -+ /* maybe we read all the busy tokens already */ -+ while (cp < end && *cp == 0) -+ cp++; -+ if (cp == end) -+ mmc_spi_wait_unbusy(host, r1b_timeout); -+ break; -+ -+ /* SPI R2 == R1 + second status byte; SEND_STATUS -+ * SPI R5 == R1 + data byte; IO_RW_DIRECT -+ */ -+ case MMC_RSP_SPI_R2: -+ cmd->resp[0] |= *cp << 8; -+ break; -+ -+ /* SPI R3, R4, or R7 == R1 + 4 bytes */ -+ case MMC_RSP_SPI_R3: -+ cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp)); -+ break; -+ -+ /* SPI R1 == just one status byte */ -+ case MMC_RSP_SPI_R1: -+ break; -+ -+ default: -+ dev_dbg(&host->spi->dev, "bad response type %04x\n", -+ mmc_spi_resp_type(cmd)); -+ if (value >= 0) -+ value = -EINVAL; -+ goto done; -+ } -+ -+ if (value < 0) -+ dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n", -+ tag, cmd->resp[0], cmd->resp[1]); -+ -+ /* disable chipselect on errors and some success cases */ -+ if (value >= 0 && cs_on) -+ return value; -+done: -+ if (value < 0) -+ cmd->error = value; -+ mmc_cs_off(host); -+ return value; -+} -+ -+/* Issue command and read its response. -+ * Returns zero on success, negative for error. -+ * -+ * On error, caller must cope with mmc core retry mechanism. That -+ * means immediate low-level resubmit, which affects the bus lock... -+ */ -+static int -+mmc_spi_command_send(struct mmc_spi_host *host, -+ struct mmc_request *mrq, -+ struct mmc_command *cmd, int cs_on) -+{ -+ struct scratch *data = host->data; -+ u8 *cp = data->status; -+ u32 arg = cmd->arg; -+ int status; -+ struct spi_transfer *t; -+ -+ /* We can handle most commands (except block reads) in one full -+ * duplex I/O operation before either starting the next transfer -+ * (data block or command) or else deselecting the card. -+ * -+ * First, write 7 bytes: -+ * - an all-ones byte to ensure the card is ready -+ * - opcode byte (plus start and transmission bits) -+ * - four bytes of big-endian argument -+ * - crc7 (plus end bit) ... always computed, it's cheap -+ * -+ * We init the whole buffer to all-ones, which is what we need -+ * to write while we're reading (later) response data. -+ */ -+ memset(cp++, 0xff, sizeof(data->status)); -+ -+ *cp++ = 0x40 | cmd->opcode; -+ *cp++ = (u8)(arg >> 24); -+ *cp++ = (u8)(arg >> 16); -+ *cp++ = (u8)(arg >> 8); -+ *cp++ = (u8)arg; -+ *cp++ = (crc7(0, &data->status[1], 5) << 1) | 0x01; -+ -+ /* Then, read up to 13 bytes (while writing all-ones): -+ * - N(CR) (== 1..8) bytes of all-ones -+ * - status byte (for all response types) -+ * - the rest of the response, either: -+ * + nothing, for R1 or R1B responses -+ * + second status byte, for R2 responses -+ * + four data bytes, for R3 and R7 responses -+ * -+ * Finally, read some more bytes ... in the nice cases we know in -+ * advance how many, and reading 1 more is always OK: -+ * - N(EC) (== 0..N) bytes of all-ones, before deselect/finish -+ * - N(RC) (== 1..N) bytes of all-ones, before next command -+ * - N(WR) (== 1..N) bytes of all-ones, before data write -+ * -+ * So in those cases one full duplex I/O of at most 21 bytes will -+ * handle the whole command, leaving the card ready to receive a -+ * data block or new command. We do that whenever we can, shaving -+ * CPU and IRQ costs (especially when using DMA or FIFOs). -+ * -+ * There are two other cases, where it's not generally practical -+ * to rely on a single I/O: -+ * -+ * - R1B responses need at least N(EC) bytes of all-zeroes. -+ * -+ * In this case we can *try* to fit it into one I/O, then -+ * maybe read more data later. -+ * -+ * - Data block reads are more troublesome, since a variable -+ * number of padding bytes precede the token and data. -+ * + N(CX) (== 0..8) bytes of all-ones, before CSD or CID -+ * + N(AC) (== 1..many) bytes of all-ones -+ * -+ * In this case we currently only have minimal speedups here: -+ * when N(CR) == 1 we can avoid I/O in response_get(). -+ */ -+ if (cs_on && (mrq->data->flags & MMC_DATA_READ)) { -+ cp += 2; /* min(N(CR)) + status */ -+ /* R1 */ -+ } else { -+ cp += 10; /* max(N(CR)) + status + min(N(RC),N(WR)) */ -+ if (cmd->flags & MMC_RSP_SPI_S2) /* R2/R5 */ -+ cp++; -+ else if (cmd->flags & MMC_RSP_SPI_B4) /* R3/R4/R7 */ -+ cp += 4; -+ else if (cmd->flags & MMC_RSP_BUSY) /* R1B */ -+ cp = data->status + sizeof(data->status); -+ /* else: R1 (most commands) */ -+ } -+ -+ dev_dbg(&host->spi->dev, " mmc_spi: CMD%d, resp %s\n", -+ cmd->opcode, maptype(cmd)); -+ -+ /* send command, leaving chipselect active */ -+ spi_message_init(&host->m); -+ -+ t = &host->t; -+ memset(t, 0, sizeof(*t)); -+ t->tx_buf = t->rx_buf = data->status; -+ t->tx_dma = t->rx_dma = host->data_dma; -+ t->len = cp - data->status; -+ t->cs_change = 1; -+ spi_message_add_tail(t, &host->m); -+ -+ if (host->dma_dev) { -+ host->m.is_dma_mapped = 1; -+ dma_sync_single_for_device(host->dma_dev, -+ host->data_dma, sizeof(*host->data), -+ DMA_BIDIRECTIONAL); -+ } -+ status = spi_sync(host->spi, &host->m); -+ -+ if (host->dma_dev) -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*host->data), -+ DMA_BIDIRECTIONAL); -+ if (status < 0) { -+ dev_dbg(&host->spi->dev, " ... write returned %d\n", status); -+ cmd->error = status; -+ return status; -+ } -+ -+ /* after no-data commands and STOP_TRANSMISSION, chipselect off */ -+ return mmc_spi_response_get(host, cmd, cs_on); -+} -+ -+/* Build data message with up to four separate transfers. For TX, we -+ * start by writing the data token. And in most cases, we finish with -+ * a status transfer. -+ * -+ * We always provide TX data for data and CRC. The MMC/SD protocol -+ * requires us to write ones; but Linux defaults to writing zeroes; -+ * so we explicitly initialize it to all ones on RX paths. -+ * -+ * We also handle DMA mapping, so the underlying SPI controller does -+ * not need to (re)do it for each message. -+ */ -+static void -+mmc_spi_setup_data_message( -+ struct mmc_spi_host *host, -+ int multiple, -+ enum dma_data_direction direction) -+{ -+ struct spi_transfer *t; -+ struct scratch *scratch = host->data; -+ dma_addr_t dma = host->data_dma; -+ -+ spi_message_init(&host->m); -+ if (dma) -+ host->m.is_dma_mapped = 1; -+ -+ /* for reads, readblock() skips 0xff bytes before finding -+ * the token; for writes, this transfer issues that token. -+ */ -+ if (direction == DMA_TO_DEVICE) { -+ t = &host->token; -+ memset(t, 0, sizeof(*t)); -+ t->len = 1; -+ if (multiple) -+ scratch->data_token = SPI_TOKEN_MULTI_WRITE; -+ else -+ scratch->data_token = SPI_TOKEN_SINGLE; -+ t->tx_buf = &scratch->data_token; -+ if (dma) -+ t->tx_dma = dma + offsetof(struct scratch, data_token); -+ spi_message_add_tail(t, &host->m); -+ } -+ -+ /* Body of transfer is buffer, then CRC ... -+ * either TX-only, or RX with TX-ones. -+ */ -+ t = &host->t; -+ memset(t, 0, sizeof(*t)); -+ t->tx_buf = host->ones; -+ t->tx_dma = host->ones_dma; -+ /* length and actual buffer info are written later */ -+ spi_message_add_tail(t, &host->m); -+ -+ t = &host->crc; -+ memset(t, 0, sizeof(*t)); -+ t->len = 2; -+ if (direction == DMA_TO_DEVICE) { -+ /* the actual CRC may get written later */ -+ t->tx_buf = &scratch->crc_val; -+ if (dma) -+ t->tx_dma = dma + offsetof(struct scratch, crc_val); -+ } else { -+ t->tx_buf = host->ones; -+ t->tx_dma = host->ones_dma; -+ t->rx_buf = &scratch->crc_val; -+ if (dma) -+ t->rx_dma = dma + offsetof(struct scratch, crc_val); -+ } -+ spi_message_add_tail(t, &host->m); -+ -+ /* -+ * A single block read is followed by N(EC) [0+] all-ones bytes -+ * before deselect ... don't bother. -+ * -+ * Multiblock reads are followed by N(AC) [1+] all-ones bytes before -+ * the next block is read, or a STOP_TRANSMISSION is issued. We'll -+ * collect that single byte, so readblock() doesn't need to. -+ * -+ * For a write, the one-byte data response follows immediately, then -+ * come zero or more busy bytes, then N(WR) [1+] all-ones bytes. -+ * Then single block reads may deselect, and multiblock ones issue -+ * the next token (next data block, or STOP_TRAN). We can try to -+ * minimize I/O ops by using a single read to collect end-of-busy. -+ */ -+ if (multiple || direction == DMA_TO_DEVICE) { -+ t = &host->early_status; -+ memset(t, 0, sizeof(*t)); -+ t->len = (direction == DMA_TO_DEVICE) -+ ? sizeof(scratch->status) -+ : 1; -+ t->tx_buf = host->ones; -+ t->tx_dma = host->ones_dma; -+ t->rx_buf = scratch->status; -+ if (dma) -+ t->rx_dma = dma + offsetof(struct scratch, status); -+ t->cs_change = 1; -+ spi_message_add_tail(t, &host->m); -+ } -+} -+ -+/* -+ * Write one block: -+ * - caller handled preceding N(WR) [1+] all-ones bytes -+ * - data block -+ * + token -+ * + data bytes -+ * + crc16 -+ * - an all-ones byte ... card writes a data-response byte -+ * - followed by N(EC) [0+] all-ones bytes, card writes zero/'busy' -+ * -+ * Return negative errno, else success. -+ */ -+static int -+mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) -+{ -+ struct spi_device *spi = host->spi; -+ int status, i; -+ struct scratch *scratch = host->data; -+ -+ if (host->mmc->use_spi_crc) -+ scratch->crc_val = cpu_to_be16( -+ crc_itu_t(0, t->tx_buf, t->len)); -+ if (host->dma_dev) -+ dma_sync_single_for_device(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ -+ status = spi_sync(spi, &host->m); -+ -+ if (status != 0) { -+ dev_dbg(&spi->dev, "write error (%d)\n", status); -+ return status; -+ } -+ -+ if (host->dma_dev) -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ -+ /* -+ * Get the transmission data-response reply. It must follow -+ * immediately after the data block we transferred. This reply -+ * doesn't necessarily tell whether the write operation succeeded; -+ * it just says if the transmission was ok and whether *earlier* -+ * writes succeeded; see the standard. -+ */ -+ switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) { -+ case SPI_RESPONSE_ACCEPTED: -+ status = 0; -+ break; -+ case SPI_RESPONSE_CRC_ERR: -+ /* host shall then issue MMC_STOP_TRANSMISSION */ -+ status = -EILSEQ; -+ break; -+ case SPI_RESPONSE_WRITE_ERR: -+ /* host shall then issue MMC_STOP_TRANSMISSION, -+ * and should MMC_SEND_STATUS to sort it out -+ */ -+ status = -EIO; -+ break; -+ default: -+ status = -EPROTO; -+ break; -+ } -+ if (status != 0) { -+ dev_dbg(&spi->dev, "write error %02x (%d)\n", -+ scratch->status[0], status); -+ return status; -+ } -+ -+ t->tx_buf += t->len; -+ if (host->dma_dev) -+ t->tx_dma += t->len; -+ -+ /* Return when not busy. If we didn't collect that status yet, -+ * we'll need some more I/O. -+ */ -+ for (i = 1; i < sizeof(scratch->status); i++) { -+ if (scratch->status[i] != 0) -+ return 0; -+ } -+ return mmc_spi_wait_unbusy(host, writeblock_timeout); -+} -+ -+/* -+ * Read one block: -+ * - skip leading all-ones bytes ... either -+ * + N(AC) [1..f(clock,CSD)] usually, else -+ * + N(CX) [0..8] when reading CSD or CID -+ * - data block -+ * + token ... if error token, no data or crc -+ * + data bytes -+ * + crc16 -+ * -+ * After single block reads, we're done; N(EC) [0+] all-ones bytes follow -+ * before dropping chipselect. -+ * -+ * For multiblock reads, caller either reads the next block or issues a -+ * STOP_TRANSMISSION command. -+ */ -+static int -+mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) -+{ -+ struct spi_device *spi = host->spi; -+ int status; -+ struct scratch *scratch = host->data; -+ -+ /* At least one SD card sends an all-zeroes byte when N(CX) -+ * applies, before the all-ones bytes ... just cope with that. -+ */ -+ status = mmc_spi_readbytes(host, 1); -+ if (status < 0) -+ return status; -+ status = scratch->status[0]; -+ if (status == 0xff || status == 0) -+ status = mmc_spi_readtoken(host); -+ -+ if (status == SPI_TOKEN_SINGLE) { -+ if (host->dma_dev) { -+ dma_sync_single_for_device(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ dma_sync_single_for_device(host->dma_dev, -+ t->rx_dma, t->len, -+ DMA_FROM_DEVICE); -+ } -+ -+ status = spi_sync(spi, &host->m); -+ -+ if (host->dma_dev) { -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ dma_sync_single_for_cpu(host->dma_dev, -+ t->rx_dma, t->len, -+ DMA_FROM_DEVICE); -+ } -+ -+ } else { -+ dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status); -+ -+ /* we've read extra garbage, timed out, etc */ -+ if (status < 0) -+ return status; -+ -+ /* low four bits are an R2 subset, fifth seems to be -+ * vendor specific ... map them all to generic error.. -+ */ -+ return -EIO; -+ } -+ -+ if (host->mmc->use_spi_crc) { -+ u16 crc = crc_itu_t(0, t->rx_buf, t->len); -+ -+ be16_to_cpus(&scratch->crc_val); -+ if (scratch->crc_val != crc) { -+ dev_dbg(&spi->dev, "read - crc error: crc_val=0x%04x, " -+ "computed=0x%04x len=%d\n", -+ scratch->crc_val, crc, t->len); -+ return -EILSEQ; -+ } -+ } -+ -+ t->rx_buf += t->len; -+ if (host->dma_dev) -+ t->rx_dma += t->len; -+ -+ return 0; -+} -+ -+/* -+ * An MMC/SD data stage includes one or more blocks, optional CRCs, -+ * and inline handshaking. That handhaking makes it unlike most -+ * other SPI protocol stacks. -+ */ -+static void -+mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, -+ struct mmc_data *data, u32 blk_size) -+{ -+ struct spi_device *spi = host->spi; -+ struct device *dma_dev = host->dma_dev; -+ struct spi_transfer *t; -+ enum dma_data_direction direction; -+ struct scatterlist *sg; -+ unsigned n_sg; -+ int multiple = (data->blocks > 1); -+ -+ if (data->flags & MMC_DATA_READ) -+ direction = DMA_FROM_DEVICE; -+ else -+ direction = DMA_TO_DEVICE; -+ mmc_spi_setup_data_message(host, multiple, direction); -+ t = &host->t; -+ -+ /* Handle scatterlist segments one at a time, with synch for -+ * each 512-byte block -+ */ -+ for (sg = data->sg, n_sg = data->sg_len; n_sg; n_sg--, sg++) { -+ int status = 0; -+ dma_addr_t dma_addr = 0; -+ void *kmap_addr; -+ unsigned length = sg->length; -+ enum dma_data_direction dir = direction; -+ -+ /* set up dma mapping for controller drivers that might -+ * use DMA ... though they may fall back to PIO -+ */ -+ if (dma_dev) { -+ /* never invalidate whole *shared* pages ... */ -+ if ((sg->offset != 0 || length != PAGE_SIZE) -+ && dir == DMA_FROM_DEVICE) -+ dir = DMA_BIDIRECTIONAL; -+ -+ dma_addr = dma_map_page(dma_dev, sg_page(sg), 0, -+ PAGE_SIZE, dir); -+ if (direction == DMA_TO_DEVICE) -+ t->tx_dma = dma_addr + sg->offset; -+ else -+ t->rx_dma = dma_addr + sg->offset; -+ } -+ -+ /* allow pio too; we don't allow highmem */ -+ kmap_addr = kmap(sg_page(sg)); -+ if (direction == DMA_TO_DEVICE) -+ t->tx_buf = kmap_addr + sg->offset; -+ else -+ t->rx_buf = kmap_addr + sg->offset; -+ -+ /* transfer each block, and update request status */ -+ while (length) { -+ t->len = min(length, blk_size); -+ -+ dev_dbg(&host->spi->dev, -+ " mmc_spi: %s block, %d bytes\n", -+ (direction == DMA_TO_DEVICE) -+ ? "write" -+ : "read", -+ t->len); -+ -+ if (direction == DMA_TO_DEVICE) -+ status = mmc_spi_writeblock(host, t); -+ else -+ status = mmc_spi_readblock(host, t); -+ if (status < 0) -+ break; -+ -+ data->bytes_xfered += t->len; -+ length -= t->len; -+ -+ if (!multiple) -+ break; -+ } -+ -+ /* discard mappings */ -+ if (direction == DMA_FROM_DEVICE) -+ flush_kernel_dcache_page(sg_page(sg)); -+ kunmap(sg_page(sg)); -+ if (dma_dev) -+ dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir); -+ -+ if (status < 0) { -+ data->error = status; -+ dev_dbg(&spi->dev, "%s status %d\n", -+ (direction == DMA_TO_DEVICE) -+ ? "write" : "read", -+ status); -+ break; -+ } -+ } -+ -+ /* NOTE some docs describe an MMC-only SET_BLOCK_COUNT (CMD23) that -+ * can be issued before multiblock writes. Unlike its more widely -+ * documented analogue for SD cards (SET_WR_BLK_ERASE_COUNT, ACMD23), -+ * that can affect the STOP_TRAN logic. Complete (and current) -+ * MMC specs should sort that out before Linux starts using CMD23. -+ */ -+ if (direction == DMA_TO_DEVICE && multiple) { -+ struct scratch *scratch = host->data; -+ int tmp; -+ const unsigned statlen = sizeof(scratch->status); -+ -+ dev_dbg(&spi->dev, " mmc_spi: STOP_TRAN\n"); -+ -+ /* Tweak the per-block message we set up earlier by morphing -+ * it to hold single buffer with the token followed by some -+ * all-ones bytes ... skip N(BR) (0..1), scan the rest for -+ * "not busy any longer" status, and leave chip selected. -+ */ -+ INIT_LIST_HEAD(&host->m.transfers); -+ list_add(&host->early_status.transfer_list, -+ &host->m.transfers); -+ -+ memset(scratch->status, 0xff, statlen); -+ scratch->status[0] = SPI_TOKEN_STOP_TRAN; -+ -+ host->early_status.tx_buf = host->early_status.rx_buf; -+ host->early_status.tx_dma = host->early_status.rx_dma; -+ host->early_status.len = statlen; -+ -+ if (host->dma_dev) -+ dma_sync_single_for_device(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ -+ tmp = spi_sync(spi, &host->m); -+ -+ if (host->dma_dev) -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*scratch), -+ DMA_BIDIRECTIONAL); -+ -+ if (tmp < 0) { -+ if (!data->error) -+ data->error = tmp; -+ return; -+ } -+ -+ /* Ideally we collected "not busy" status with one I/O, -+ * avoiding wasteful byte-at-a-time scanning... but more -+ * I/O is often needed. -+ */ -+ for (tmp = 2; tmp < statlen; tmp++) { -+ if (scratch->status[tmp] != 0) -+ return; -+ } -+ tmp = mmc_spi_wait_unbusy(host, writeblock_timeout); -+ if (tmp < 0 && !data->error) -+ data->error = tmp; -+ } -+} -+ -+/****************************************************************************/ -+ -+/* -+ * MMC driver implementation -- the interface to the MMC stack -+ */ -+ -+static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct mmc_spi_host *host = mmc_priv(mmc); -+ int status = -EINVAL; -+ -+#ifdef DEBUG -+ /* MMC core and layered drivers *MUST* issue SPI-aware commands */ -+ { -+ struct mmc_command *cmd; -+ int invalid = 0; -+ -+ cmd = mrq->cmd; -+ if (!mmc_spi_resp_type(cmd)) { -+ dev_dbg(&host->spi->dev, "bogus command\n"); -+ cmd->error = -EINVAL; -+ invalid = 1; -+ } -+ -+ cmd = mrq->stop; -+ if (cmd && !mmc_spi_resp_type(cmd)) { -+ dev_dbg(&host->spi->dev, "bogus STOP command\n"); -+ cmd->error = -EINVAL; -+ invalid = 1; -+ } -+ -+ if (invalid) { -+ dump_stack(); -+ mmc_request_done(host->mmc, mrq); -+ return; -+ } -+ } -+#endif -+ -+ /* issue command; then optionally data and stop */ -+ status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL); -+ if (status == 0 && mrq->data) { -+ mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz); -+ if (mrq->stop) -+ status = mmc_spi_command_send(host, mrq, mrq->stop, 0); -+ else -+ mmc_cs_off(host); -+ } -+ -+ mmc_request_done(host->mmc, mrq); -+} -+ -+/* See Section 6.4.1, in SD "Simplified Physical Layer Specification 2.0" -+ * -+ * NOTE that here we can't know that the card has just been powered up; -+ * not all MMC/SD sockets support power switching. -+ * -+ * FIXME when the card is still in SPI mode, e.g. from a previous kernel, -+ * this doesn't seem to do the right thing at all... -+ */ -+static void mmc_spi_initsequence(struct mmc_spi_host *host) -+{ -+ /* Try to be very sure any previous command has completed; -+ * wait till not-busy, skip debris from any old commands. -+ */ -+ mmc_spi_wait_unbusy(host, r1b_timeout); -+ mmc_spi_readbytes(host, 10); -+ -+ /* -+ * Do a burst with chipselect active-high. We need to do this to -+ * meet the requirement of 74 clock cycles with both chipselect -+ * and CMD (MOSI) high before CMD0 ... after the card has been -+ * powered up to Vdd(min), and so is ready to take commands. -+ * -+ * Some cards are particularly needy of this (e.g. Viking "SD256") -+ * while most others don't seem to care. -+ * -+ * Note that this is one of the places MMC/SD plays games with the -+ * SPI protocol. Another is that when chipselect is released while -+ * the card returns BUSY status, the clock must issue several cycles -+ * with chipselect high before the card will stop driving its output. -+ */ -+ host->spi->mode |= SPI_CS_HIGH; -+ if (spi_setup(host->spi) != 0) { -+ /* Just warn; most cards work without it. */ -+ dev_warn(&host->spi->dev, -+ "can't change chip-select polarity\n"); -+ host->spi->mode &= ~SPI_CS_HIGH; -+ } else { -+ mmc_spi_readbytes(host, 18); -+ -+ host->spi->mode &= ~SPI_CS_HIGH; -+ if (spi_setup(host->spi) != 0) { -+ /* Wot, we can't get the same setup we had before? */ -+ dev_err(&host->spi->dev, -+ "can't restore chip-select polarity\n"); -+ } -+ } -+} -+ -+static char *mmc_powerstring(u8 power_mode) -+{ -+ switch (power_mode) { -+ case MMC_POWER_OFF: return "off"; -+ case MMC_POWER_UP: return "up"; -+ case MMC_POWER_ON: return "on"; -+ } -+ return "?"; -+} -+ -+static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct mmc_spi_host *host = mmc_priv(mmc); -+ -+ if (host->power_mode != ios->power_mode) { -+ int canpower; -+ -+ canpower = host->pdata && host->pdata->setpower; -+ -+ dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n", -+ mmc_powerstring(ios->power_mode), -+ ios->vdd, -+ canpower ? ", can switch" : ""); -+ -+ /* switch power on/off if possible, accounting for -+ * max 250msec powerup time if needed. -+ */ -+ if (canpower) { -+ switch (ios->power_mode) { -+ case MMC_POWER_OFF: -+ case MMC_POWER_UP: -+ host->pdata->setpower(&host->spi->dev, -+ ios->vdd); -+ if (ios->power_mode == MMC_POWER_UP) -+ msleep(host->powerup_msecs); -+ } -+ } -+ -+ /* See 6.4.1 in the simplified SD card physical spec 2.0 */ -+ if (ios->power_mode == MMC_POWER_ON) -+ mmc_spi_initsequence(host); -+ -+ /* If powering down, ground all card inputs to avoid power -+ * delivery from data lines! On a shared SPI bus, this -+ * will probably be temporary; 6.4.2 of the simplified SD -+ * spec says this must last at least 1msec. -+ * -+ * - Clock low means CPOL 0, e.g. mode 0 -+ * - MOSI low comes from writing zero -+ * - Chipselect is usually active low... -+ */ -+ if (canpower && ios->power_mode == MMC_POWER_OFF) { -+ int mres; -+ -+ host->spi->mode &= ~(SPI_CPOL|SPI_CPHA); -+ mres = spi_setup(host->spi); -+ if (mres < 0) -+ dev_dbg(&host->spi->dev, -+ "switch to SPI mode 0 failed\n"); -+ -+ if (spi_w8r8(host->spi, 0x00) < 0) -+ dev_dbg(&host->spi->dev, -+ "put spi signals to low failed\n"); -+ -+ /* -+ * Now clock should be low due to spi mode 0; -+ * MOSI should be low because of written 0x00; -+ * chipselect should be low (it is active low) -+ * power supply is off, so now MMC is off too! -+ * -+ * FIXME no, chipselect can be high since the -+ * device is inactive and SPI_CS_HIGH is clear... -+ */ -+ msleep(10); -+ if (mres == 0) { -+ host->spi->mode |= (SPI_CPOL|SPI_CPHA); -+ mres = spi_setup(host->spi); -+ if (mres < 0) -+ dev_dbg(&host->spi->dev, -+ "switch back to SPI mode 3" -+ " failed\n"); -+ } -+ } -+ -+ host->power_mode = ios->power_mode; -+ } -+ -+ if (host->spi->max_speed_hz != ios->clock && ios->clock != 0) { -+ int status; -+ -+ host->spi->max_speed_hz = ios->clock; -+ status = spi_setup(host->spi); -+ dev_dbg(&host->spi->dev, -+ "mmc_spi: clock to %d Hz, %d\n", -+ host->spi->max_speed_hz, status); -+ } -+} -+ -+static int mmc_spi_get_ro(struct mmc_host *mmc) -+{ -+ struct mmc_spi_host *host = mmc_priv(mmc); -+ -+ if (host->pdata && host->pdata->get_ro) -+ return host->pdata->get_ro(mmc->parent); -+ /* board doesn't support read only detection; assume writeable */ -+ return 0; -+} -+ -+ -+static const struct mmc_host_ops mmc_spi_ops = { -+ .request = mmc_spi_request, -+ .set_ios = mmc_spi_set_ios, -+ .get_ro = mmc_spi_get_ro, -+}; -+ -+ -+/****************************************************************************/ -+ -+/* -+ * SPI driver implementation -+ */ -+ -+static irqreturn_t -+mmc_spi_detect_irq(int irq, void *mmc) -+{ -+ struct mmc_spi_host *host = mmc_priv(mmc); -+ u16 delay_msec = max(host->pdata->detect_delay, (u16)100); -+ -+ mmc_detect_change(mmc, msecs_to_jiffies(delay_msec)); -+ return IRQ_HANDLED; -+} -+ -+struct count_children { -+ unsigned n; -+ struct bus_type *bus; -+}; -+ -+static int maybe_count_child(struct device *dev, void *c) -+{ -+ struct count_children *ccp = c; -+ -+ if (dev->bus == ccp->bus) { -+ if (ccp->n) -+ return -EBUSY; -+ ccp->n++; -+ } -+ return 0; -+} -+ -+static int mmc_spi_probe(struct spi_device *spi) -+{ -+ void *ones; -+ struct mmc_host *mmc; -+ struct mmc_spi_host *host; -+ int status; -+ -+ /* MMC and SD specs only seem to care that sampling is on the -+ * rising edge ... meaning SPI modes 0 or 3. So either SPI mode -+ * should be legit. We'll use mode 0 since it seems to be a -+ * bit less troublesome on some hardware ... unclear why. -+ */ -+ spi->mode = SPI_MODE_0; -+ spi->bits_per_word = 8; -+ -+ status = spi_setup(spi); -+ if (status < 0) { -+ dev_dbg(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n", -+ spi->mode, spi->max_speed_hz / 1000, -+ status); -+ return status; -+ } -+ -+ /* We can use the bus safely iff nobody else will interfere with us. -+ * Most commands consist of one SPI message to issue a command, then -+ * several more to collect its response, then possibly more for data -+ * transfer. Clocking access to other devices during that period will -+ * corrupt the command execution. -+ * -+ * Until we have software primitives which guarantee non-interference, -+ * we'll aim for a hardware-level guarantee. -+ * -+ * REVISIT we can't guarantee another device won't be added later... -+ */ -+ if (spi->master->num_chipselect > 1) { -+ struct count_children cc; -+ -+ cc.n = 0; -+ cc.bus = spi->dev.bus; -+ status = device_for_each_child(spi->dev.parent, &cc, -+ maybe_count_child); -+ if (status < 0) { -+ dev_err(&spi->dev, "can't share SPI bus\n"); -+ return status; -+ } -+ -+ dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n"); -+ } -+ -+ /* We need a supply of ones to transmit. This is the only time -+ * the CPU touches these, so cache coherency isn't a concern. -+ * -+ * NOTE if many systems use more than one MMC-over-SPI connector -+ * it'd save some memory to share this. That's evidently rare. -+ */ -+ status = -ENOMEM; -+ ones = kmalloc(MMC_SPI_BLOCKSIZE, GFP_KERNEL); -+ if (!ones) -+ goto nomem; -+ memset(ones, 0xff, MMC_SPI_BLOCKSIZE); -+ -+ mmc = mmc_alloc_host(sizeof(*host), &spi->dev); -+ if (!mmc) -+ goto nomem; -+ -+ mmc->ops = &mmc_spi_ops; -+ mmc->max_blk_size = MMC_SPI_BLOCKSIZE; -+ -+ /* As long as we keep track of the number of successfully -+ * transmitted blocks, we're good for multiwrite. -+ */ -+ mmc->caps = MMC_CAP_SPI | MMC_CAP_MULTIWRITE; -+ -+ /* SPI doesn't need the lowspeed device identification thing for -+ * MMC or SD cards, since it never comes up in open drain mode. -+ * That's good; some SPI masters can't handle very low speeds! -+ * -+ * However, low speed SDIO cards need not handle over 400 KHz; -+ * that's the only reason not to use a few MHz for f_min (until -+ * the upper layer reads the target frequency from the CSD). -+ */ -+ mmc->f_min = 400000; -+ mmc->f_max = spi->max_speed_hz; -+ -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ host->spi = spi; -+ -+ host->ones = ones; -+ -+ /* Platform data is used to hook up things like card sensing -+ * and power switching gpios. -+ */ -+ host->pdata = spi->dev.platform_data; -+ if (host->pdata) -+ mmc->ocr_avail = host->pdata->ocr_mask; -+ if (!mmc->ocr_avail) { -+ dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n"); -+ mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; -+ } -+ if (host->pdata && host->pdata->setpower) { -+ host->powerup_msecs = host->pdata->powerup_msecs; -+ if (!host->powerup_msecs || host->powerup_msecs > 250) -+ host->powerup_msecs = 250; -+ } -+ -+ dev_set_drvdata(&spi->dev, mmc); -+ -+ /* preallocate dma buffers */ -+ host->data = kmalloc(sizeof(*host->data), GFP_KERNEL); -+ if (!host->data) -+ goto fail_nobuf1; -+ -+//FIXME -+#if 0 -+ if (spi->master->dev.parent->dma_mask) { -+ struct device *dev = spi->master->dev.parent; -+ -+ host->dma_dev = dev; -+ host->ones_dma = dma_map_single(dev, ones, -+ MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); -+ host->data_dma = dma_map_single(dev, host->data, -+ sizeof(*host->data), DMA_BIDIRECTIONAL); -+ -+ /* REVISIT in theory those map operations can fail... */ -+ -+ dma_sync_single_for_cpu(host->dma_dev, -+ host->data_dma, sizeof(*host->data), -+ DMA_BIDIRECTIONAL); -+ } -+#endif -+ -+ /* setup message for status/busy readback */ -+ spi_message_init(&host->readback); -+ host->readback.is_dma_mapped = (host->dma_dev != NULL); -+ -+ spi_message_add_tail(&host->status, &host->readback); -+ host->status.tx_buf = host->ones; -+ host->status.tx_dma = host->ones_dma; -+ host->status.rx_buf = &host->data->status; -+ host->status.rx_dma = host->data_dma + offsetof(struct scratch, status); -+ host->status.cs_change = 1; -+ -+ /* register card detect irq */ -+ if (host->pdata && host->pdata->init) { -+ status = host->pdata->init(&spi->dev, mmc_spi_detect_irq, mmc); -+ if (status != 0) -+ goto fail_glue_init; -+ } -+ -+ status = mmc_add_host(mmc); -+ if (status != 0) -+ goto fail_add_host; -+ -+ dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n", -+ mmc->class_dev.bus_id, -+ host->dma_dev ? "" : ", no DMA", -+ (host->pdata && host->pdata->get_ro) -+ ? "" : ", no WP", -+ (host->pdata && host->pdata->setpower) -+ ? "" : ", no poweroff"); -+ return 0; -+ -+fail_add_host: -+ mmc_remove_host (mmc); -+fail_glue_init: -+ if (host->dma_dev) -+ dma_unmap_single(host->dma_dev, host->data_dma, -+ sizeof(*host->data), DMA_BIDIRECTIONAL); -+ kfree(host->data); -+ -+fail_nobuf1: -+ mmc_free_host(mmc); -+ dev_set_drvdata(&spi->dev, NULL); -+ -+nomem: -+ kfree(ones); -+ return status; -+} -+ -+ -+static int __devexit mmc_spi_remove(struct spi_device *spi) -+{ -+ struct mmc_host *mmc = dev_get_drvdata(&spi->dev); -+ struct mmc_spi_host *host; -+ -+ if (mmc) { -+ host = mmc_priv(mmc); -+ -+ /* prevent new mmc_detect_change() calls */ -+ if (host->pdata && host->pdata->exit) -+ host->pdata->exit(&spi->dev, mmc); -+ -+ mmc_remove_host(mmc); -+ -+ if (host->dma_dev) { -+ dma_unmap_single(host->dma_dev, host->ones_dma, -+ MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE); -+ dma_unmap_single(host->dma_dev, host->data_dma, -+ sizeof(*host->data), DMA_BIDIRECTIONAL); -+ } -+ -+ kfree(host->data); -+ kfree(host->ones); -+ -+ spi->max_speed_hz = mmc->f_max; -+ mmc_free_host(mmc); -+ dev_set_drvdata(&spi->dev, NULL); -+ } -+ return 0; -+} -+ -+ -+static struct spi_driver mmc_spi_driver = { -+ .driver = { -+ .name = "mmc_spi", -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ }, -+ .probe = mmc_spi_probe, -+ .remove = __devexit_p(mmc_spi_remove), -+}; -+ -+ -+static int __init mmc_spi_init(void) -+{ -+ return spi_register_driver(&mmc_spi_driver); -+} -+module_init(mmc_spi_init); -+ -+ -+static void __exit mmc_spi_exit(void) -+{ -+ spi_unregister_driver(&mmc_spi_driver); -+} -+module_exit(mmc_spi_exit); -+ -+ -+MODULE_AUTHOR("Mike Lavender, David Brownell, " -+ "Hans-Peter Nilsson, Jan Nikitenko"); -+MODULE_DESCRIPTION("SPI SD/MMC host driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/spi/mmc_spi.h -@@ -0,0 +1,33 @@ -+#ifndef __LINUX_SPI_MMC_SPI_H -+#define __LINUX_SPI_MMC_SPI_H -+ -+struct device; -+struct mmc_host; -+ -+/* Put this in platform_data of a device being used to manage an MMC/SD -+ * card slot. (Modeled after PXA mmc glue; see that for usage examples.) -+ * -+ * REVISIT This is not a spi-specific notion. Any card slot should be -+ * able to handle it. If the MMC core doesn't adopt this kind of notion, -+ * switch the "struct device *" parameters over to "struct spi_device *". -+ */ -+struct mmc_spi_platform_data { -+ /* driver activation and (optional) card detect irq hookup */ -+ int (*init)(struct device *, -+ irqreturn_t (*)(int, void *), -+ void *); -+ void (*exit)(struct device *, void *); -+ -+ /* sense switch on sd cards */ -+ int (*get_ro)(struct device *); -+ -+ /* how long to debounce card detect, in msecs */ -+ u16 detect_delay; -+ -+ /* power management */ -+ u16 powerup_msecs; /* delay of up to 250 msec */ -+ u32 ocr_mask; /* available voltages */ -+ void (*setpower)(struct device *, unsigned int maskval); -+}; -+ -+#endif /* __LINUX_SPI_MMC_SPI_H */ ---- a/drivers/mmc/core/bus.c -+++ b/drivers/mmc/core/bus.c -@@ -19,6 +19,7 @@ - - #include "sysfs.h" - #include "core.h" -+#include "sdio_cis.h" - #include "bus.h" - - #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) -@@ -34,6 +35,8 @@ static ssize_t mmc_type_show(struct devi - return sprintf(buf, "MMC\n"); - case MMC_TYPE_SD: - return sprintf(buf, "SD\n"); -+ case MMC_TYPE_SDIO: -+ return sprintf(buf, "SDIO\n"); - default: - return -EFAULT; - } -@@ -55,36 +58,37 @@ static int mmc_bus_match(struct device * - } - - static int --mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, -- int buf_size) -+mmc_bus_uevent(struct device *dev, char **envp, -+ int num_envp, char *buffer, int buffer_size) - { - struct mmc_card *card = dev_to_mmc_card(dev); -- int retval = 0, i = 0, length = 0; -- --#define add_env(fmt,val) do { \ -- retval = add_uevent_var(envp, num_envp, &i, \ -- buf, buf_size, &length, \ -- fmt, val); \ -- if (retval) \ -- return retval; \ --} while (0); -+ const char *type; -+ int retval = 0; -+ int i = 0, len = 0; - - switch (card->type) { - case MMC_TYPE_MMC: -- add_env("MMC_TYPE=%s", "MMC"); -+ type = "MMC"; - break; - case MMC_TYPE_SD: -- add_env("MMC_TYPE=%s", "SD"); -+ type = "SD"; - break; -+ case MMC_TYPE_SDIO: -+ type = "SDIO"; -+ break; -+ default: -+ type = NULL; - } - -- add_env("MMC_NAME=%s", mmc_card_name(card)); -- --#undef add_env -+ if (type) { -+ retval = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MMC_TYPE=%s", type); -+ if (retval) -+ return retval; -+ } - -- envp[i] = NULL; -+ retval = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MMC_NAME=%s", mmc_card_name(card)); - -- return 0; -+ return retval; - } - - static int mmc_bus_probe(struct device *dev) -@@ -176,6 +180,11 @@ static void mmc_release_card(struct devi - { - struct mmc_card *card = dev_to_mmc_card(dev); - -+ sdio_free_common_cis(card); -+ -+ if (card->info) -+ kfree(card->info); -+ - kfree(card); - } - -@@ -221,15 +230,25 @@ int mmc_add_card(struct mmc_card *card) - if (mmc_card_blockaddr(card)) - type = "SDHC"; - break; -+ case MMC_TYPE_SDIO: -+ type = "SDIO"; -+ break; - default: - type = "?"; - break; - } - -- printk(KERN_INFO "%s: new %s%s card at address %04x\n", -- mmc_hostname(card->host), -- mmc_card_highspeed(card) ? "high speed " : "", -- type, card->rca); -+ if (mmc_host_is_spi(card->host)) { -+ printk(KERN_INFO "%s: new %s%s card on SPI\n", -+ mmc_hostname(card->host), -+ mmc_card_highspeed(card) ? "high speed " : "", -+ type); -+ } else { -+ printk(KERN_INFO "%s: new %s%s card at address %04x\n", -+ mmc_hostname(card->host), -+ mmc_card_highspeed(card) ? "high speed " : "", -+ type, card->rca); -+ } - - card->dev.uevent_suppress = 1; - -@@ -261,8 +280,13 @@ int mmc_add_card(struct mmc_card *card) - void mmc_remove_card(struct mmc_card *card) - { - if (mmc_card_present(card)) { -- printk(KERN_INFO "%s: card %04x removed\n", -- mmc_hostname(card->host), card->rca); -+ if (mmc_host_is_spi(card->host)) { -+ printk(KERN_INFO "%s: SPI card removed\n", -+ mmc_hostname(card->host)); -+ } else { -+ printk(KERN_INFO "%s: card %04x removed\n", -+ mmc_hostname(card->host), card->rca); -+ } - - if (card->host->bus_ops->sysfs_remove) - card->host->bus_ops->sysfs_remove(card->host, card); ---- a/drivers/mmc/core/core.c -+++ b/drivers/mmc/core/core.c -@@ -18,7 +18,7 @@ - #include <linux/delay.h> - #include <linux/pagemap.h> - #include <linux/err.h> --#include <asm/scatterlist.h> -+#include <linux/leds.h> - #include <linux/scatterlist.h> - - #include <linux/mmc/card.h> -@@ -29,16 +29,27 @@ - #include "core.h" - #include "bus.h" - #include "host.h" -+#include "sdio_bus.h" - - #include "mmc_ops.h" - #include "sd_ops.h" -+#include "sdio_ops.h" - - extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); - extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); -+extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr); - - static struct workqueue_struct *workqueue; - - /* -+ * Enabling software CRCs on the data blocks can be a significant (30%) -+ * performance cost, and for other reasons may not always be desired. -+ * So we allow it it to be disabled. -+ */ -+int use_spi_crc = 1; -+module_param(use_spi_crc, bool, 0); -+ -+/* - * Internal function. Schedule delayed work in the MMC work queue. - */ - static int mmc_schedule_delayed_work(struct delayed_work *work, -@@ -68,6 +79,11 @@ void mmc_request_done(struct mmc_host *h - struct mmc_command *cmd = mrq->cmd; - int err = cmd->error; - -+ if (err && cmd->retries && mmc_host_is_spi(host)) { -+ if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) -+ cmd->retries = 0; -+ } -+ - if (err && cmd->retries) { - pr_debug("%s: req failed (CMD%u): %d, retrying...\n", - mmc_hostname(host), cmd->opcode, err); -@@ -76,6 +92,8 @@ void mmc_request_done(struct mmc_host *h - cmd->error = 0; - host->ops->request(host, mrq); - } else { -+ led_trigger_event(host->led, LED_OFF); -+ - pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n", - mmc_hostname(host), cmd->opcode, err, - cmd->resp[0], cmd->resp[1], -@@ -118,7 +136,7 @@ mmc_start_request(struct mmc_host *host, - "tsac %d ms nsac %d\n", - mmc_hostname(host), mrq->data->blksz, - mrq->data->blocks, mrq->data->flags, -- mrq->data->timeout_ns / 10000000, -+ mrq->data->timeout_ns / 1000000, - mrq->data->timeout_clks); - } - -@@ -130,6 +148,8 @@ mmc_start_request(struct mmc_host *host, - - WARN_ON(!host->claimed); - -+ led_trigger_event(host->led, LED_FULL); -+ - mrq->cmd->error = 0; - mrq->cmd->mrq = mrq; - if (mrq->data) { -@@ -199,7 +219,7 @@ int mmc_wait_for_cmd(struct mmc_host *ho - { - struct mmc_request mrq; - -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - memset(&mrq, 0, sizeof(struct mmc_request)); - -@@ -220,17 +240,24 @@ EXPORT_SYMBOL(mmc_wait_for_cmd); - * mmc_set_data_timeout - set the timeout for a data command - * @data: data phase for command - * @card: the MMC card associated with the data transfer -- * @write: flag to differentiate reads from writes - * - * Computes the data timeout parameters according to the - * correct algorithm given the card type. - */ --void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, -- int write) -+void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) - { - unsigned int mult; - - /* -+ * SDIO cards only define an upper 1 s limit on access. -+ */ -+ if (mmc_card_sdio(card)) { -+ data->timeout_ns = 1000000000; -+ data->timeout_clks = 0; -+ return; -+ } -+ -+ /* - * SD cards use a 100 multiplier rather than 10 - */ - mult = mmc_card_sd(card) ? 100 : 10; -@@ -239,7 +266,7 @@ void mmc_set_data_timeout(struct mmc_dat - * Scale up the multiplier (and therefore the timeout) by - * the r2w factor for writes. - */ -- if (write) -+ if (data->flags & MMC_DATA_WRITE) - mult <<= card->csd.r2w_factor; - - data->timeout_ns = card->csd.tacc_ns * mult; -@@ -255,7 +282,7 @@ void mmc_set_data_timeout(struct mmc_dat - timeout_us += data->timeout_clks * 1000 / - (card->host->ios.clock / 1000); - -- if (write) -+ if (data->flags & MMC_DATA_WRITE) - limit_us = 250000; - else - limit_us = 100000; -@@ -272,15 +299,20 @@ void mmc_set_data_timeout(struct mmc_dat - EXPORT_SYMBOL(mmc_set_data_timeout); - - /** -- * mmc_claim_host - exclusively claim a host -+ * __mmc_claim_host - exclusively claim a host - * @host: mmc host to claim -+ * @abort: whether or not the operation should be aborted - * -- * Claim a host for a set of operations. -+ * Claim a host for a set of operations. If @abort is non null and -+ * dereference a non-zero value then this will return prematurely with -+ * that non-zero value without acquiring the lock. Returns zero -+ * with the lock held otherwise. - */ --void mmc_claim_host(struct mmc_host *host) -+int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) - { - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; -+ int stop; - - might_sleep(); - -@@ -288,19 +320,24 @@ void mmc_claim_host(struct mmc_host *hos - spin_lock_irqsave(&host->lock, flags); - while (1) { - set_current_state(TASK_UNINTERRUPTIBLE); -- if (!host->claimed) -+ stop = abort ? atomic_read(abort) : 0; -+ if (stop || !host->claimed) - break; - spin_unlock_irqrestore(&host->lock, flags); - schedule(); - spin_lock_irqsave(&host->lock, flags); - } - set_current_state(TASK_RUNNING); -- host->claimed = 1; -+ if (!stop) -+ host->claimed = 1; -+ else -+ wake_up(&host->wq); - spin_unlock_irqrestore(&host->lock, flags); - remove_wait_queue(&host->wq, &wait); -+ return stop; - } - --EXPORT_SYMBOL(mmc_claim_host); -+EXPORT_SYMBOL(__mmc_claim_host); - - /** - * mmc_release_host - release a host -@@ -313,7 +350,7 @@ void mmc_release_host(struct mmc_host *h - { - unsigned long flags; - -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - spin_lock_irqsave(&host->lock, flags); - host->claimed = 0; -@@ -433,19 +470,32 @@ static void mmc_power_up(struct mmc_host - int bit = fls(host->ocr_avail) - 1; - - host->ios.vdd = bit; -- host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -- host->ios.chip_select = MMC_CS_DONTCARE; -+ if (mmc_host_is_spi(host)) { -+ host->ios.chip_select = MMC_CS_HIGH; -+ host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; -+ } else { -+ host->ios.chip_select = MMC_CS_DONTCARE; -+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -+ } - host->ios.power_mode = MMC_POWER_UP; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; - mmc_set_ios(host); - -- mmc_delay(1); -+ /* -+ * This delay should be sufficient to allow the power supply -+ * to reach the minimum voltage. -+ */ -+ mmc_delay(2); - - host->ios.clock = host->f_min; - host->ios.power_mode = MMC_POWER_ON; - mmc_set_ios(host); - -+ /* -+ * This delay must be at least 74 clock sizes, or 1 ms, or the -+ * time required to reach a stable voltage. -+ */ - mmc_delay(2); - } - -@@ -453,8 +503,10 @@ static void mmc_power_off(struct mmc_hos - { - host->ios.clock = 0; - host->ios.vdd = 0; -- host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -- host->ios.chip_select = MMC_CS_DONTCARE; -+ if (!mmc_host_is_spi(host)) { -+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; -+ host->ios.chip_select = MMC_CS_DONTCARE; -+ } - host->ios.power_mode = MMC_POWER_OFF; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; -@@ -511,7 +563,7 @@ void mmc_attach_bus(struct mmc_host *hos - BUG_ON(!host); - BUG_ON(!ops); - -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - spin_lock_irqsave(&host->lock, flags); - -@@ -535,8 +587,8 @@ void mmc_detach_bus(struct mmc_host *hos - - BUG_ON(!host); - -- BUG_ON(!host->claimed); -- BUG_ON(!host->bus_ops); -+ WARN_ON(!host->claimed); -+ WARN_ON(!host->bus_ops); - - spin_lock_irqsave(&host->lock, flags); - -@@ -564,7 +616,7 @@ void mmc_detect_change(struct mmc_host * - #ifdef CONFIG_MMC_DEBUG - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); -- BUG_ON(host->removed); -+ WARN_ON(host->removed); - spin_unlock_irqrestore(&host->lock, flags); - #endif - -@@ -597,24 +649,38 @@ void mmc_rescan(struct work_struct *work - - mmc_send_if_cond(host, host->ocr_avail); - -+ /* -+ * First we search for SDIO... -+ */ -+ err = mmc_send_io_op_cond(host, 0, &ocr); -+ if (!err) { -+ if (mmc_attach_sdio(host, ocr)) -+ mmc_power_off(host); -+ return; -+ } -+ -+ /* -+ * ...then normal SD... -+ */ - err = mmc_send_app_op_cond(host, 0, &ocr); -- if (err == MMC_ERR_NONE) { -+ if (!err) { - if (mmc_attach_sd(host, ocr)) - mmc_power_off(host); -- } else { -- /* -- * If we fail to detect any SD cards then try -- * searching for MMC cards. -- */ -- err = mmc_send_op_cond(host, 0, &ocr); -- if (err == MMC_ERR_NONE) { -- if (mmc_attach_mmc(host, ocr)) -- mmc_power_off(host); -- } else { -+ return; -+ } -+ -+ /* -+ * ...and finally MMC. -+ */ -+ err = mmc_send_op_cond(host, 0, &ocr); -+ if (!err) { -+ if (mmc_attach_mmc(host, ocr)) - mmc_power_off(host); -- mmc_release_host(host); -- } -+ return; - } -+ -+ mmc_release_host(host); -+ mmc_power_off(host); - } else { - if (host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); -@@ -725,22 +791,38 @@ static int __init mmc_init(void) - return -ENOMEM; - - ret = mmc_register_bus(); -- if (ret == 0) { -- ret = mmc_register_host_class(); -- if (ret) -- mmc_unregister_bus(); -- } -+ if (ret) -+ goto destroy_workqueue; -+ -+ ret = mmc_register_host_class(); -+ if (ret) -+ goto unregister_bus; -+ -+ ret = sdio_register_bus(); -+ if (ret) -+ goto unregister_host_class; -+ -+ return 0; -+ -+unregister_host_class: -+ mmc_unregister_host_class(); -+unregister_bus: -+ mmc_unregister_bus(); -+destroy_workqueue: -+ destroy_workqueue(workqueue); -+ - return ret; - } - - static void __exit mmc_exit(void) - { -+ sdio_unregister_bus(); - mmc_unregister_host_class(); - mmc_unregister_bus(); - destroy_workqueue(workqueue); - } - --module_init(mmc_init); -+subsys_initcall(mmc_init); - module_exit(mmc_exit); - - MODULE_LICENSE("GPL"); ---- a/drivers/mmc/core/core.h -+++ b/drivers/mmc/core/core.h -@@ -48,5 +48,7 @@ void mmc_rescan(struct work_struct *work - void mmc_start_host(struct mmc_host *host); - void mmc_stop_host(struct mmc_host *host); - -+extern int use_spi_crc; -+ - #endif - ---- a/drivers/mmc/core/host.c -+++ b/drivers/mmc/core/host.c -@@ -15,6 +15,7 @@ - #include <linux/err.h> - #include <linux/idr.h> - #include <linux/pagemap.h> -+#include <linux/leds.h> - - #include <linux/mmc/host.h> - -@@ -100,6 +101,9 @@ int mmc_add_host(struct mmc_host *host) - { - int err; - -+ WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && -+ !host->ops->enable_sdio_irq); -+ - if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) - return -ENOMEM; - -@@ -112,6 +116,8 @@ int mmc_add_host(struct mmc_host *host) - snprintf(host->class_dev.bus_id, BUS_ID_SIZE, - "mmc%d", host->index); - -+ led_trigger_register_simple(host->class_dev.bus_id, &host->led); -+ - err = device_add(&host->class_dev); - if (err) - return err; -@@ -137,6 +143,8 @@ void mmc_remove_host(struct mmc_host *ho - - device_del(&host->class_dev); - -+ led_trigger_unregister_simple(host->led); -+ - spin_lock(&mmc_host_lock); - idr_remove(&mmc_host_idr, host->index); - spin_unlock(&mmc_host_lock); ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -161,13 +161,12 @@ static int mmc_read_ext_csd(struct mmc_c - { - int err; - u8 *ext_csd; -+ unsigned int ext_csd_struct; - - BUG_ON(!card); - -- err = MMC_ERR_FAILED; -- - if (card->csd.mmca_vsn < CSD_SPEC_VER_4) -- return MMC_ERR_NONE; -+ return 0; - - /* - * As the ext_csd is so large and mostly unused, we don't store the -@@ -176,13 +175,19 @@ static int mmc_read_ext_csd(struct mmc_c - ext_csd = kmalloc(512, GFP_KERNEL); - if (!ext_csd) { - printk(KERN_ERR "%s: could not allocate a buffer to " -- "receive the ext_csd. mmc v4 cards will be " -- "treated as v3.\n", mmc_hostname(card->host)); -- return MMC_ERR_FAILED; -+ "receive the ext_csd.\n", mmc_hostname(card->host)); -+ return -ENOMEM; - } - - err = mmc_send_ext_csd(card, ext_csd); -- if (err != MMC_ERR_NONE) { -+ if (err) { -+ /* -+ * We all hosts that cannot perform the command -+ * to fail more gracefully -+ */ -+ if (err != -EINVAL) -+ goto out; -+ - /* - * High capacity cards should have this "magic" size - * stored in their CSD. -@@ -197,18 +202,30 @@ static int mmc_read_ext_csd(struct mmc_c - "EXT_CSD, performance might " - "suffer.\n", - mmc_hostname(card->host)); -- err = MMC_ERR_NONE; -+ err = 0; - } -+ - goto out; - } - -- card->ext_csd.sectors = -- ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | -- ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | -- ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | -- ext_csd[EXT_CSD_SEC_CNT + 3] << 24; -- if (card->ext_csd.sectors) -- mmc_card_set_blockaddr(card); -+ ext_csd_struct = ext_csd[EXT_CSD_REV]; -+ if (ext_csd_struct > 2) { -+ printk(KERN_ERR "%s: unrecognised EXT_CSD structure " -+ "version %d\n", mmc_hostname(card->host), -+ ext_csd_struct); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ if (ext_csd_struct >= 2) { -+ card->ext_csd.sectors = -+ ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | -+ ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | -+ ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | -+ ext_csd[EXT_CSD_SEC_CNT + 3] << 24; -+ if (card->ext_csd.sectors) -+ mmc_card_set_blockaddr(card); -+ } - - switch (ext_csd[EXT_CSD_CARD_TYPE]) { - case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: -@@ -246,7 +263,7 @@ static int mmc_init_card(struct mmc_host - unsigned int max_dtr; - - BUG_ON(!host); -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - /* - * Since we're changing the OCR value, we seem to -@@ -258,19 +275,33 @@ static int mmc_init_card(struct mmc_host - - /* The extra bit indicates that we support high capacity */ - err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); -- if (err != MMC_ERR_NONE) -+ if (err) - goto err; - - /* -+ * For SPI, enable CRC as appropriate. -+ */ -+ if (mmc_host_is_spi(host)) { -+ err = mmc_spi_set_crc(host, use_spi_crc); -+ if (err) -+ goto err; -+ } -+ -+ /* - * Fetch CID from card. - */ -- err = mmc_all_send_cid(host, cid); -- if (err != MMC_ERR_NONE) -+ if (mmc_host_is_spi(host)) -+ err = mmc_send_cid(host, cid); -+ else -+ err = mmc_all_send_cid(host, cid); -+ if (err) - goto err; - - if (oldcard) { -- if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) -+ if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { -+ err = -ENOENT; - goto err; -+ } - - card = oldcard; - } else { -@@ -278,8 +309,10 @@ static int mmc_init_card(struct mmc_host - * Allocate card structure. - */ - card = mmc_alloc_card(host); -- if (IS_ERR(card)) -+ if (IS_ERR(card)) { -+ err = PTR_ERR(card); - goto err; -+ } - - card->type = MMC_TYPE_MMC; - card->rca = 1; -@@ -287,43 +320,47 @@ static int mmc_init_card(struct mmc_host - } - - /* -- * Set card RCA. -+ * For native busses: set card RCA and quit open drain mode. - */ -- err = mmc_set_relative_addr(card); -- if (err != MMC_ERR_NONE) -- goto free_card; -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_set_relative_addr(card); -+ if (err) -+ goto free_card; - -- mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ } - - if (!oldcard) { - /* - * Fetch CSD from card. - */ - err = mmc_send_csd(card, card->raw_csd); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - err = mmc_decode_csd(card); -- if (err < 0) -+ if (err) - goto free_card; - err = mmc_decode_cid(card); -- if (err < 0) -+ if (err) - goto free_card; - } - - /* - * Select card, as all following commands rely on that. - */ -- err = mmc_select_card(card); -- if (err != MMC_ERR_NONE) -- goto free_card; -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_select_card(card); -+ if (err) -+ goto free_card; -+ } - - if (!oldcard) { - /* -- * Fetch and process extened CSD. -+ * Fetch and process extended CSD. - */ - err = mmc_read_ext_csd(card); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - } - -@@ -334,7 +371,7 @@ static int mmc_init_card(struct mmc_host - (host->caps & MMC_CAP_MMC_HIGHSPEED)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, 1); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - mmc_card_set_highspeed(card); -@@ -363,7 +400,7 @@ static int mmc_init_card(struct mmc_host - (host->caps & MMC_CAP_4_BIT_DATA)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); -@@ -372,14 +409,14 @@ static int mmc_init_card(struct mmc_host - if (!oldcard) - host->card = card; - -- return MMC_ERR_NONE; -+ return 0; - - free_card: - if (!oldcard) - mmc_remove_card(card); - err: - -- return MMC_ERR_FAILED; -+ return err; - } - - /* -@@ -413,7 +450,7 @@ static void mmc_detect(struct mmc_host * - - mmc_release_host(host); - -- if (err != MMC_ERR_NONE) { -+ if (err) { - mmc_remove(host); - - mmc_claim_host(host); -@@ -480,7 +517,8 @@ static void mmc_suspend(struct mmc_host - BUG_ON(!host->card); - - mmc_claim_host(host); -- mmc_deselect_cards(host); -+ if (!mmc_host_is_spi(host)) -+ mmc_deselect_cards(host); - host->card->state &= ~MMC_STATE_HIGHSPEED; - mmc_release_host(host); - } -@@ -502,7 +540,7 @@ static void mmc_resume(struct mmc_host * - err = mmc_init_card(host, host->ocr, host->card); - mmc_release_host(host); - -- if (err != MMC_ERR_NONE) { -+ if (err) { - mmc_remove(host); - - mmc_claim_host(host); -@@ -536,11 +574,20 @@ int mmc_attach_mmc(struct mmc_host *host - int err; - - BUG_ON(!host); -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - mmc_attach_bus(host, &mmc_ops); - - /* -+ * We need to get OCR a different way for SPI. -+ */ -+ if (mmc_host_is_spi(host)) { -+ err = mmc_spi_read_ocr(host, 1, &ocr); -+ if (err) -+ goto err; -+ } -+ -+ /* - * Sanity check the voltages that the card claims to - * support. - */ -@@ -565,7 +612,7 @@ int mmc_attach_mmc(struct mmc_host *host - * Detect and init the card. - */ - err = mmc_init_card(host, host->ocr, NULL); -- if (err != MMC_ERR_NONE) -+ if (err) - goto err; - - mmc_release_host(host); -@@ -587,6 +634,6 @@ err: - printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", - mmc_hostname(host), err); - -- return 0; -+ return err; - } - ---- a/drivers/mmc/core/mmc_ops.c -+++ b/drivers/mmc/core/mmc_ops.c -@@ -10,7 +10,6 @@ - */ - - #include <linux/types.h> --#include <asm/scatterlist.h> - #include <linux/scatterlist.h> - - #include <linux/mmc/host.h> -@@ -40,10 +39,10 @@ static int _mmc_select_card(struct mmc_h - } - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_select_card(struct mmc_card *card) -@@ -63,23 +62,36 @@ int mmc_go_idle(struct mmc_host *host) - int err; - struct mmc_command cmd; - -- mmc_set_chip_select(host, MMC_CS_HIGH); -- -- mmc_delay(1); -+ /* -+ * Non-SPI hosts need to prevent chipselect going active during -+ * GO_IDLE; that would put chips into SPI mode. Remind them of -+ * that in case of hardware that won't pull up DAT3/nCS otherwise. -+ * -+ * SPI hosts ignore ios.chip_select; it's managed according to -+ * rules that must accomodate non-MMC slaves which this layer -+ * won't even know about. -+ */ -+ if (!mmc_host_is_spi(host)) { -+ mmc_set_chip_select(host, MMC_CS_HIGH); -+ mmc_delay(1); -+ } - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_GO_IDLE_STATE; - cmd.arg = 0; -- cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; - - err = mmc_wait_for_cmd(host, &cmd, 0); - - mmc_delay(1); - -- mmc_set_chip_select(host, MMC_CS_DONTCARE); -+ if (!mmc_host_is_spi(host)) { -+ mmc_set_chip_select(host, MMC_CS_DONTCARE); -+ mmc_delay(1); -+ } - -- mmc_delay(1); -+ host->use_spi_crc = 0; - - return err; - } -@@ -94,23 +106,33 @@ int mmc_send_op_cond(struct mmc_host *ho - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SEND_OP_COND; -- cmd.arg = ocr; -- cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; -+ cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; - - for (i = 100; i; i--) { - err = mmc_wait_for_cmd(host, &cmd, 0); -- if (err != MMC_ERR_NONE) -+ if (err) - break; - -- if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) -+ /* if we're just probing, do a single pass */ -+ if (ocr == 0) - break; - -- err = MMC_ERR_TIMEOUT; -+ /* otherwise wait until reset completes */ -+ if (mmc_host_is_spi(host)) { -+ if (!(cmd.resp[0] & R1_SPI_IDLE)) -+ break; -+ } else { -+ if (cmd.resp[0] & MMC_CARD_BUSY) -+ break; -+ } -+ -+ err = -ETIMEDOUT; - - mmc_delay(10); - } - -- if (rocr) -+ if (rocr && !mmc_host_is_spi(host)) - *rocr = cmd.resp[0]; - - return err; -@@ -131,12 +153,12 @@ int mmc_all_send_cid(struct mmc_host *ho - cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - - memcpy(cid, cmd.resp, sizeof(u32) * 4); - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_set_relative_addr(struct mmc_card *card) -@@ -154,46 +176,52 @@ int mmc_set_relative_addr(struct mmc_car - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -- return MMC_ERR_NONE; -+ return 0; - } - --int mmc_send_csd(struct mmc_card *card, u32 *csd) -+static int -+mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) - { - int err; - struct mmc_command cmd; - -- BUG_ON(!card); -- BUG_ON(!card->host); -- BUG_ON(!csd); -+ BUG_ON(!host); -+ BUG_ON(!cxd); - - memset(&cmd, 0, sizeof(struct mmc_command)); - -- cmd.opcode = MMC_SEND_CSD; -- cmd.arg = card->rca << 16; -+ cmd.opcode = opcode; -+ cmd.arg = arg; - cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; - -- err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -+ if (err) - return err; - -- memcpy(csd, cmd.resp, sizeof(u32) * 4); -+ memcpy(cxd, cmd.resp, sizeof(u32) * 4); - -- return MMC_ERR_NONE; -+ return 0; - } - --int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) -+static int -+mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, -+ u32 opcode, void *buf, unsigned len) - { - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_data data; - struct scatterlist sg; -+ void *data_buf; - -- BUG_ON(!card); -- BUG_ON(!card->host); -- BUG_ON(!ext_csd); -+ /* dma onto stack is unsafe/nonportable, but callers to this -+ * routine normally provide temporary on-stack buffers ... -+ */ -+ data_buf = kmalloc(len, GFP_KERNEL); -+ if (data_buf == NULL) -+ return -ENOMEM; - - memset(&mrq, 0, sizeof(struct mmc_request)); - memset(&cmd, 0, sizeof(struct mmc_command)); -@@ -202,28 +230,117 @@ int mmc_send_ext_csd(struct mmc_card *ca - mrq.cmd = &cmd; - mrq.data = &data; - -- cmd.opcode = MMC_SEND_EXT_CSD; -+ cmd.opcode = opcode; - cmd.arg = 0; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - -- data.blksz = 512; -+ /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we -+ * rely on callers to never use this with "native" calls for reading -+ * CSD or CID. Native versions of those commands use the R2 type, -+ * not R1 plus a data block. -+ */ -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; -+ -+ data.blksz = len; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - -- sg_init_one(&sg, ext_csd, 512); -+ sg_init_one(&sg, data_buf, len); -+ -+ if (card) -+ mmc_set_data_timeout(&data, card); - -- mmc_set_data_timeout(&data, card, 0); -+ mmc_wait_for_req(host, &mrq); - -- mmc_wait_for_req(card->host, &mrq); -+ memcpy(buf, data_buf, len); -+ kfree(data_buf); - -- if (cmd.error != MMC_ERR_NONE) -+ if (cmd.error) - return cmd.error; -- if (data.error != MMC_ERR_NONE) -+ if (data.error) - return data.error; - -- return MMC_ERR_NONE; -+ return 0; -+} -+ -+int mmc_send_csd(struct mmc_card *card, u32 *csd) -+{ -+ int ret, i; -+ -+ if (!mmc_host_is_spi(card->host)) -+ return mmc_send_cxd_native(card->host, card->rca << 16, -+ csd, MMC_SEND_CSD); -+ -+ ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); -+ if (ret) -+ return ret; -+ -+ for (i = 0;i < 4;i++) -+ csd[i] = be32_to_cpu(csd[i]); -+ -+ return 0; -+} -+ -+int mmc_send_cid(struct mmc_host *host, u32 *cid) -+{ -+ int ret, i; -+ -+ if (!mmc_host_is_spi(host)) { -+ if (!host->card) -+ return -EINVAL; -+ return mmc_send_cxd_native(host, host->card->rca << 16, -+ cid, MMC_SEND_CID); -+ } -+ -+ ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); -+ if (ret) -+ return ret; -+ -+ for (i = 0;i < 4;i++) -+ cid[i] = be32_to_cpu(cid[i]); -+ -+ return 0; -+} -+ -+int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) -+{ -+ return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD, -+ ext_csd, 512); -+} -+ -+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) -+{ -+ struct mmc_command cmd; -+ int err; -+ -+ memset(&cmd, 0, sizeof(struct mmc_command)); -+ -+ cmd.opcode = MMC_SPI_READ_OCR; -+ cmd.arg = highcap ? (1 << 30) : 0; -+ cmd.flags = MMC_RSP_SPI_R3; -+ -+ err = mmc_wait_for_cmd(host, &cmd, 0); -+ -+ *ocrp = cmd.resp[1]; -+ return err; -+} -+ -+int mmc_spi_set_crc(struct mmc_host *host, int use_crc) -+{ -+ struct mmc_command cmd; -+ int err; -+ -+ memset(&cmd, 0, sizeof(struct mmc_command)); -+ -+ cmd.opcode = MMC_SPI_CRC_ON_OFF; -+ cmd.flags = MMC_RSP_SPI_R1; -+ cmd.arg = use_crc; -+ -+ err = mmc_wait_for_cmd(host, &cmd, 0); -+ if (!err) -+ host->use_spi_crc = use_crc; -+ return err; - } - - int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) -@@ -241,13 +358,13 @@ int mmc_switch(struct mmc_card *card, u8 - (index << 16) | - (value << 8) | - set; -- cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; -+ cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_send_status(struct mmc_card *card, u32 *status) -@@ -261,16 +378,20 @@ int mmc_send_status(struct mmc_card *car - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SEND_STATUS; -- cmd.arg = card->rca << 16; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; -+ if (!mmc_host_is_spi(card->host)) -+ cmd.arg = card->rca << 16; -+ cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -+ /* NOTE: callers are required to understand the difference -+ * between "native" and SPI format status words! -+ */ - if (status) - *status = cmd.resp[0]; - -- return MMC_ERR_NONE; -+ return 0; - } - ---- a/drivers/mmc/core/mmc_ops.h -+++ b/drivers/mmc/core/mmc_ops.h -@@ -22,6 +22,9 @@ int mmc_send_csd(struct mmc_card *card, - int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); - int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); - int mmc_send_status(struct mmc_card *card, u32 *status); -+int mmc_send_cid(struct mmc_host *host, u32 *cid); -+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); -+int mmc_spi_set_crc(struct mmc_host *host, int use_crc); - - #endif - ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -166,8 +166,6 @@ static int mmc_decode_scr(struct mmc_car - unsigned int scr_struct; - u32 resp[4]; - -- BUG_ON(!mmc_card_sd(card)); -- - resp[3] = card->raw_scr[1]; - resp[2] = card->raw_scr[0]; - -@@ -193,30 +191,38 @@ static int mmc_read_switch(struct mmc_ca - u8 *status; - - if (card->scr.sda_vsn < SCR_SPEC_VER_1) -- return MMC_ERR_NONE; -+ return 0; - - if (!(card->csd.cmdclass & CCC_SWITCH)) { - printk(KERN_WARNING "%s: card lacks mandatory switch " - "function, performance might suffer.\n", - mmc_hostname(card->host)); -- return MMC_ERR_NONE; -+ return 0; - } - -- err = MMC_ERR_FAILED; -+ err = -EIO; - - status = kmalloc(64, GFP_KERNEL); - if (!status) { - printk(KERN_ERR "%s: could not allocate a buffer for " - "switch capabilities.\n", mmc_hostname(card->host)); -- return err; -+ return -ENOMEM; - } - - err = mmc_sd_switch(card, 0, 0, 1, status); -- if (err != MMC_ERR_NONE) { -+ if (err) { -+ /* -+ * We all hosts that cannot perform the command -+ * to fail more gracefully -+ */ -+ if (err != -EINVAL) -+ goto out; -+ - printk(KERN_WARNING "%s: problem reading switch " - "capabilities, performance might suffer.\n", - mmc_hostname(card->host)); -- err = MMC_ERR_NONE; -+ err = 0; -+ - goto out; - } - -@@ -238,28 +244,28 @@ static int mmc_switch_hs(struct mmc_card - u8 *status; - - if (card->scr.sda_vsn < SCR_SPEC_VER_1) -- return MMC_ERR_NONE; -+ return 0; - - if (!(card->csd.cmdclass & CCC_SWITCH)) -- return MMC_ERR_NONE; -+ return 0; - - if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) -- return MMC_ERR_NONE; -+ return 0; - - if (card->sw_caps.hs_max_dtr == 0) -- return MMC_ERR_NONE; -+ return 0; - -- err = MMC_ERR_FAILED; -+ err = -EIO; - - status = kmalloc(64, GFP_KERNEL); - if (!status) { - printk(KERN_ERR "%s: could not allocate a buffer for " - "switch capabilities.\n", mmc_hostname(card->host)); -- return err; -+ return -ENOMEM; - } - - err = mmc_sd_switch(card, 1, 0, 1, status); -- if (err != MMC_ERR_NONE) -+ if (err) - goto out; - - if ((status[16] & 0xF) != 1) { -@@ -292,7 +298,7 @@ static int mmc_sd_init_card(struct mmc_h - unsigned int max_dtr; - - BUG_ON(!host); -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - /* - * Since we're changing the OCR value, we seem to -@@ -309,23 +315,37 @@ static int mmc_sd_init_card(struct mmc_h - * block-addressed SDHC cards. - */ - err = mmc_send_if_cond(host, ocr); -- if (err == MMC_ERR_NONE) -+ if (!err) - ocr |= 1 << 30; - - err = mmc_send_app_op_cond(host, ocr, NULL); -- if (err != MMC_ERR_NONE) -+ if (err) - goto err; - - /* -+ * For SPI, enable CRC as appropriate. -+ */ -+ if (mmc_host_is_spi(host)) { -+ err = mmc_spi_set_crc(host, use_spi_crc); -+ if (err) -+ goto err; -+ } -+ -+ /* - * Fetch CID from card. - */ -- err = mmc_all_send_cid(host, cid); -- if (err != MMC_ERR_NONE) -+ if (mmc_host_is_spi(host)) -+ err = mmc_send_cid(host, cid); -+ else -+ err = mmc_all_send_cid(host, cid); -+ if (err) - goto err; - - if (oldcard) { -- if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) -+ if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { -+ err = -ENOENT; - goto err; -+ } - - card = oldcard; - } else { -@@ -333,32 +353,36 @@ static int mmc_sd_init_card(struct mmc_h - * Allocate card structure. - */ - card = mmc_alloc_card(host); -- if (IS_ERR(card)) -+ if (IS_ERR(card)) { -+ err = PTR_ERR(card); - goto err; -+ } - - card->type = MMC_TYPE_SD; - memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); - } - - /* -- * Set card RCA. -+ * For native busses: get card RCA and quit open drain mode. - */ -- err = mmc_send_relative_addr(host, &card->rca); -- if (err != MMC_ERR_NONE) -- goto free_card; -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_send_relative_addr(host, &card->rca); -+ if (err) -+ goto free_card; - -- mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ } - - if (!oldcard) { - /* - * Fetch CSD from card. - */ - err = mmc_send_csd(card, card->raw_csd); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - err = mmc_decode_csd(card); -- if (err < 0) -+ if (err) - goto free_card; - - mmc_decode_cid(card); -@@ -367,16 +391,18 @@ static int mmc_sd_init_card(struct mmc_h - /* - * Select card, as all following commands rely on that. - */ -- err = mmc_select_card(card); -- if (err != MMC_ERR_NONE) -- goto free_card; -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_select_card(card); -+ if (err) -+ goto free_card; -+ } - - if (!oldcard) { - /* - * Fetch SCR from card. - */ - err = mmc_app_send_scr(card, card->raw_scr); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - err = mmc_decode_scr(card); -@@ -387,7 +413,7 @@ static int mmc_sd_init_card(struct mmc_h - * Fetch switch information from card. - */ - err = mmc_read_switch(card); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - } - -@@ -395,7 +421,7 @@ static int mmc_sd_init_card(struct mmc_h - * Attempt to change to high-speed (if supported) - */ - err = mmc_switch_hs(card); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - /* -@@ -418,7 +444,7 @@ static int mmc_sd_init_card(struct mmc_h - if ((host->caps & MMC_CAP_4_BIT_DATA) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); -- if (err != MMC_ERR_NONE) -+ if (err) - goto free_card; - - mmc_set_bus_width(host, MMC_BUS_WIDTH_4); -@@ -442,14 +468,14 @@ static int mmc_sd_init_card(struct mmc_h - if (!oldcard) - host->card = card; - -- return MMC_ERR_NONE; -+ return 0; - - free_card: - if (!oldcard) - mmc_remove_card(card); - err: - -- return MMC_ERR_FAILED; -+ return err; - } - - /* -@@ -483,7 +509,7 @@ static void mmc_sd_detect(struct mmc_hos - - mmc_release_host(host); - -- if (err != MMC_ERR_NONE) { -+ if (err) { - mmc_sd_remove(host); - - mmc_claim_host(host); -@@ -552,7 +578,8 @@ static void mmc_sd_suspend(struct mmc_ho - BUG_ON(!host->card); - - mmc_claim_host(host); -- mmc_deselect_cards(host); -+ if (!mmc_host_is_spi(host)) -+ mmc_deselect_cards(host); - host->card->state &= ~MMC_STATE_HIGHSPEED; - mmc_release_host(host); - } -@@ -574,7 +601,7 @@ static void mmc_sd_resume(struct mmc_hos - err = mmc_sd_init_card(host, host->ocr, host->card); - mmc_release_host(host); - -- if (err != MMC_ERR_NONE) { -+ if (err) { - mmc_sd_remove(host); - - mmc_claim_host(host); -@@ -608,11 +635,22 @@ int mmc_attach_sd(struct mmc_host *host, - int err; - - BUG_ON(!host); -- BUG_ON(!host->claimed); -+ WARN_ON(!host->claimed); - - mmc_attach_bus(host, &mmc_sd_ops); - - /* -+ * We need to get OCR a different way for SPI. -+ */ -+ if (mmc_host_is_spi(host)) { -+ mmc_go_idle(host); -+ -+ err = mmc_spi_read_ocr(host, 0, &ocr); -+ if (err) -+ goto err; -+ } -+ -+ /* - * Sanity check the voltages that the card claims to - * support. - */ -@@ -644,7 +682,7 @@ int mmc_attach_sd(struct mmc_host *host, - * Detect and init the card. - */ - err = mmc_sd_init_card(host, host->ocr, NULL); -- if (err != MMC_ERR_NONE) -+ if (err) - goto err; - - mmc_release_host(host); -@@ -666,6 +704,6 @@ err: - printk(KERN_ERR "%s: error %d whilst initialising SD card\n", - mmc_hostname(host), err); - -- return 0; -+ return err; - } - ---- a/drivers/mmc/core/sd_ops.c -+++ b/drivers/mmc/core/sd_ops.c -@@ -10,7 +10,6 @@ - */ - - #include <linux/types.h> --#include <asm/scatterlist.h> - #include <linux/scatterlist.h> - - #include <linux/mmc/host.h> -@@ -33,21 +32,21 @@ static int mmc_app_cmd(struct mmc_host * - - if (card) { - cmd.arg = card->rca << 16; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - } else { - cmd.arg = 0; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR; - } - - err = mmc_wait_for_cmd(host, &cmd, 0); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - - /* Check that card supported application commands */ -- if (!(cmd.resp[0] & R1_APP_CMD)) -- return MMC_ERR_FAILED; -+ if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD)) -+ return -EOPNOTSUPP; - -- return MMC_ERR_NONE; -+ return 0; - } - - /** -@@ -73,7 +72,7 @@ int mmc_wait_for_app_cmd(struct mmc_host - BUG_ON(!cmd); - BUG_ON(retries < 0); - -- err = MMC_ERR_INVALID; -+ err = -EIO; - - /* - * We have to resend MMC_APP_CMD for each attempt so -@@ -83,8 +82,14 @@ int mmc_wait_for_app_cmd(struct mmc_host - memset(&mrq, 0, sizeof(struct mmc_request)); - - err = mmc_app_cmd(host, card); -- if (err != MMC_ERR_NONE) -+ if (err) { -+ /* no point in retrying; no APP commands allowed */ -+ if (mmc_host_is_spi(host)) { -+ if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) -+ break; -+ } - continue; -+ } - - memset(&mrq, 0, sizeof(struct mmc_request)); - -@@ -97,8 +102,14 @@ int mmc_wait_for_app_cmd(struct mmc_host - mmc_wait_for_req(host, &mrq); - - err = cmd->error; -- if (cmd->error == MMC_ERR_NONE) -+ if (!cmd->error) - break; -+ -+ /* no point in retrying illegal APP commands */ -+ if (mmc_host_is_spi(host)) { -+ if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) -+ break; -+ } - } - - return err; -@@ -127,14 +138,14 @@ int mmc_app_set_bus_width(struct mmc_car - cmd.arg = SD_BUS_WIDTH_4; - break; - default: -- return MMC_ERR_INVALID; -+ return -EINVAL; - } - - err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) -@@ -147,23 +158,36 @@ int mmc_send_app_op_cond(struct mmc_host - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_OP_COND; -- cmd.arg = ocr; -- cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; -+ if (mmc_host_is_spi(host)) -+ cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ -+ else -+ cmd.arg = ocr; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; - - for (i = 100; i; i--) { - err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - break; - -- if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) -+ /* if we're just probing, do a single pass */ -+ if (ocr == 0) - break; - -- err = MMC_ERR_TIMEOUT; -+ /* otherwise wait until reset completes */ -+ if (mmc_host_is_spi(host)) { -+ if (!(cmd.resp[0] & R1_SPI_IDLE)) -+ break; -+ } else { -+ if (cmd.resp[0] & MMC_CARD_BUSY) -+ break; -+ } -+ -+ err = -ETIMEDOUT; - - mmc_delay(10); - } - -- if (rocr) -+ if (rocr && !mmc_host_is_spi(host)) - *rocr = cmd.resp[0]; - - return err; -@@ -174,6 +198,7 @@ int mmc_send_if_cond(struct mmc_host *ho - struct mmc_command cmd; - int err; - static const u8 test_pattern = 0xAA; -+ u8 result_pattern; - - /* - * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND -@@ -182,16 +207,21 @@ int mmc_send_if_cond(struct mmc_host *ho - */ - cmd.opcode = SD_SEND_IF_COND; - cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; -- cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; -+ cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, 0); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - -- if ((cmd.resp[0] & 0xFF) != test_pattern) -- return MMC_ERR_FAILED; -+ if (mmc_host_is_spi(host)) -+ result_pattern = cmd.resp[1] & 0xFF; -+ else -+ result_pattern = cmd.resp[0] & 0xFF; -+ -+ if (result_pattern != test_pattern) -+ return -EIO; - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) -@@ -209,12 +239,12 @@ int mmc_send_relative_addr(struct mmc_ho - cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - - *rca = cmd.resp[0] >> 16; - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_app_send_scr(struct mmc_card *card, u32 *scr) -@@ -229,8 +259,10 @@ int mmc_app_send_scr(struct mmc_card *ca - BUG_ON(!card->host); - BUG_ON(!scr); - -+ /* NOTE: caller guarantees scr is heap-allocated */ -+ - err = mmc_app_cmd(card->host, card); -- if (err != MMC_ERR_NONE) -+ if (err) - return err; - - memset(&mrq, 0, sizeof(struct mmc_request)); -@@ -242,7 +274,7 @@ int mmc_app_send_scr(struct mmc_card *ca - - cmd.opcode = SD_APP_SEND_SCR; - cmd.arg = 0; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 8; - data.blocks = 1; -@@ -252,19 +284,19 @@ int mmc_app_send_scr(struct mmc_card *ca - - sg_init_one(&sg, scr, 8); - -- mmc_set_data_timeout(&data, card, 0); -+ mmc_set_data_timeout(&data, card); - - mmc_wait_for_req(card->host, &mrq); - -- if (cmd.error != MMC_ERR_NONE) -+ if (cmd.error) - return cmd.error; -- if (data.error != MMC_ERR_NONE) -+ if (data.error) - return data.error; - -- scr[0] = ntohl(scr[0]); -- scr[1] = ntohl(scr[1]); -+ scr[0] = be32_to_cpu(scr[0]); -+ scr[1] = be32_to_cpu(scr[1]); - -- return MMC_ERR_NONE; -+ return 0; - } - - int mmc_sd_switch(struct mmc_card *card, int mode, int group, -@@ -278,6 +310,8 @@ int mmc_sd_switch(struct mmc_card *card, - BUG_ON(!card); - BUG_ON(!card->host); - -+ /* NOTE: caller guarantees resp is heap-allocated */ -+ - mode = !!mode; - value &= 0xF; - -@@ -292,7 +326,7 @@ int mmc_sd_switch(struct mmc_card *card, - cmd.arg = mode << 31 | 0x00FFFFFF; - cmd.arg &= ~(0xF << (group * 4)); - cmd.arg |= value << (group * 4); -- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 64; - data.blocks = 1; -@@ -302,15 +336,15 @@ int mmc_sd_switch(struct mmc_card *card, - - sg_init_one(&sg, resp, 64); - -- mmc_set_data_timeout(&data, card, 0); -+ mmc_set_data_timeout(&data, card); - - mmc_wait_for_req(card->host, &mrq); - -- if (cmd.error != MMC_ERR_NONE) -+ if (cmd.error) - return cmd.error; -- if (data.error != MMC_ERR_NONE) -+ if (data.error) - return data.error; - -- return MMC_ERR_NONE; -+ return 0; - } - ---- /dev/null -+++ b/drivers/mmc/core/sdio.c -@@ -0,0 +1,395 @@ -+/* -+ * linux/drivers/mmc/sdio.c -+ * -+ * Copyright 2006-2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#include <linux/err.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_func.h> -+ -+#include "core.h" -+#include "bus.h" -+#include "sdio_bus.h" -+#include "mmc_ops.h" -+#include "sd_ops.h" -+#include "sdio_ops.h" -+#include "sdio_cis.h" -+ -+static int sdio_read_fbr(struct sdio_func *func) -+{ -+ int ret; -+ unsigned char data; -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, -+ SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); -+ if (ret) -+ goto out; -+ -+ data &= 0x0f; -+ -+ if (data == 0x0f) { -+ ret = mmc_io_rw_direct(func->card, 0, 0, -+ SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); -+ if (ret) -+ goto out; -+ } -+ -+ func->class = data; -+ -+out: -+ return ret; -+} -+ -+static int sdio_init_func(struct mmc_card *card, unsigned int fn) -+{ -+ int ret; -+ struct sdio_func *func; -+ -+ BUG_ON(fn > SDIO_MAX_FUNCS); -+ -+ func = sdio_alloc_func(card); -+ if (IS_ERR(func)) -+ return PTR_ERR(func); -+ -+ func->num = fn; -+ -+ ret = sdio_read_fbr(func); -+ if (ret) -+ goto fail; -+ -+ ret = sdio_read_func_cis(func); -+ if (ret) -+ goto fail; -+ -+ card->sdio_func[fn - 1] = func; -+ -+ return 0; -+ -+fail: -+ /* -+ * It is okay to remove the function here even though we hold -+ * the host lock as we haven't registered the device yet. -+ */ -+ sdio_remove_func(func); -+ return ret; -+} -+ -+static int sdio_read_cccr(struct mmc_card *card) -+{ -+ int ret; -+ int cccr_vsn; -+ unsigned char data; -+ -+ memset(&card->cccr, 0, sizeof(struct sdio_cccr)); -+ -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data); -+ if (ret) -+ goto out; -+ -+ cccr_vsn = data & 0x0f; -+ -+ if (cccr_vsn > SDIO_CCCR_REV_1_20) { -+ printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", -+ mmc_hostname(card->host), cccr_vsn); -+ return -EINVAL; -+ } -+ -+ card->cccr.sdio_vsn = (data & 0xf0) >> 4; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data); -+ if (ret) -+ goto out; -+ -+ if (data & SDIO_CCCR_CAP_SMB) -+ card->cccr.multi_block = 1; -+ if (data & SDIO_CCCR_CAP_LSC) -+ card->cccr.low_speed = 1; -+ if (data & SDIO_CCCR_CAP_4BLS) -+ card->cccr.wide_bus = 1; -+ -+ if (cccr_vsn >= SDIO_CCCR_REV_1_10) { -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data); -+ if (ret) -+ goto out; -+ -+ if (data & SDIO_POWER_SMPC) -+ card->cccr.high_power = 1; -+ } -+ -+ if (cccr_vsn >= SDIO_CCCR_REV_1_20) { -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); -+ if (ret) -+ goto out; -+ -+ if (data & SDIO_SPEED_SHS) -+ card->cccr.high_speed = 1; -+ } -+ -+out: -+ return ret; -+} -+ -+static int sdio_enable_wide(struct mmc_card *card) -+{ -+ int ret; -+ u8 ctrl; -+ -+ if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) -+ return 0; -+ -+ if (card->cccr.low_speed && !card->cccr.wide_bus) -+ return 0; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); -+ if (ret) -+ return ret; -+ -+ ctrl |= SDIO_BUS_WIDTH_4BIT; -+ -+ ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); -+ if (ret) -+ return ret; -+ -+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); -+ -+ return 0; -+} -+ -+/* -+ * Host is being removed. Free up the current card. -+ */ -+static void mmc_sdio_remove(struct mmc_host *host) -+{ -+ int i; -+ -+ BUG_ON(!host); -+ BUG_ON(!host->card); -+ -+ for (i = 0;i < host->card->sdio_funcs;i++) { -+ if (host->card->sdio_func[i]) { -+ sdio_remove_func(host->card->sdio_func[i]); -+ host->card->sdio_func[i] = NULL; -+ } -+ } -+ -+ mmc_remove_card(host->card); -+ host->card = NULL; -+} -+ -+/* -+ * Card detection callback from host. -+ */ -+static void mmc_sdio_detect(struct mmc_host *host) -+{ -+ int err; -+ -+ BUG_ON(!host); -+ BUG_ON(!host->card); -+ -+ mmc_claim_host(host); -+ -+ /* -+ * Just check if our card has been removed. -+ */ -+ err = mmc_select_card(host->card); -+ -+ mmc_release_host(host); -+ -+ if (err) { -+ mmc_sdio_remove(host); -+ -+ mmc_claim_host(host); -+ mmc_detach_bus(host); -+ mmc_release_host(host); -+ } -+} -+ -+ -+static const struct mmc_bus_ops mmc_sdio_ops = { -+ .remove = mmc_sdio_remove, -+ .detect = mmc_sdio_detect, -+}; -+ -+ -+/* -+ * Starting point for SDIO card init. -+ */ -+int mmc_attach_sdio(struct mmc_host *host, u32 ocr) -+{ -+ int err; -+ int i, funcs; -+ struct mmc_card *card; -+ -+ BUG_ON(!host); -+ WARN_ON(!host->claimed); -+ -+ mmc_attach_bus(host, &mmc_sdio_ops); -+ -+ /* -+ * Sanity check the voltages that the card claims to -+ * support. -+ */ -+ if (ocr & 0x7F) { -+ printk(KERN_WARNING "%s: card claims to support voltages " -+ "below the defined range. These will be ignored.\n", -+ mmc_hostname(host)); -+ ocr &= ~0x7F; -+ } -+ -+ if (ocr & MMC_VDD_165_195) { -+ printk(KERN_WARNING "%s: SDIO card claims to support the " -+ "incompletely defined 'low voltage range'. This " -+ "will be ignored.\n", mmc_hostname(host)); -+ ocr &= ~MMC_VDD_165_195; -+ } -+ -+ host->ocr = mmc_select_voltage(host, ocr); -+ -+ /* -+ * Can we support the voltage(s) of the card(s)? -+ */ -+ if (!host->ocr) { -+ err = -EINVAL; -+ goto err; -+ } -+ -+ /* -+ * Inform the card of the voltage -+ */ -+ err = mmc_send_io_op_cond(host, host->ocr, &ocr); -+ if (err) -+ goto err; -+ -+ /* -+ * For SPI, enable CRC as appropriate. -+ */ -+ if (mmc_host_is_spi(host)) { -+ err = mmc_spi_set_crc(host, use_spi_crc); -+ if (err) -+ goto err; -+ } -+ -+ /* -+ * The number of functions on the card is encoded inside -+ * the ocr. -+ */ -+ funcs = (ocr & 0x70000000) >> 28; -+ -+ /* -+ * Allocate card structure. -+ */ -+ card = mmc_alloc_card(host); -+ if (IS_ERR(card)) { -+ err = PTR_ERR(card); -+ goto err; -+ } -+ -+ card->type = MMC_TYPE_SDIO; -+ card->sdio_funcs = funcs; -+ -+ host->card = card; -+ -+ /* -+ * For native busses: set card RCA and quit open drain mode. -+ */ -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_send_relative_addr(host, &card->rca); -+ if (err) -+ goto remove; -+ -+ mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ } -+ -+ /* -+ * Select card, as all following commands rely on that. -+ */ -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_select_card(card); -+ if (err) -+ goto remove; -+ } -+ -+ /* -+ * Read the common registers. -+ */ -+ err = sdio_read_cccr(card); -+ if (err) -+ goto remove; -+ -+ /* -+ * Read the common CIS tuples. -+ */ -+ err = sdio_read_common_cis(card); -+ if (err) -+ goto remove; -+ -+ /* -+ * No support for high-speed yet, so just set -+ * the card's maximum speed. -+ */ -+ mmc_set_clock(host, card->cis.max_dtr); -+ -+ /* -+ * Switch to wider bus (if supported). -+ */ -+ err = sdio_enable_wide(card); -+ if (err) -+ goto remove; -+ -+ /* -+ * Initialize (but don't add) all present functions. -+ */ -+ for (i = 0;i < funcs;i++) { -+ err = sdio_init_func(host->card, i + 1); -+ if (err) -+ goto remove; -+ } -+ -+ mmc_release_host(host); -+ -+ /* -+ * First add the card to the driver model... -+ */ -+ err = mmc_add_card(host->card); -+ if (err) -+ goto remove_added; -+ -+ /* -+ * ...then the SDIO functions. -+ */ -+ for (i = 0;i < funcs;i++) { -+ err = sdio_add_func(host->card->sdio_func[i]); -+ if (err) -+ goto remove_added; -+ } -+ -+ return 0; -+ -+ -+remove_added: -+ /* Remove without lock if the device has been added. */ -+ mmc_sdio_remove(host); -+ mmc_claim_host(host); -+remove: -+ /* And with lock if it hasn't been added. */ -+ if (host->card) -+ mmc_sdio_remove(host); -+err: -+ mmc_detach_bus(host); -+ mmc_release_host(host); -+ -+ printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", -+ mmc_hostname(host), err); -+ -+ return err; -+} -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_bus.c -@@ -0,0 +1,265 @@ -+/* -+ * linux/drivers/mmc/core/sdio_bus.c -+ * -+ * Copyright 2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ * -+ * SDIO function driver model -+ */ -+ -+#include <linux/device.h> -+#include <linux/err.h> -+ -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio_func.h> -+ -+#include "sdio_cis.h" -+#include "sdio_bus.h" -+ -+#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) -+#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) -+ -+/* show configuration fields */ -+#define sdio_config_attr(field, format_string) \ -+static ssize_t \ -+field##_show(struct device *dev, struct device_attribute *attr, char *buf) \ -+{ \ -+ struct sdio_func *func; \ -+ \ -+ func = dev_to_sdio_func (dev); \ -+ return sprintf (buf, format_string, func->field); \ -+} -+ -+sdio_config_attr(class, "0x%02x\n"); -+sdio_config_attr(vendor, "0x%04x\n"); -+sdio_config_attr(device, "0x%04x\n"); -+ -+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct sdio_func *func = dev_to_sdio_func (dev); -+ -+ return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n", -+ func->class, func->vendor, func->device); -+} -+ -+static struct device_attribute sdio_dev_attrs[] = { -+ __ATTR_RO(class), -+ __ATTR_RO(vendor), -+ __ATTR_RO(device), -+ __ATTR_RO(modalias), -+ __ATTR_NULL, -+}; -+ -+static const struct sdio_device_id *sdio_match_one(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class) -+ return NULL; -+ if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor) -+ return NULL; -+ if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device) -+ return NULL; -+ return id; -+} -+ -+static const struct sdio_device_id *sdio_match_device(struct sdio_func *func, -+ struct sdio_driver *sdrv) -+{ -+ const struct sdio_device_id *ids; -+ -+ ids = sdrv->id_table; -+ -+ if (ids) { -+ while (ids->class || ids->vendor || ids->device) { -+ if (sdio_match_one(func, ids)) -+ return ids; -+ ids++; -+ } -+ } -+ -+ return NULL; -+} -+ -+static int sdio_bus_match(struct device *dev, struct device_driver *drv) -+{ -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ struct sdio_driver *sdrv = to_sdio_driver(drv); -+ -+ if (sdio_match_device(func, sdrv)) -+ return 1; -+ -+ return 0; -+} -+ -+static int -+sdio_bus_uevent(struct device *dev, char **envp, -+ int num_envp, char *buffer, int buffer_size) -+{ -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ int i = 0, len = 0; -+ -+ if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, -+ "SDIO_CLASS=%02X", func->class)) -+ return -ENOMEM; -+ -+ if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, -+ "SDIO_ID=%04X:%04X", func->vendor, func->device)) -+ return -ENOMEM; -+ -+ if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, -+ "MODALIAS=sdio:c%02Xv%04Xd%04X", -+ func->class, func->vendor, func->device)) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static int sdio_bus_probe(struct device *dev) -+{ -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ const struct sdio_device_id *id; -+ int ret; -+ -+ id = sdio_match_device(func, drv); -+ if (!id) -+ return -ENODEV; -+ -+ /* Set the default block size so the driver is sure it's something -+ * sensible. */ -+ sdio_claim_host(func); -+ ret = sdio_set_block_size(func, 0); -+ sdio_release_host(func); -+ if (ret) -+ return ret; -+ -+ return drv->probe(func, id); -+} -+ -+static int sdio_bus_remove(struct device *dev) -+{ -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ -+ drv->remove(func); -+ -+ if (func->irq_handler) { -+ printk(KERN_WARNING "WARNING: driver %s did not remove " -+ "its interrupt handler!\n", drv->name); -+ sdio_claim_host(func); -+ sdio_release_irq(func); -+ sdio_release_host(func); -+ } -+ -+ return 0; -+} -+ -+static struct bus_type sdio_bus_type = { -+ .name = "sdio", -+ .dev_attrs = sdio_dev_attrs, -+ .match = sdio_bus_match, -+ .uevent = sdio_bus_uevent, -+ .probe = sdio_bus_probe, -+ .remove = sdio_bus_remove, -+}; -+ -+int sdio_register_bus(void) -+{ -+ return bus_register(&sdio_bus_type); -+} -+ -+void sdio_unregister_bus(void) -+{ -+ bus_unregister(&sdio_bus_type); -+} -+ -+/** -+ * sdio_register_driver - register a function driver -+ * @drv: SDIO function driver -+ */ -+int sdio_register_driver(struct sdio_driver *drv) -+{ -+ drv->drv.name = drv->name; -+ drv->drv.bus = &sdio_bus_type; -+ return driver_register(&drv->drv); -+} -+EXPORT_SYMBOL_GPL(sdio_register_driver); -+ -+/** -+ * sdio_unregister_driver - unregister a function driver -+ * @drv: SDIO function driver -+ */ -+void sdio_unregister_driver(struct sdio_driver *drv) -+{ -+ drv->drv.bus = &sdio_bus_type; -+ driver_unregister(&drv->drv); -+} -+EXPORT_SYMBOL_GPL(sdio_unregister_driver); -+ -+static void sdio_release_func(struct device *dev) -+{ -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ -+ sdio_free_func_cis(func); -+ -+ if (func->info) -+ kfree(func->info); -+ -+ kfree(func); -+} -+ -+/* -+ * Allocate and initialise a new SDIO function structure. -+ */ -+struct sdio_func *sdio_alloc_func(struct mmc_card *card) -+{ -+ struct sdio_func *func; -+ -+ func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL); -+ if (!func) -+ return ERR_PTR(-ENOMEM); -+ -+ func->card = card; -+ -+ device_initialize(&func->dev); -+ -+ func->dev.parent = &card->dev; -+ func->dev.bus = &sdio_bus_type; -+ func->dev.release = sdio_release_func; -+ -+ return func; -+} -+ -+/* -+ * Register a new SDIO function with the driver model. -+ */ -+int sdio_add_func(struct sdio_func *func) -+{ -+ int ret; -+ -+ snprintf(func->dev.bus_id, sizeof(func->dev.bus_id), -+ "%s:%d", mmc_card_id(func->card), func->num); -+ -+ ret = device_add(&func->dev); -+ if (ret == 0) -+ sdio_func_set_present(func); -+ -+ return ret; -+} -+ -+/* -+ * Unregister a SDIO function with the driver model, and -+ * (eventually) free it. -+ */ -+void sdio_remove_func(struct sdio_func *func) -+{ -+ if (sdio_func_present(func)) -+ device_del(&func->dev); -+ -+ put_device(&func->dev); -+} -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_bus.h -@@ -0,0 +1,22 @@ -+/* -+ * linux/drivers/mmc/core/sdio_bus.h -+ * -+ * Copyright 2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+#ifndef _MMC_CORE_SDIO_BUS_H -+#define _MMC_CORE_SDIO_BUS_H -+ -+struct sdio_func *sdio_alloc_func(struct mmc_card *card); -+int sdio_add_func(struct sdio_func *func); -+void sdio_remove_func(struct sdio_func *func); -+ -+int sdio_register_bus(void); -+void sdio_unregister_bus(void); -+ -+#endif -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_cis.c -@@ -0,0 +1,346 @@ -+/* -+ * linux/drivers/mmc/core/sdio_cis.c -+ * -+ * Author: Nicolas Pitre -+ * Created: June 11, 2007 -+ * Copyright: MontaVista Software Inc. -+ * -+ * Copyright 2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#include <linux/kernel.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_func.h> -+ -+#include "sdio_cis.h" -+#include "sdio_ops.h" -+ -+static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, -+ const unsigned char *buf, unsigned size) -+{ -+ unsigned i, nr_strings; -+ char **buffer, *string; -+ -+ buf += 2; -+ size -= 2; -+ -+ nr_strings = 0; -+ for (i = 0; i < size; i++) { -+ if (buf[i] == 0xff) -+ break; -+ if (buf[i] == 0) -+ nr_strings++; -+ } -+ -+ if (buf[i-1] != '\0') { -+ printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n"); -+ return 0; -+ } -+ -+ size = i; -+ -+ buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ string = (char*)(buffer + nr_strings); -+ -+ for (i = 0; i < nr_strings; i++) { -+ buffer[i] = string; -+ strcpy(string, buf); -+ string += strlen(string) + 1; -+ buf += strlen(buf) + 1; -+ } -+ -+ if (func) { -+ func->num_info = nr_strings; -+ func->info = (const char**)buffer; -+ } else { -+ card->num_info = nr_strings; -+ card->info = (const char**)buffer; -+ } -+ -+ return 0; -+} -+ -+static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func, -+ const unsigned char *buf, unsigned size) -+{ -+ unsigned int vendor, device; -+ -+ /* TPLMID_MANF */ -+ vendor = buf[0] | (buf[1] << 8); -+ -+ /* TPLMID_CARD */ -+ device = buf[2] | (buf[3] << 8); -+ -+ if (func) { -+ func->vendor = vendor; -+ func->device = device; -+ } else { -+ card->cis.vendor = vendor; -+ card->cis.device = device; -+ } -+ -+ return 0; -+} -+ -+static const unsigned char speed_val[16] = -+ { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; -+static const unsigned int speed_unit[8] = -+ { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; -+ -+static int cistpl_funce_common(struct mmc_card *card, -+ const unsigned char *buf, unsigned size) -+{ -+ if (size < 0x04 || buf[0] != 0) -+ return -EINVAL; -+ -+ /* TPLFE_FN0_BLK_SIZE */ -+ card->cis.blksize = buf[1] | (buf[2] << 8); -+ -+ /* TPLFE_MAX_TRAN_SPEED */ -+ card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] * -+ speed_unit[buf[3] & 7]; -+ -+ return 0; -+} -+ -+static int cistpl_funce_func(struct sdio_func *func, -+ const unsigned char *buf, unsigned size) -+{ -+ unsigned vsn; -+ unsigned min_size; -+ -+ vsn = func->card->cccr.sdio_vsn; -+ min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; -+ -+ if (size < min_size || buf[0] != 1) -+ return -EINVAL; -+ -+ /* TPLFE_MAX_BLK_SIZE */ -+ func->max_blksize = buf[12] | (buf[13] << 8); -+ -+ return 0; -+} -+ -+static int cistpl_funce(struct mmc_card *card, struct sdio_func *func, -+ const unsigned char *buf, unsigned size) -+{ -+ int ret; -+ -+ /* -+ * There should be two versions of the CISTPL_FUNCE tuple, -+ * one for the common CIS (function 0) and a version used by -+ * the individual function's CIS (1-7). Yet, the later has a -+ * different length depending on the SDIO spec version. -+ */ -+ if (func) -+ ret = cistpl_funce_func(func, buf, size); -+ else -+ ret = cistpl_funce_common(card, buf, size); -+ -+ if (ret) { -+ printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u " -+ "type %u\n", mmc_hostname(card->host), size, buf[0]); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, -+ const unsigned char *, unsigned); -+ -+struct cis_tpl { -+ unsigned char code; -+ unsigned char min_size; -+ tpl_parse_t *parse; -+}; -+ -+static const struct cis_tpl cis_tpl_list[] = { -+ { 0x15, 3, cistpl_vers_1 }, -+ { 0x20, 4, cistpl_manfid }, -+ { 0x21, 2, /* cistpl_funcid */ }, -+ { 0x22, 0, cistpl_funce }, -+}; -+ -+static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) -+{ -+ int ret; -+ struct sdio_func_tuple *this, **prev; -+ unsigned i, ptr = 0; -+ -+ /* -+ * Note that this works for the common CIS (function number 0) as -+ * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS -+ * have the same offset. -+ */ -+ for (i = 0; i < 3; i++) { -+ unsigned char x, fn; -+ -+ if (func) -+ fn = func->num; -+ else -+ fn = 0; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, -+ SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x); -+ if (ret) -+ return ret; -+ ptr |= x << (i * 8); -+ } -+ -+ if (func) -+ prev = &func->tuples; -+ else -+ prev = &card->tuples; -+ -+ BUG_ON(*prev); -+ -+ do { -+ unsigned char tpl_code, tpl_link; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code); -+ if (ret) -+ break; -+ -+ /* 0xff means we're done */ -+ if (tpl_code == 0xff) -+ break; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link); -+ if (ret) -+ break; -+ -+ this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL); -+ if (!this) -+ return -ENOMEM; -+ -+ for (i = 0; i < tpl_link; i++) { -+ ret = mmc_io_rw_direct(card, 0, 0, -+ ptr + i, 0, &this->data[i]); -+ if (ret) -+ break; -+ } -+ if (ret) { -+ kfree(this); -+ break; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++) -+ if (cis_tpl_list[i].code == tpl_code) -+ break; -+ if (i >= ARRAY_SIZE(cis_tpl_list)) { -+ /* this tuple is unknown to the core */ -+ this->next = NULL; -+ this->code = tpl_code; -+ this->size = tpl_link; -+ *prev = this; -+ prev = &this->next; -+ printk(KERN_DEBUG -+ "%s: queuing CIS tuple 0x%02x length %u\n", -+ mmc_hostname(card->host), tpl_code, tpl_link); -+ } else { -+ const struct cis_tpl *tpl = cis_tpl_list + i; -+ if (tpl_link < tpl->min_size) { -+ printk(KERN_ERR -+ "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n", -+ mmc_hostname(card->host), -+ tpl_code, tpl_link, tpl->min_size); -+ ret = -EINVAL; -+ } else if (tpl->parse) { -+ ret = tpl->parse(card, func, -+ this->data, tpl_link); -+ } -+ kfree(this); -+ } -+ -+ ptr += tpl_link; -+ } while (!ret); -+ -+ /* -+ * Link in all unknown tuples found in the common CIS so that -+ * drivers don't have to go digging in two places. -+ */ -+ if (func) -+ *prev = card->tuples; -+ -+ return ret; -+} -+ -+int sdio_read_common_cis(struct mmc_card *card) -+{ -+ return sdio_read_cis(card, NULL); -+} -+ -+void sdio_free_common_cis(struct mmc_card *card) -+{ -+ struct sdio_func_tuple *tuple, *victim; -+ -+ tuple = card->tuples; -+ -+ while (tuple) { -+ victim = tuple; -+ tuple = tuple->next; -+ kfree(victim); -+ } -+ -+ card->tuples = NULL; -+} -+ -+int sdio_read_func_cis(struct sdio_func *func) -+{ -+ int ret; -+ -+ ret = sdio_read_cis(func->card, func); -+ if (ret) -+ return ret; -+ -+ /* -+ * Since we've linked to tuples in the card structure, -+ * we must make sure we have a reference to it. -+ */ -+ get_device(&func->card->dev); -+ -+ /* -+ * Vendor/device id is optional for function CIS, so -+ * copy it from the card structure as needed. -+ */ -+ if (func->vendor == 0) { -+ func->vendor = func->card->cis.vendor; -+ func->device = func->card->cis.device; -+ } -+ -+ return 0; -+} -+ -+void sdio_free_func_cis(struct sdio_func *func) -+{ -+ struct sdio_func_tuple *tuple, *victim; -+ -+ tuple = func->tuples; -+ -+ while (tuple && tuple != func->card->tuples) { -+ victim = tuple; -+ tuple = tuple->next; -+ kfree(victim); -+ } -+ -+ func->tuples = NULL; -+ -+ /* -+ * We have now removed the link to the tuples in the -+ * card structure, so remove the reference. -+ */ -+ put_device(&func->card->dev); -+} -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_cis.h -@@ -0,0 +1,23 @@ -+/* -+ * linux/drivers/mmc/core/sdio_cis.h -+ * -+ * Author: Nicolas Pitre -+ * Created: June 11, 2007 -+ * Copyright: MontaVista Software Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#ifndef _MMC_SDIO_CIS_H -+#define _MMC_SDIO_CIS_H -+ -+int sdio_read_common_cis(struct mmc_card *card); -+void sdio_free_common_cis(struct mmc_card *card); -+ -+int sdio_read_func_cis(struct sdio_func *func); -+void sdio_free_func_cis(struct sdio_func *func); -+ -+#endif ---- /dev/null -+++ b/drivers/mmc/core/sdio_io.c -@@ -0,0 +1,548 @@ -+/* -+ * linux/drivers/mmc/core/sdio_io.c -+ * -+ * Copyright 2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_func.h> -+ -+#include "sdio_ops.h" -+ -+/** -+ * sdio_claim_host - exclusively claim a bus for a certain SDIO function -+ * @func: SDIO function that will be accessed -+ * -+ * Claim a bus for a set of operations. The SDIO function given -+ * is used to figure out which bus is relevant. -+ */ -+void sdio_claim_host(struct sdio_func *func) -+{ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ mmc_claim_host(func->card->host); -+} -+EXPORT_SYMBOL_GPL(sdio_claim_host); -+ -+/** -+ * sdio_release_host - release a bus for a certain SDIO function -+ * @func: SDIO function that was accessed -+ * -+ * Release a bus, allowing others to claim the bus for their -+ * operations. -+ */ -+void sdio_release_host(struct sdio_func *func) -+{ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ mmc_release_host(func->card->host); -+} -+EXPORT_SYMBOL_GPL(sdio_release_host); -+ -+/** -+ * sdio_enable_func - enables a SDIO function for usage -+ * @func: SDIO function to enable -+ * -+ * Powers up and activates a SDIO function so that register -+ * access is possible. -+ */ -+int sdio_enable_func(struct sdio_func *func) -+{ -+ int ret; -+ unsigned char reg; -+ unsigned long timeout; -+ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func)); -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®); -+ if (ret) -+ goto err; -+ -+ reg |= 1 << func->num; -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL); -+ if (ret) -+ goto err; -+ -+ /* -+ * FIXME: This should timeout based on information in the CIS, -+ * but we don't have card to parse that yet. -+ */ -+ timeout = jiffies + HZ; -+ -+ while (1) { -+ ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®); -+ if (ret) -+ goto err; -+ if (reg & (1 << func->num)) -+ break; -+ ret = -ETIME; -+ if (time_after(jiffies, timeout)) -+ goto err; -+ } -+ -+ pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func)); -+ -+ return 0; -+ -+err: -+ pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func)); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(sdio_enable_func); -+ -+/** -+ * sdio_disable_func - disable a SDIO function -+ * @func: SDIO function to disable -+ * -+ * Powers down and deactivates a SDIO function. Register access -+ * to this function will fail until the function is reenabled. -+ */ -+int sdio_disable_func(struct sdio_func *func) -+{ -+ int ret; -+ unsigned char reg; -+ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func)); -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®); -+ if (ret) -+ goto err; -+ -+ reg &= ~(1 << func->num); -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL); -+ if (ret) -+ goto err; -+ -+ pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func)); -+ -+ return 0; -+ -+err: -+ pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func)); -+ return -EIO; -+} -+EXPORT_SYMBOL_GPL(sdio_disable_func); -+ -+/** -+ * sdio_set_block_size - set the block size of an SDIO function -+ * @func: SDIO function to change -+ * @blksz: new block size or 0 to use the default. -+ * -+ * The default block size is the largest supported by both the function -+ * and the host, with a maximum of 512 to ensure that arbitrarily sized -+ * data transfer use the optimal (least) number of commands. -+ * -+ * A driver may call this to override the default block size set by the -+ * core. This can be used to set a block size greater than the maximum -+ * that reported by the card; it is the driver's responsibility to ensure -+ * it uses a value that the card supports. -+ * -+ * Returns 0 on success, -EINVAL if the host does not support the -+ * requested block size, or -EIO (etc.) if one of the resultant FBR block -+ * size register writes failed. -+ * -+ */ -+int sdio_set_block_size(struct sdio_func *func, unsigned blksz) -+{ -+ int ret; -+ -+ if (blksz > func->card->host->max_blk_size) -+ return -EINVAL; -+ -+ if (blksz == 0) { -+ blksz = min(min( -+ func->max_blksize, -+ func->card->host->max_blk_size), -+ 512u); -+ } -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, -+ SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE, -+ blksz & 0xff, NULL); -+ if (ret) -+ return ret; -+ ret = mmc_io_rw_direct(func->card, 1, 0, -+ SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1, -+ (blksz >> 8) & 0xff, NULL); -+ if (ret) -+ return ret; -+ func->cur_blksize = blksz; -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(sdio_set_block_size); -+ -+/* Split an arbitrarily sized data transfer into several -+ * IO_RW_EXTENDED commands. */ -+static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, -+ unsigned addr, int incr_addr, u8 *buf, unsigned size) -+{ -+ unsigned remainder = size; -+ unsigned max_blocks; -+ int ret; -+ -+ /* Do the bulk of the transfer using block mode (if supported). */ -+ if (func->card->cccr.multi_block) { -+ /* Blocks per command is limited by host count, host transfer -+ * size (we only use a single sg entry) and the maximum for -+ * IO_RW_EXTENDED of 511 blocks. */ -+ max_blocks = min(min( -+ func->card->host->max_blk_count, -+ func->card->host->max_seg_size / func->cur_blksize), -+ 511u); -+ -+ while (remainder > func->cur_blksize) { -+ unsigned blocks; -+ -+ blocks = remainder / func->cur_blksize; -+ if (blocks > max_blocks) -+ blocks = max_blocks; -+ size = blocks * func->cur_blksize; -+ -+ ret = mmc_io_rw_extended(func->card, write, -+ func->num, addr, incr_addr, buf, -+ blocks, func->cur_blksize); -+ if (ret) -+ return ret; -+ -+ remainder -= size; -+ buf += size; -+ if (incr_addr) -+ addr += size; -+ } -+ } -+ -+ /* Write the remainder using byte mode. */ -+ while (remainder > 0) { -+ size = remainder; -+ if (size > func->cur_blksize) -+ size = func->cur_blksize; -+ if (size > 512) -+ size = 512; /* maximum size for byte mode */ -+ -+ ret = mmc_io_rw_extended(func->card, write, func->num, addr, -+ incr_addr, buf, 1, size); -+ if (ret) -+ return ret; -+ -+ remainder -= size; -+ buf += size; -+ if (incr_addr) -+ addr += size; -+ } -+ return 0; -+} -+ -+/** -+ * sdio_readb - read a single byte from a SDIO function -+ * @func: SDIO function to access -+ * @addr: address to read -+ * @err_ret: optional status value from transfer -+ * -+ * Reads a single byte from the address space of a given SDIO -+ * function. If there is a problem reading the address, 0xff -+ * is returned and @err_ret will contain the error code. -+ */ -+unsigned char sdio_readb(struct sdio_func *func, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ unsigned char val; -+ -+ BUG_ON(!func); -+ -+ if (err_ret) -+ *err_ret = 0; -+ -+ ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val); -+ if (ret) { -+ if (err_ret) -+ *err_ret = ret; -+ return 0xFF; -+ } -+ -+ return val; -+} -+EXPORT_SYMBOL_GPL(sdio_readb); -+ -+/** -+ * sdio_writeb - write a single byte to a SDIO function -+ * @func: SDIO function to access -+ * @b: byte to write -+ * @addr: address to write to -+ * @err_ret: optional status value from transfer -+ * -+ * Writes a single byte to the address space of a given SDIO -+ * function. @err_ret will contain the status of the actual -+ * transfer. -+ */ -+void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ BUG_ON(!func); -+ -+ ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL); -+ if (err_ret) -+ *err_ret = ret; -+} -+EXPORT_SYMBOL_GPL(sdio_writeb); -+ -+/** -+ * sdio_memcpy_fromio - read a chunk of memory from a SDIO function -+ * @func: SDIO function to access -+ * @dst: buffer to store the data -+ * @addr: address to begin reading from -+ * @count: number of bytes to read -+ * -+ * Reads from the address space of a given SDIO function. Return -+ * value indicates if the transfer succeeded or not. -+ */ -+int sdio_memcpy_fromio(struct sdio_func *func, void *dst, -+ unsigned int addr, int count) -+{ -+ return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count); -+} -+EXPORT_SYMBOL_GPL(sdio_memcpy_fromio); -+ -+/** -+ * sdio_memcpy_toio - write a chunk of memory to a SDIO function -+ * @func: SDIO function to access -+ * @addr: address to start writing to -+ * @src: buffer that contains the data to write -+ * @count: number of bytes to write -+ * -+ * Writes to the address space of a given SDIO function. Return -+ * value indicates if the transfer succeeded or not. -+ */ -+int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, -+ void *src, int count) -+{ -+ return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count); -+} -+EXPORT_SYMBOL_GPL(sdio_memcpy_toio); -+ -+/** -+ * sdio_readsb - read from a FIFO on a SDIO function -+ * @func: SDIO function to access -+ * @dst: buffer to store the data -+ * @addr: address of (single byte) FIFO -+ * @count: number of bytes to read -+ * -+ * Reads from the specified FIFO of a given SDIO function. Return -+ * value indicates if the transfer succeeded or not. -+ */ -+int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr, -+ int count) -+{ -+ return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count); -+} -+ -+EXPORT_SYMBOL_GPL(sdio_readsb); -+ -+/** -+ * sdio_writesb - write to a FIFO of a SDIO function -+ * @func: SDIO function to access -+ * @addr: address of (single byte) FIFO -+ * @src: buffer that contains the data to write -+ * @count: number of bytes to write -+ * -+ * Writes to the specified FIFO of a given SDIO function. Return -+ * value indicates if the transfer succeeded or not. -+ */ -+int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src, -+ int count) -+{ -+ return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count); -+} -+EXPORT_SYMBOL_GPL(sdio_writesb); -+ -+/** -+ * sdio_readw - read a 16 bit integer from a SDIO function -+ * @func: SDIO function to access -+ * @addr: address to read -+ * @err_ret: optional status value from transfer -+ * -+ * Reads a 16 bit integer from the address space of a given SDIO -+ * function. If there is a problem reading the address, 0xffff -+ * is returned and @err_ret will contain the error code. -+ */ -+unsigned short sdio_readw(struct sdio_func *func, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ if (err_ret) -+ *err_ret = 0; -+ -+ ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2); -+ if (ret) { -+ if (err_ret) -+ *err_ret = ret; -+ return 0xFFFF; -+ } -+ -+ return le16_to_cpu(*(u16*)func->tmpbuf); -+} -+EXPORT_SYMBOL_GPL(sdio_readw); -+ -+/** -+ * sdio_writew - write a 16 bit integer to a SDIO function -+ * @func: SDIO function to access -+ * @b: integer to write -+ * @addr: address to write to -+ * @err_ret: optional status value from transfer -+ * -+ * Writes a 16 bit integer to the address space of a given SDIO -+ * function. @err_ret will contain the status of the actual -+ * transfer. -+ */ -+void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ *(u16*)func->tmpbuf = cpu_to_le16(b); -+ -+ ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2); -+ if (err_ret) -+ *err_ret = ret; -+} -+EXPORT_SYMBOL_GPL(sdio_writew); -+ -+/** -+ * sdio_readl - read a 32 bit integer from a SDIO function -+ * @func: SDIO function to access -+ * @addr: address to read -+ * @err_ret: optional status value from transfer -+ * -+ * Reads a 32 bit integer from the address space of a given SDIO -+ * function. If there is a problem reading the address, -+ * 0xffffffff is returned and @err_ret will contain the error -+ * code. -+ */ -+unsigned long sdio_readl(struct sdio_func *func, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ if (err_ret) -+ *err_ret = 0; -+ -+ ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4); -+ if (ret) { -+ if (err_ret) -+ *err_ret = ret; -+ return 0xFFFFFFFF; -+ } -+ -+ return le32_to_cpu(*(u32*)func->tmpbuf); -+} -+EXPORT_SYMBOL_GPL(sdio_readl); -+ -+/** -+ * sdio_writel - write a 32 bit integer to a SDIO function -+ * @func: SDIO function to access -+ * @b: integer to write -+ * @addr: address to write to -+ * @err_ret: optional status value from transfer -+ * -+ * Writes a 32 bit integer to the address space of a given SDIO -+ * function. @err_ret will contain the status of the actual -+ * transfer. -+ */ -+void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ *(u32*)func->tmpbuf = cpu_to_le32(b); -+ -+ ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4); -+ if (err_ret) -+ *err_ret = ret; -+} -+EXPORT_SYMBOL_GPL(sdio_writel); -+ -+/** -+ * sdio_f0_readb - read a single byte from SDIO function 0 -+ * @func: an SDIO function of the card -+ * @addr: address to read -+ * @err_ret: optional status value from transfer -+ * -+ * Reads a single byte from the address space of SDIO function 0. -+ * If there is a problem reading the address, 0xff is returned -+ * and @err_ret will contain the error code. -+ */ -+unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ unsigned char val; -+ -+ BUG_ON(!func); -+ -+ if (err_ret) -+ *err_ret = 0; -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val); -+ if (ret) { -+ if (err_ret) -+ *err_ret = ret; -+ return 0xFF; -+ } -+ -+ return val; -+} -+EXPORT_SYMBOL_GPL(sdio_f0_readb); -+ -+/** -+ * sdio_f0_writeb - write a single byte to SDIO function 0 -+ * @func: an SDIO function of the card -+ * @b: byte to write -+ * @addr: address to write to -+ * @err_ret: optional status value from transfer -+ * -+ * Writes a single byte to the address space of SDIO function 0. -+ * @err_ret will contain the status of the actual transfer. -+ * -+ * Only writes to the vendor specific CCCR registers (0xF0 - -+ * 0xFF) are permiited; @err_ret will be set to -EINVAL for * -+ * writes outside this range. -+ */ -+void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, -+ int *err_ret) -+{ -+ int ret; -+ -+ BUG_ON(!func); -+ -+ if (addr < 0xF0 || addr > 0xFF) { -+ if (err_ret) -+ *err_ret = -EINVAL; -+ return; -+ } -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL); -+ if (err_ret) -+ *err_ret = ret; -+} -+EXPORT_SYMBOL_GPL(sdio_f0_writeb); ---- /dev/null -+++ b/drivers/mmc/core/sdio_irq.c -@@ -0,0 +1,267 @@ -+/* -+ * linux/drivers/mmc/core/sdio_irq.c -+ * -+ * Author: Nicolas Pitre -+ * Created: June 18, 2007 -+ * Copyright: MontaVista Software Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/kthread.h> -+#include <linux/wait.h> -+#include <linux/delay.h> -+ -+#include <linux/mmc/core.h> -+#include <linux/mmc/host.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_func.h> -+ -+#include "sdio_ops.h" -+ -+static int process_sdio_pending_irqs(struct mmc_card *card) -+{ -+ int i, ret, count; -+ unsigned char pending; -+ -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending); -+ if (ret) { -+ printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n", -+ mmc_card_id(card), ret); -+ return ret; -+ } -+ -+ count = 0; -+ for (i = 1; i <= 7; i++) { -+ if (pending & (1 << i)) { -+ struct sdio_func *func = card->sdio_func[i - 1]; -+ if (!func) { -+ printk(KERN_WARNING "%s: pending IRQ for " -+ "non-existant function\n", -+ mmc_card_id(card)); -+ ret = -EINVAL; -+ } else if (func->irq_handler) { -+ func->irq_handler(func); -+ count++; -+ } else { -+ printk(KERN_WARNING "%s: pending IRQ with no handler\n", -+ sdio_func_id(func)); -+ ret = -EINVAL; -+ } -+ } -+ } -+ -+ if (count) -+ return count; -+ -+ return ret; -+} -+ -+static int sdio_irq_thread(void *_host) -+{ -+ struct mmc_host *host = _host; -+ struct sched_param param = { .sched_priority = 1 }; -+ unsigned long period, idle_period; -+ int ret; -+ -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+ -+ /* -+ * We want to allow for SDIO cards to work even on non SDIO -+ * aware hosts. One thing that non SDIO host cannot do is -+ * asynchronous notification of pending SDIO card interrupts -+ * hence we poll for them in that case. -+ */ -+ idle_period = msecs_to_jiffies(10); -+ period = (host->caps & MMC_CAP_SDIO_IRQ) ? -+ MAX_SCHEDULE_TIMEOUT : idle_period; -+ -+ pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n", -+ mmc_hostname(host), period); -+ -+ do { -+ /* -+ * We claim the host here on drivers behalf for a couple -+ * reasons: -+ * -+ * 1) it is already needed to retrieve the CCCR_INTx; -+ * 2) we want the driver(s) to clear the IRQ condition ASAP; -+ * 3) we need to control the abort condition locally. -+ * -+ * Just like traditional hard IRQ handlers, we expect SDIO -+ * IRQ handlers to be quick and to the point, so that the -+ * holding of the host lock does not cover too much work -+ * that doesn't require that lock to be held. -+ */ -+ ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort); -+ if (ret) -+ break; -+ ret = process_sdio_pending_irqs(host->card); -+ mmc_release_host(host); -+ -+ /* -+ * Give other threads a chance to run in the presence of -+ * errors. FIXME: determine if due to card removal and -+ * possibly exit this thread if so. -+ */ -+ if (ret < 0) -+ ssleep(1); -+ -+ /* -+ * Adaptive polling frequency based on the assumption -+ * that an interrupt will be closely followed by more. -+ * This has a substantial benefit for network devices. -+ */ -+ if (!(host->caps & MMC_CAP_SDIO_IRQ)) { -+ if (ret > 0) -+ period /= 2; -+ else { -+ period++; -+ if (period > idle_period) -+ period = idle_period; -+ } -+ } -+ -+ set_task_state(current, TASK_INTERRUPTIBLE); -+ if (host->caps & MMC_CAP_SDIO_IRQ) -+ host->ops->enable_sdio_irq(host, 1); -+ if (!kthread_should_stop()) -+ schedule_timeout(period); -+ set_task_state(current, TASK_RUNNING); -+ } while (!kthread_should_stop()); -+ -+ if (host->caps & MMC_CAP_SDIO_IRQ) -+ host->ops->enable_sdio_irq(host, 0); -+ -+ pr_debug("%s: IRQ thread exiting with code %d\n", -+ mmc_hostname(host), ret); -+ -+ return ret; -+} -+ -+static int sdio_card_irq_get(struct mmc_card *card) -+{ -+ struct mmc_host *host = card->host; -+ -+ WARN_ON(!host->claimed); -+ -+ if (!host->sdio_irqs++) { -+ atomic_set(&host->sdio_irq_thread_abort, 0); -+ host->sdio_irq_thread = -+ kthread_run(sdio_irq_thread, host, "ksdiorqd"); -+ if (IS_ERR(host->sdio_irq_thread)) { -+ int err = PTR_ERR(host->sdio_irq_thread); -+ host->sdio_irqs--; -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static int sdio_card_irq_put(struct mmc_card *card) -+{ -+ struct mmc_host *host = card->host; -+ -+ WARN_ON(!host->claimed); -+ BUG_ON(host->sdio_irqs < 1); -+ -+ if (!--host->sdio_irqs) { -+ atomic_set(&host->sdio_irq_thread_abort, 1); -+ kthread_stop(host->sdio_irq_thread); -+ } -+ -+ return 0; -+} -+ -+/** -+ * sdio_claim_irq - claim the IRQ for a SDIO function -+ * @func: SDIO function -+ * @handler: IRQ handler callback -+ * -+ * Claim and activate the IRQ for the given SDIO function. The provided -+ * handler will be called when that IRQ is asserted. The host is always -+ * claimed already when the handler is called so the handler must not -+ * call sdio_claim_host() nor sdio_release_host(). -+ */ -+int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler) -+{ -+ int ret; -+ unsigned char reg; -+ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func)); -+ -+ if (func->irq_handler) { -+ pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func)); -+ return -EBUSY; -+ } -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); -+ if (ret) -+ return ret; -+ -+ reg |= 1 << func->num; -+ -+ reg |= 1; /* Master interrupt enable */ -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); -+ if (ret) -+ return ret; -+ -+ func->irq_handler = handler; -+ ret = sdio_card_irq_get(func->card); -+ if (ret) -+ func->irq_handler = NULL; -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(sdio_claim_irq); -+ -+/** -+ * sdio_release_irq - release the IRQ for a SDIO function -+ * @func: SDIO function -+ * -+ * Disable and release the IRQ for the given SDIO function. -+ */ -+int sdio_release_irq(struct sdio_func *func) -+{ -+ int ret; -+ unsigned char reg; -+ -+ BUG_ON(!func); -+ BUG_ON(!func->card); -+ -+ pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func)); -+ -+ if (func->irq_handler) { -+ func->irq_handler = NULL; -+ sdio_card_irq_put(func->card); -+ } -+ -+ ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); -+ if (ret) -+ return ret; -+ -+ reg &= ~(1 << func->num); -+ -+ /* Disable master interrupt with the last function interrupt */ -+ if (!(reg & 0xFE)) -+ reg = 0; -+ -+ ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(sdio_release_irq); -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_ops.c -@@ -0,0 +1,175 @@ -+/* -+ * linux/drivers/mmc/sdio_ops.c -+ * -+ * Copyright 2006-2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#include <linux/scatterlist.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/mmc.h> -+#include <linux/mmc/sdio.h> -+ -+#include "core.h" -+ -+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) -+{ -+ struct mmc_command cmd; -+ int i, err = 0; -+ -+ BUG_ON(!host); -+ -+ memset(&cmd, 0, sizeof(struct mmc_command)); -+ -+ cmd.opcode = SD_IO_SEND_OP_COND; -+ cmd.arg = ocr; -+ cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR; -+ -+ for (i = 100; i; i--) { -+ err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -+ if (err) -+ break; -+ -+ /* if we're just probing, do a single pass */ -+ if (ocr == 0) -+ break; -+ -+ /* otherwise wait until reset completes */ -+ if (mmc_host_is_spi(host)) { -+ /* -+ * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate -+ * an initialized card under SPI, but some cards -+ * (Marvell's) only behave when looking at this -+ * one. -+ */ -+ if (cmd.resp[1] & MMC_CARD_BUSY) -+ break; -+ } else { -+ if (cmd.resp[0] & MMC_CARD_BUSY) -+ break; -+ } -+ -+ err = -ETIMEDOUT; -+ -+ mmc_delay(10); -+ } -+ -+ if (rocr) -+ *rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0]; -+ -+ return err; -+} -+ -+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, -+ unsigned addr, u8 in, u8* out) -+{ -+ struct mmc_command cmd; -+ int err; -+ -+ BUG_ON(!card); -+ BUG_ON(fn > 7); -+ -+ memset(&cmd, 0, sizeof(struct mmc_command)); -+ -+ cmd.opcode = SD_IO_RW_DIRECT; -+ cmd.arg = write ? 0x80000000 : 0x00000000; -+ cmd.arg |= fn << 28; -+ cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; -+ cmd.arg |= addr << 9; -+ cmd.arg |= in; -+ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; -+ -+ err = mmc_wait_for_cmd(card->host, &cmd, 0); -+ if (err) -+ return err; -+ -+ if (mmc_host_is_spi(card->host)) { -+ /* host driver already reported errors */ -+ } else { -+ if (cmd.resp[0] & R5_ERROR) -+ return -EIO; -+ if (cmd.resp[0] & R5_FUNCTION_NUMBER) -+ return -EINVAL; -+ if (cmd.resp[0] & R5_OUT_OF_RANGE) -+ return -ERANGE; -+ } -+ -+ if (out) { -+ if (mmc_host_is_spi(card->host)) -+ *out = (cmd.resp[0] >> 8) & 0xFF; -+ else -+ *out = cmd.resp[0] & 0xFF; -+ } -+ -+ return 0; -+} -+ -+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, -+ unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) -+{ -+ struct mmc_request mrq; -+ struct mmc_command cmd; -+ struct mmc_data data; -+ struct scatterlist sg; -+ -+ BUG_ON(!card); -+ BUG_ON(fn > 7); -+ BUG_ON(blocks == 1 && blksz > 512); -+ WARN_ON(blocks == 0); -+ WARN_ON(blksz == 0); -+ -+ memset(&mrq, 0, sizeof(struct mmc_request)); -+ memset(&cmd, 0, sizeof(struct mmc_command)); -+ memset(&data, 0, sizeof(struct mmc_data)); -+ -+ mrq.cmd = &cmd; -+ mrq.data = &data; -+ -+ cmd.opcode = SD_IO_RW_EXTENDED; -+ cmd.arg = write ? 0x80000000 : 0x00000000; -+ cmd.arg |= fn << 28; -+ cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; -+ cmd.arg |= addr << 9; -+ if (blocks == 1 && blksz <= 512) -+ cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ -+ else -+ cmd.arg |= 0x08000000 | blocks; /* block mode */ -+ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; -+ -+ data.blksz = blksz; -+ data.blocks = blocks; -+ data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; -+ data.sg = &sg; -+ data.sg_len = 1; -+ -+ sg_init_one(&sg, buf, blksz * blocks); -+ -+ mmc_set_data_timeout(&data, card); -+ -+ mmc_wait_for_req(card->host, &mrq); -+ -+ if (cmd.error) -+ return cmd.error; -+ if (data.error) -+ return data.error; -+ -+ if (mmc_host_is_spi(card->host)) { -+ /* host driver already reported errors */ -+ } else { -+ if (cmd.resp[0] & R5_ERROR) -+ return -EIO; -+ if (cmd.resp[0] & R5_FUNCTION_NUMBER) -+ return -EINVAL; -+ if (cmd.resp[0] & R5_OUT_OF_RANGE) -+ return -ERANGE; -+ } -+ -+ return 0; -+} -+ ---- /dev/null -+++ b/drivers/mmc/core/sdio_ops.h -@@ -0,0 +1,22 @@ -+/* -+ * linux/drivers/mmc/sdio_ops.c -+ * -+ * Copyright 2006-2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#ifndef _MMC_SDIO_OPS_H -+#define _MMC_SDIO_OPS_H -+ -+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); -+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, -+ unsigned addr, u8 in, u8* out); -+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, -+ unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); -+ -+#endif -+ ---- a/include/linux/mmc/card.h -+++ b/include/linux/mmc/card.h -@@ -55,7 +55,28 @@ struct sd_switch_caps { - unsigned int hs_max_dtr; - }; - -+struct sdio_cccr { -+ unsigned int sdio_vsn; -+ unsigned int sd_vsn; -+ unsigned int multi_block:1, -+ low_speed:1, -+ wide_bus:1, -+ high_power:1, -+ high_speed:1; -+}; -+ -+struct sdio_cis { -+ unsigned short vendor; -+ unsigned short device; -+ unsigned short blksize; -+ unsigned int max_dtr; -+}; -+ - struct mmc_host; -+struct sdio_func; -+struct sdio_func_tuple; -+ -+#define SDIO_MAX_FUNCS 7 - - /* - * MMC device -@@ -67,11 +88,13 @@ struct mmc_card { - unsigned int type; /* card type */ - #define MMC_TYPE_MMC 0 /* MMC card */ - #define MMC_TYPE_SD 1 /* SD card */ -+#define MMC_TYPE_SDIO 2 /* SDIO card */ - unsigned int state; /* (our) card state */ - #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ - #define MMC_STATE_READONLY (1<<1) /* card is read-only */ - #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */ - #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ -+ - u32 raw_cid[4]; /* raw card CID */ - u32 raw_csd[4]; /* raw card CSD */ - u32 raw_scr[2]; /* raw card SCR */ -@@ -80,10 +103,19 @@ struct mmc_card { - struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ - struct sd_scr scr; /* extra SD information */ - struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ -+ -+ unsigned int sdio_funcs; /* number of SDIO functions */ -+ struct sdio_cccr cccr; /* common card info */ -+ struct sdio_cis cis; /* common tuple info */ -+ struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ -+ unsigned num_info; /* number of info strings */ -+ const char **info; /* info strings */ -+ struct sdio_func_tuple *tuples; /* unknown common tuples */ - }; - - #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) - #define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD) -+#define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO) - - #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) - #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) ---- a/include/linux/mmc/core.h -+++ b/include/linux/mmc/core.h -@@ -25,14 +25,20 @@ struct mmc_command { - #define MMC_RSP_CRC (1 << 2) /* expect valid crc */ - #define MMC_RSP_BUSY (1 << 3) /* card may send busy */ - #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ --#define MMC_CMD_MASK (3 << 5) /* command type */ -+ -+#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */ - #define MMC_CMD_AC (0 << 5) - #define MMC_CMD_ADTC (1 << 5) - #define MMC_CMD_BC (2 << 5) - #define MMC_CMD_BCR (3 << 5) - -+#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */ -+#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */ -+#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */ -+#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */ -+ - /* -- * These are the response types, and correspond to valid bit -+ * These are the native response types, and correspond to valid bit - * patterns of the above flags. One additional valid pattern - * is all zeros, which means we don't expect a response. - */ -@@ -41,12 +47,30 @@ struct mmc_command { - #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) - #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) - #define MMC_RSP_R3 (MMC_RSP_PRESENT) -+#define MMC_RSP_R4 (MMC_RSP_PRESENT) -+#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) - #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) - #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) - - #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) - - /* -+ * These are the SPI response types for MMC, SD, and SDIO cards. -+ * Commands return R1, with maybe more info. Zero is an error type; -+ * callers must always provide the appropriate MMC_RSP_SPI_Rx flags. -+ */ -+#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1) -+#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY) -+#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2) -+#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4) -+#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4) -+#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2) -+#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4) -+ -+#define mmc_spi_resp_type(cmd) ((cmd)->flags & \ -+ (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4)) -+ -+/* - * These are the command types. - */ - #define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK) -@@ -54,12 +78,19 @@ struct mmc_command { - unsigned int retries; /* max number of retries */ - unsigned int error; /* command error */ - --#define MMC_ERR_NONE 0 --#define MMC_ERR_TIMEOUT 1 --#define MMC_ERR_BADCRC 2 --#define MMC_ERR_FIFO 3 --#define MMC_ERR_FAILED 4 --#define MMC_ERR_INVALID 5 -+/* -+ * Standard errno values are used for errors, but some have specific -+ * meaning in the MMC layer: -+ * -+ * ETIMEDOUT Card took too long to respond -+ * EILSEQ Basic format problem with the received or sent data -+ * (e.g. CRC check failed, incorrect opcode in response -+ * or bad end bit) -+ * EINVAL Request cannot be performed because of restrictions -+ * in hardware and/or the driver -+ * ENOMEDIUM Host can determine that the slot is empty and is -+ * actively failing requests -+ */ - - struct mmc_data *data; /* data segment associated with cmd */ - struct mmc_request *mrq; /* associated request */ -@@ -76,7 +107,6 @@ struct mmc_data { - #define MMC_DATA_WRITE (1 << 8) - #define MMC_DATA_READ (1 << 9) - #define MMC_DATA_STREAM (1 << 10) --#define MMC_DATA_MULTI (1 << 11) - - unsigned int bytes_xfered; - -@@ -104,9 +134,20 @@ extern int mmc_wait_for_cmd(struct mmc_h - extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, - struct mmc_command *, int); - --extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int); -+extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); - --extern void mmc_claim_host(struct mmc_host *host); -+extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); - extern void mmc_release_host(struct mmc_host *host); - -+/** -+ * mmc_claim_host - exclusively claim a host -+ * @host: mmc host to claim -+ * -+ * Claim a host for a set of operations. -+ */ -+static inline void mmc_claim_host(struct mmc_host *host) -+{ -+ __mmc_claim_host(host, NULL); -+} -+ - #endif ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -10,6 +10,8 @@ - #ifndef LINUX_MMC_HOST_H - #define LINUX_MMC_HOST_H - -+#include <linux/leds.h> -+ - #include <linux/mmc/core.h> - - struct mmc_ios { -@@ -51,6 +53,7 @@ struct mmc_host_ops { - void (*request)(struct mmc_host *host, struct mmc_request *req); - void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); - int (*get_ro)(struct mmc_host *host); -+ void (*enable_sdio_irq)(struct mmc_host *host, int enable); - }; - - struct mmc_card; -@@ -87,9 +90,10 @@ struct mmc_host { - - #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ - #define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ --#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */ --#define MMC_CAP_MMC_HIGHSPEED (1 << 3) /* Can do MMC high-speed timing */ --#define MMC_CAP_SD_HIGHSPEED (1 << 4) /* Can do SD high-speed timing */ -+#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */ -+#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */ -+#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */ -+#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */ - - /* host specific block data */ - unsigned int max_seg_size; /* see blk_queue_max_segment_size */ -@@ -106,23 +110,30 @@ struct mmc_host { - struct mmc_ios ios; /* current io bus settings */ - u32 ocr; /* the current OCR setting */ - -- unsigned int mode; /* current card mode of host */ --#define MMC_MODE_MMC 0 --#define MMC_MODE_SD 1 -+ /* group bitfields together to minimize padding */ -+ unsigned int use_spi_crc:1; -+ unsigned int claimed:1; /* host exclusively claimed */ -+ unsigned int bus_dead:1; /* bus has been released */ -+#ifdef CONFIG_MMC_DEBUG -+ unsigned int removed:1; /* host is being removed */ -+#endif - - struct mmc_card *card; /* device attached to this host */ - - wait_queue_head_t wq; -- unsigned int claimed:1; /* host exclusively claimed */ - - struct delayed_work detect; --#ifdef CONFIG_MMC_DEBUG -- unsigned int removed:1; /* host is being removed */ --#endif - - const struct mmc_bus_ops *bus_ops; /* current bus driver */ - unsigned int bus_refs; /* reference counter */ -- unsigned int bus_dead:1; /* bus has been released */ -+ -+ unsigned int sdio_irqs; -+ struct task_struct *sdio_irq_thread; -+ atomic_t sdio_irq_thread_abort; -+ -+#ifdef CONFIG_LEDS_TRIGGERS -+ struct led_trigger *led; /* activity led */ -+#endif - - unsigned long private[0] ____cacheline_aligned; - }; -@@ -137,6 +148,8 @@ static inline void *mmc_priv(struct mmc_ - return (void *)host->private; - } - -+#define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) -+ - #define mmc_dev(x) ((x)->parent) - #define mmc_classdev(x) (&(x)->class_dev) - #define mmc_hostname(x) ((x)->class_dev.bus_id) -@@ -147,5 +160,11 @@ extern int mmc_resume_host(struct mmc_ho - extern void mmc_detect_change(struct mmc_host *, unsigned long delay); - extern void mmc_request_done(struct mmc_host *, struct mmc_request *); - -+static inline void mmc_signal_sdio_irq(struct mmc_host *host) -+{ -+ host->ops->enable_sdio_irq(host, 0); -+ wake_up_process(host->sdio_irq_thread); -+} -+ - #endif - ---- a/include/linux/mmc/mmc.h -+++ b/include/linux/mmc/mmc.h -@@ -27,7 +27,7 @@ - - /* Standard MMC commands (4.1) type argument response */ - /* class 1 */ --#define MMC_GO_IDLE_STATE 0 /* bc */ -+#define MMC_GO_IDLE_STATE 0 /* bc */ - #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ - #define MMC_ALL_SEND_CID 2 /* bcr R2 */ - #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ -@@ -39,8 +39,10 @@ - #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ - #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ - #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ --#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ -+#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ - #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ -+#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */ -+#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */ - - /* class 2 */ - #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ -@@ -90,15 +92,15 @@ - */ - - /* -- MMC status in R1 -+ MMC status in R1, for native mode (SPI bits are different) - Type -- e : error bit -+ e : error bit - s : status bit - r : detected and set for the actual command response - x : detected and set during command execution. the host must poll - the card by sending status command in order to read these bits. - Clear condition -- a : according to the card state -+ a : according to the card state - b : always related to the previous command. Reception of - a valid command will clear it (with a delay of one command) - c : clear by read -@@ -124,10 +126,33 @@ - #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ - #define R1_ERASE_RESET (1 << 13) /* sr, c */ - #define R1_STATUS(x) (x & 0xFFFFE000) --#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ -+#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ - #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ - #define R1_APP_CMD (1 << 5) /* sr, c */ - -+/* -+ * MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS -+ * R1 is the low order byte; R2 is the next highest byte, when present. -+ */ -+#define R1_SPI_IDLE (1 << 0) -+#define R1_SPI_ERASE_RESET (1 << 1) -+#define R1_SPI_ILLEGAL_COMMAND (1 << 2) -+#define R1_SPI_COM_CRC (1 << 3) -+#define R1_SPI_ERASE_SEQ (1 << 4) -+#define R1_SPI_ADDRESS (1 << 5) -+#define R1_SPI_PARAMETER (1 << 6) -+/* R1 bit 7 is always zero */ -+#define R2_SPI_CARD_LOCKED (1 << 8) -+#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */ -+#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP -+#define R2_SPI_ERROR (1 << 10) -+#define R2_SPI_CC_ERROR (1 << 11) -+#define R2_SPI_CARD_ECC_ERROR (1 << 12) -+#define R2_SPI_WP_VIOLATION (1 << 13) -+#define R2_SPI_ERASE_PARAM (1 << 14) -+#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */ -+#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE -+ - /* These are unpacked versions of the actual responses */ - - struct _mmc_csd { -@@ -182,6 +207,7 @@ struct _mmc_csd { - */ - #define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ - /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ -+ /* (and for SPI, CMD58,59) */ - #define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ - /* (CMD11) */ - #define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ -@@ -227,6 +253,7 @@ struct _mmc_csd { - #define EXT_CSD_BUS_WIDTH 183 /* R/W */ - #define EXT_CSD_HS_TIMING 185 /* R/W */ - #define EXT_CSD_CARD_TYPE 196 /* RO */ -+#define EXT_CSD_REV 192 /* RO */ - #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ - - /* ---- /dev/null -+++ b/include/linux/mmc/sdio.h -@@ -0,0 +1,159 @@ -+/* -+ * include/linux/mmc/sdio.h -+ * -+ * Copyright 2006-2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#ifndef MMC_SDIO_H -+#define MMC_SDIO_H -+ -+/* SDIO commands type argument response */ -+#define SD_IO_SEND_OP_COND 5 /* bcr [23:0] OCR R4 */ -+#define SD_IO_RW_DIRECT 52 /* ac [31:0] See below R5 */ -+#define SD_IO_RW_EXTENDED 53 /* adtc [31:0] See below R5 */ -+ -+/* -+ * SD_IO_RW_DIRECT argument format: -+ * -+ * [31] R/W flag -+ * [30:28] Function number -+ * [27] RAW flag -+ * [25:9] Register address -+ * [7:0] Data -+ */ -+ -+/* -+ * SD_IO_RW_EXTENDED argument format: -+ * -+ * [31] R/W flag -+ * [30:28] Function number -+ * [27] Block mode -+ * [26] Increment address -+ * [25:9] Register address -+ * [8:0] Byte/block count -+ */ -+ -+/* -+ SDIO status in R5 -+ Type -+ e : error bit -+ s : status bit -+ r : detected and set for the actual command response -+ x : detected and set during command execution. the host must poll -+ the card by sending status command in order to read these bits. -+ Clear condition -+ a : according to the card state -+ b : always related to the previous command. Reception of -+ a valid command will clear it (with a delay of one command) -+ c : clear by read -+ */ -+ -+#define R5_COM_CRC_ERROR (1 << 15) /* er, b */ -+#define R5_ILLEGAL_COMMAND (1 << 14) /* er, b */ -+#define R5_ERROR (1 << 11) /* erx, c */ -+#define R5_FUNCTION_NUMBER (1 << 9) /* er, c */ -+#define R5_OUT_OF_RANGE (1 << 8) /* er, c */ -+#define R5_STATUS(x) (x & 0xCB00) -+#define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) /* s, b */ -+ -+/* -+ * Card Common Control Registers (CCCR) -+ */ -+ -+#define SDIO_CCCR_CCCR 0x00 -+ -+#define SDIO_CCCR_REV_1_00 0 /* CCCR/FBR Version 1.00 */ -+#define SDIO_CCCR_REV_1_10 1 /* CCCR/FBR Version 1.10 */ -+#define SDIO_CCCR_REV_1_20 2 /* CCCR/FBR Version 1.20 */ -+ -+#define SDIO_SDIO_REV_1_00 0 /* SDIO Spec Version 1.00 */ -+#define SDIO_SDIO_REV_1_10 1 /* SDIO Spec Version 1.10 */ -+#define SDIO_SDIO_REV_1_20 2 /* SDIO Spec Version 1.20 */ -+#define SDIO_SDIO_REV_2_00 3 /* SDIO Spec Version 2.00 */ -+ -+#define SDIO_CCCR_SD 0x01 -+ -+#define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */ -+#define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */ -+#define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */ -+ -+#define SDIO_CCCR_IOEx 0x02 -+#define SDIO_CCCR_IORx 0x03 -+ -+#define SDIO_CCCR_IENx 0x04 /* Function/Master Interrupt Enable */ -+#define SDIO_CCCR_INTx 0x05 /* Function Interrupt Pending */ -+ -+#define SDIO_CCCR_ABORT 0x06 /* function abort/card reset */ -+ -+#define SDIO_CCCR_IF 0x07 /* bus interface controls */ -+ -+#define SDIO_BUS_WIDTH_1BIT 0x00 -+#define SDIO_BUS_WIDTH_4BIT 0x02 -+ -+#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */ -+ -+#define SDIO_CCCR_CAPS 0x08 -+ -+#define SDIO_CCCR_CAP_SDC 0x01 /* can do CMD52 while data transfer */ -+#define SDIO_CCCR_CAP_SMB 0x02 /* can do multi-block xfers (CMD53) */ -+#define SDIO_CCCR_CAP_SRW 0x04 /* supports read-wait protocol */ -+#define SDIO_CCCR_CAP_SBS 0x08 /* supports suspend/resume */ -+#define SDIO_CCCR_CAP_S4MI 0x10 /* interrupt during 4-bit CMD53 */ -+#define SDIO_CCCR_CAP_E4MI 0x20 /* enable ints during 4-bit CMD53 */ -+#define SDIO_CCCR_CAP_LSC 0x40 /* low speed card */ -+#define SDIO_CCCR_CAP_4BLS 0x80 /* 4 bit low speed card */ -+ -+#define SDIO_CCCR_CIS 0x09 /* common CIS pointer (3 bytes) */ -+ -+/* Following 4 regs are valid only if SBS is set */ -+#define SDIO_CCCR_SUSPEND 0x0c -+#define SDIO_CCCR_SELx 0x0d -+#define SDIO_CCCR_EXECx 0x0e -+#define SDIO_CCCR_READYx 0x0f -+ -+#define SDIO_CCCR_BLKSIZE 0x10 -+ -+#define SDIO_CCCR_POWER 0x12 -+ -+#define SDIO_POWER_SMPC 0x01 /* Supports Master Power Control */ -+#define SDIO_POWER_EMPC 0x02 /* Enable Master Power Control */ -+ -+#define SDIO_CCCR_SPEED 0x13 -+ -+#define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */ -+#define SDIO_SPEED_EHS 0x02 /* Enable High-Speed mode */ -+ -+/* -+ * Function Basic Registers (FBR) -+ */ -+ -+#define SDIO_FBR_BASE(f) ((f) * 0x100) /* base of function f's FBRs */ -+ -+#define SDIO_FBR_STD_IF 0x00 -+ -+#define SDIO_FBR_SUPPORTS_CSA 0x40 /* supports Code Storage Area */ -+#define SDIO_FBR_ENABLE_CSA 0x80 /* enable Code Storage Area */ -+ -+#define SDIO_FBR_STD_IF_EXT 0x01 -+ -+#define SDIO_FBR_POWER 0x02 -+ -+#define SDIO_FBR_POWER_SPS 0x01 /* Supports Power Selection */ -+#define SDIO_FBR_POWER_EPS 0x02 /* Enable (low) Power Selection */ -+ -+#define SDIO_FBR_CIS 0x09 /* CIS pointer (3 bytes) */ -+ -+ -+#define SDIO_FBR_CSA 0x0C /* CSA pointer (3 bytes) */ -+ -+#define SDIO_FBR_CSA_DATA 0x0F -+ -+#define SDIO_FBR_BLKSIZE 0x10 /* block size (2 bytes) */ -+ -+#endif -+ ---- /dev/null -+++ b/include/linux/mmc/sdio_func.h -@@ -0,0 +1,153 @@ -+/* -+ * include/linux/mmc/sdio_func.h -+ * -+ * Copyright 2007 Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+#ifndef MMC_SDIO_FUNC_H -+#define MMC_SDIO_FUNC_H -+ -+#include <linux/device.h> -+#include <linux/mod_devicetable.h> -+ -+struct mmc_card; -+struct sdio_func; -+ -+typedef void (sdio_irq_handler_t)(struct sdio_func *); -+ -+/* -+ * SDIO function CIS tuple (unknown to the core) -+ */ -+struct sdio_func_tuple { -+ struct sdio_func_tuple *next; -+ unsigned char code; -+ unsigned char size; -+ unsigned char data[0]; -+}; -+ -+/* -+ * SDIO function devices -+ */ -+struct sdio_func { -+ struct mmc_card *card; /* the card this device belongs to */ -+ struct device dev; /* the device */ -+ sdio_irq_handler_t *irq_handler; /* IRQ callback */ -+ unsigned int num; /* function number */ -+ -+ unsigned char class; /* standard interface class */ -+ unsigned short vendor; /* vendor id */ -+ unsigned short device; /* device id */ -+ -+ unsigned max_blksize; /* maximum block size */ -+ unsigned cur_blksize; /* current block size */ -+ -+ unsigned int state; /* function state */ -+#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ -+ -+ u8 tmpbuf[4]; /* DMA:able scratch buffer */ -+ -+ unsigned num_info; /* number of info strings */ -+ const char **info; /* info strings */ -+ -+ struct sdio_func_tuple *tuples; -+}; -+ -+#define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT) -+ -+#define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT) -+ -+#define sdio_func_id(f) ((f)->dev.bus_id) -+ -+#define sdio_get_drvdata(f) dev_get_drvdata(&(f)->dev) -+#define sdio_set_drvdata(f,d) dev_set_drvdata(&(f)->dev, d) -+ -+/* -+ * SDIO function device driver -+ */ -+struct sdio_driver { -+ char *name; -+ const struct sdio_device_id *id_table; -+ -+ int (*probe)(struct sdio_func *, const struct sdio_device_id *); -+ void (*remove)(struct sdio_func *); -+ -+ struct device_driver drv; -+}; -+ -+/** -+ * SDIO_DEVICE - macro used to describe a specific SDIO device -+ * @vend: the 16 bit manufacturer code -+ * @dev: the 16 bit function id -+ * -+ * This macro is used to create a struct sdio_device_id that matches a -+ * specific device. The class field will be set to SDIO_ANY_ID. -+ */ -+#define SDIO_DEVICE(vend,dev) \ -+ .class = SDIO_ANY_ID, \ -+ .vendor = (vend), .device = (dev) -+ -+/** -+ * SDIO_DEVICE_CLASS - macro used to describe a specific SDIO device class -+ * @dev_class: the 8 bit standard interface code -+ * -+ * This macro is used to create a struct sdio_device_id that matches a -+ * specific standard SDIO function type. The vendor and device fields will -+ * be set to SDIO_ANY_ID. -+ */ -+#define SDIO_DEVICE_CLASS(dev_class) \ -+ .class = (dev_class), \ -+ .vendor = SDIO_ANY_ID, .device = SDIO_ANY_ID -+ -+extern int sdio_register_driver(struct sdio_driver *); -+extern void sdio_unregister_driver(struct sdio_driver *); -+ -+/* -+ * SDIO I/O operations -+ */ -+extern void sdio_claim_host(struct sdio_func *func); -+extern void sdio_release_host(struct sdio_func *func); -+ -+extern int sdio_enable_func(struct sdio_func *func); -+extern int sdio_disable_func(struct sdio_func *func); -+ -+extern int sdio_set_block_size(struct sdio_func *func, unsigned blksz); -+ -+extern int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler); -+extern int sdio_release_irq(struct sdio_func *func); -+ -+extern unsigned char sdio_readb(struct sdio_func *func, -+ unsigned int addr, int *err_ret); -+extern unsigned short sdio_readw(struct sdio_func *func, -+ unsigned int addr, int *err_ret); -+extern unsigned long sdio_readl(struct sdio_func *func, -+ unsigned int addr, int *err_ret); -+ -+extern int sdio_memcpy_fromio(struct sdio_func *func, void *dst, -+ unsigned int addr, int count); -+extern int sdio_readsb(struct sdio_func *func, void *dst, -+ unsigned int addr, int count); -+ -+extern void sdio_writeb(struct sdio_func *func, unsigned char b, -+ unsigned int addr, int *err_ret); -+extern void sdio_writew(struct sdio_func *func, unsigned short b, -+ unsigned int addr, int *err_ret); -+extern void sdio_writel(struct sdio_func *func, unsigned long b, -+ unsigned int addr, int *err_ret); -+ -+extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, -+ void *src, int count); -+extern int sdio_writesb(struct sdio_func *func, unsigned int addr, -+ void *src, int count); -+ -+extern unsigned char sdio_f0_readb(struct sdio_func *func, -+ unsigned int addr, int *err_ret); -+extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b, -+ unsigned int addr, int *err_ret); -+ -+#endif -+ ---- /dev/null -+++ b/include/linux/mmc/sdio_ids.h -@@ -0,0 +1,29 @@ -+/* -+ * SDIO Classes, Interface Types, Manufacturer IDs, etc. -+ */ -+ -+#ifndef MMC_SDIO_IDS_H -+#define MMC_SDIO_IDS_H -+ -+/* -+ * Standard SDIO Function Interfaces -+ */ -+ -+#define SDIO_CLASS_NONE 0x00 /* Not a SDIO standard interface */ -+#define SDIO_CLASS_UART 0x01 /* standard UART interface */ -+#define SDIO_CLASS_BT_A 0x02 /* Type-A BlueTooth std interface */ -+#define SDIO_CLASS_BT_B 0x03 /* Type-B BlueTooth std interface */ -+#define SDIO_CLASS_GPS 0x04 /* GPS standard interface */ -+#define SDIO_CLASS_CAMERA 0x05 /* Camera standard interface */ -+#define SDIO_CLASS_PHS 0x06 /* PHS standard interface */ -+#define SDIO_CLASS_WLAN 0x07 /* WLAN interface */ -+#define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */ -+ -+/* -+ * Vendors and devices. Sort key: vendor first, device next. -+ */ -+ -+#define SDIO_VENDOR_ID_MARVELL 0x02df -+#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 -+ -+#endif ---- a/include/linux/mod_devicetable.h -+++ b/include/linux/mod_devicetable.h -@@ -22,6 +22,18 @@ struct pci_device_id { - }; - - -+/* SDIO */ -+ -+#define SDIO_ANY_ID (~0) -+ -+struct sdio_device_id { -+ __u8 class; /* Standard interface or SDIO_ANY_ID */ -+ __u16 vendor; /* Vendor or SDIO_ANY_ID */ -+ __u16 device; /* Device ID or SDIO_ANY_ID */ -+ kernel_ulong_t driver_data; /* Data private to the driver */ -+}; -+ -+ - #define IEEE1394_MATCH_VENDOR_ID 0x0001 - #define IEEE1394_MATCH_MODEL_ID 0x0002 - #define IEEE1394_MATCH_SPECIFIER_ID 0x0004 ---- a/drivers/mmc/card/Kconfig -+++ b/drivers/mmc/card/Kconfig -@@ -32,3 +32,10 @@ config MMC_BLOCK_BOUNCE - - If unsure, say Y here. - -+config SDIO_UART -+ tristate "SDIO UART/GPS class support" -+ depends on MMC -+ help -+ SDIO function driver for SDIO cards that implements the UART -+ class, as well as the GPS class which appears like a UART. -+ ---- a/drivers/mmc/card/Makefile -+++ b/drivers/mmc/card/Makefile -@@ -9,3 +9,5 @@ endif - obj-$(CONFIG_MMC_BLOCK) += mmc_block.o - mmc_block-objs := block.o queue.o - -+obj-$(CONFIG_SDIO_UART) += sdio_uart.o -+ ---- a/drivers/mmc/card/block.c -+++ b/drivers/mmc/card/block.c -@@ -44,6 +44,9 @@ - * max 8 partitions per card - */ - #define MMC_SHIFT 3 -+#define MMC_NUM_MINORS (256 >> MMC_SHIFT) -+ -+static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; - - /* - * There is one mmc_blk_data per slot. -@@ -80,6 +83,9 @@ static void mmc_blk_put(struct mmc_blk_d - mutex_lock(&open_lock); - md->usage--; - if (md->usage == 0) { -+ int devidx = md->disk->first_minor >> MMC_SHIFT; -+ __clear_bit(devidx, dev_use); -+ - put_disk(md->disk); - kfree(md); - } -@@ -151,17 +157,19 @@ static u32 mmc_sd_num_wr_blocks(struct m - - cmd.opcode = MMC_APP_CMD; - cmd.arg = card->rca << 16; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, 0); -- if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) -+ if (err) -+ return (u32)-1; -+ if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) - return (u32)-1; - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_SEND_NUM_WR_BLKS; - cmd.arg = 0; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - - memset(&data, 0, sizeof(struct mmc_data)); - -@@ -192,7 +200,7 @@ static u32 mmc_sd_num_wr_blocks(struct m - - mmc_wait_for_req(card->host, &mrq); - -- if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) -+ if (cmd.error || data.error) - return (u32)-1; - - blocks = ntohl(blocks); -@@ -220,17 +228,15 @@ static int mmc_blk_issue_rq(struct mmc_q - brq.cmd.arg = req->sector; - if (!mmc_card_blockaddr(card)) - brq.cmd.arg <<= 9; -- brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; -+ brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - brq.data.blksz = 1 << md->block_bits; - brq.stop.opcode = MMC_STOP_TRANSMISSION; - brq.stop.arg = 0; -- brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; -+ brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); - if (brq.data.blocks > card->host->max_blk_count) - brq.data.blocks = card->host->max_blk_count; - -- mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); -- - /* - * If the host doesn't support multiple block writes, force - * block writes to single block. SD cards are excepted from -@@ -243,8 +249,12 @@ static int mmc_blk_issue_rq(struct mmc_q - brq.data.blocks = 1; - - if (brq.data.blocks > 1) { -- brq.data.flags |= MMC_DATA_MULTI; -- brq.mrq.stop = &brq.stop; -+ /* SPI multiblock writes terminate using a special -+ * token, not a STOP_TRANSMISSION request. -+ */ -+ if (!mmc_host_is_spi(card->host) -+ || rq_data_dir(req) == READ) -+ brq.mrq.stop = &brq.stop; - readcmd = MMC_READ_MULTIPLE_BLOCK; - writecmd = MMC_WRITE_MULTIPLE_BLOCK; - } else { -@@ -261,6 +271,8 @@ static int mmc_blk_issue_rq(struct mmc_q - brq.data.flags |= MMC_DATA_WRITE; - } - -+ mmc_set_data_timeout(&brq.data, card); -+ - brq.data.sg = mq->sg; - brq.data.sg_len = mmc_queue_map_sg(mq); - -@@ -302,7 +314,7 @@ static int mmc_blk_issue_rq(struct mmc_q - goto cmd_err; - } - -- if (rq_data_dir(req) != READ) { -+ if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { - do { - int err; - -@@ -315,7 +327,13 @@ static int mmc_blk_issue_rq(struct mmc_q - req->rq_disk->disk_name, err); - goto cmd_err; - } -- } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); -+ /* -+ * Some cards mishandle the status bits, -+ * so make sure to check both the busy -+ * indication and the card state. -+ */ -+ } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || -+ (R1_CURRENT_STATE(cmd.resp[0]) == 7)); - - #if 0 - if (cmd.resp[0] & ~0x00000900) -@@ -394,9 +412,6 @@ static int mmc_blk_issue_rq(struct mmc_q - return 0; - } - --#define MMC_NUM_MINORS (256 >> MMC_SHIFT) -- --static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; - - static inline int mmc_blk_readonly(struct mmc_card *card) - { -@@ -510,7 +525,7 @@ mmc_blk_set_blksize(struct mmc_blk_data - mmc_claim_host(card->host); - cmd.opcode = MMC_SET_BLOCKLEN; - cmd.arg = 1 << md->block_bits; -- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; -+ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, 5); - mmc_release_host(card->host); - -@@ -562,17 +577,12 @@ static void mmc_blk_remove(struct mmc_ca - struct mmc_blk_data *md = mmc_get_drvdata(card); - - if (md) { -- int devidx; -- - /* Stop new requests from getting into the queue */ - del_gendisk(md->disk); - - /* Then flush out any already in there */ - mmc_cleanup_queue(&md->queue); - -- devidx = md->disk->first_minor >> MMC_SHIFT; -- __clear_bit(devidx, dev_use); -- - mmc_blk_put(md); - } - mmc_set_drvdata(card, NULL); ---- a/drivers/mmc/card/queue.c -+++ b/drivers/mmc/card/queue.c -@@ -13,6 +13,7 @@ - #include <linux/blkdev.h> - #include <linux/freezer.h> - #include <linux/kthread.h> -+#include <linux/scatterlist.h> - - #include <linux/mmc/card.h> - #include <linux/mmc/host.h> -@@ -22,6 +23,12 @@ - - #define MMC_QUEUE_SUSPENDED (1 << 0) - -+#define sg_init_table(sg, n) do { \ -+ memset(sg, 0, sizeof(*(sg)) * (n)); \ -+} while (0) -+ -+#define sg_virt(sg) (page_address((sg)->page) + (sg)->offset) -+ - /* - * Prepare a MMC request. This just filters out odd stuff. - */ -@@ -159,6 +166,7 @@ int mmc_init_queue(struct mmc_queue *mq, - ret = -ENOMEM; - goto cleanup_queue; - } -+ sg_init_table(mq->sg, 1); - - mq->bounce_sg = kmalloc(sizeof(struct scatterlist) * - bouncesz / 512, GFP_KERNEL); -@@ -166,6 +174,7 @@ int mmc_init_queue(struct mmc_queue *mq, - ret = -ENOMEM; - goto cleanup_queue; - } -+ sg_init_table(mq->bounce_sg, bouncesz / 512); - } - } - #endif -@@ -183,6 +192,7 @@ int mmc_init_queue(struct mmc_queue *mq, - ret = -ENOMEM; - goto cleanup_queue; - } -+ sg_init_table(mq->sg, host->max_phys_segs); - } - - init_MUTEX(&mq->thread_sem); -@@ -302,12 +312,12 @@ static void copy_sg(struct scatterlist * - BUG_ON(dst_len == 0); - - if (dst_size == 0) { -- dst_buf = page_address(dst->page) + dst->offset; -+ dst_buf = sg_virt(dst); - dst_size = dst->length; - } - - if (src_size == 0) { -- src_buf = page_address(src->page) + src->offset; -+ src_buf = sg_virt(src); - src_size = src->length; - } - -@@ -353,9 +363,7 @@ unsigned int mmc_queue_map_sg(struct mmc - return 1; - } - -- mq->sg[0].page = virt_to_page(mq->bounce_buf); -- mq->sg[0].offset = offset_in_page(mq->bounce_buf); -- mq->sg[0].length = 0; -+ sg_init_one(mq->sg, mq->bounce_buf, 0); - - while (sg_len) { - mq->sg[0].length += mq->bounce_sg[sg_len - 1].length; ---- /dev/null -+++ b/drivers/mmc/card/sdio_uart.c -@@ -0,0 +1,1158 @@ -+/* -+ * linux/drivers/mmc/card/sdio_uart.c - SDIO UART/GPS driver -+ * -+ * Based on drivers/serial/8250.c and drivers/serial/serial_core.c -+ * by Russell King. -+ * -+ * Author: Nicolas Pitre -+ * Created: June 15, 2007 -+ * Copyright: MontaVista Software, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ */ -+ -+/* -+ * Note: Although this driver assumes a 16550A-like UART implementation, -+ * it is not possible to leverage the common 8250/16550 driver, nor the -+ * core UART infrastructure, as they assumes direct access to the hardware -+ * registers, often under a spinlock. This is not possible in the SDIO -+ * context as SDIO access functions must be able to sleep. -+ * -+ * Because we need to lock the SDIO host to ensure an exclusive access to -+ * the card, we simply rely on that lock to also prevent and serialize -+ * concurrent access to the same port. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/mutex.h> -+#include <linux/serial_reg.h> -+#include <linux/circ_buf.h> -+#include <linux/gfp.h> -+#include <linux/tty.h> -+#include <linux/tty_flip.h> -+ -+#include <linux/mmc/core.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/sdio_func.h> -+#include <linux/mmc/sdio_ids.h> -+ -+ -+#define UART_NR 8 /* Number of UARTs this driver can handle */ -+ -+ -+#define UART_XMIT_SIZE PAGE_SIZE -+#define WAKEUP_CHARS 256 -+ -+#define circ_empty(circ) ((circ)->head == (circ)->tail) -+#define circ_clear(circ) ((circ)->head = (circ)->tail = 0) -+ -+#define circ_chars_pending(circ) \ -+ (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) -+ -+#define circ_chars_free(circ) \ -+ (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) -+ -+ -+struct uart_icount { -+ __u32 cts; -+ __u32 dsr; -+ __u32 rng; -+ __u32 dcd; -+ __u32 rx; -+ __u32 tx; -+ __u32 frame; -+ __u32 overrun; -+ __u32 parity; -+ __u32 brk; -+}; -+ -+struct sdio_uart_port { -+ struct kref kref; -+ struct tty_struct *tty; -+ unsigned int index; -+ unsigned int opened; -+ struct mutex open_lock; -+ struct sdio_func *func; -+ struct mutex func_lock; -+ struct task_struct *in_sdio_uart_irq; -+ unsigned int regs_offset; -+ struct circ_buf xmit; -+ spinlock_t write_lock; -+ struct uart_icount icount; -+ unsigned int uartclk; -+ unsigned int mctrl; -+ unsigned int read_status_mask; -+ unsigned int ignore_status_mask; -+ unsigned char x_char; -+ unsigned char ier; -+ unsigned char lcr; -+}; -+ -+static struct sdio_uart_port *sdio_uart_table[UART_NR]; -+static DEFINE_SPINLOCK(sdio_uart_table_lock); -+ -+static int sdio_uart_add_port(struct sdio_uart_port *port) -+{ -+ int index, ret = -EBUSY; -+ -+ kref_init(&port->kref); -+ mutex_init(&port->open_lock); -+ mutex_init(&port->func_lock); -+ spin_lock_init(&port->write_lock); -+ -+ spin_lock(&sdio_uart_table_lock); -+ for (index = 0; index < UART_NR; index++) { -+ if (!sdio_uart_table[index]) { -+ port->index = index; -+ sdio_uart_table[index] = port; -+ ret = 0; -+ break; -+ } -+ } -+ spin_unlock(&sdio_uart_table_lock); -+ -+ return ret; -+} -+ -+static struct sdio_uart_port *sdio_uart_port_get(unsigned index) -+{ -+ struct sdio_uart_port *port; -+ -+ if (index >= UART_NR) -+ return NULL; -+ -+ spin_lock(&sdio_uart_table_lock); -+ port = sdio_uart_table[index]; -+ if (port) -+ kref_get(&port->kref); -+ spin_unlock(&sdio_uart_table_lock); -+ -+ return port; -+} -+ -+static void sdio_uart_port_destroy(struct kref *kref) -+{ -+ struct sdio_uart_port *port = -+ container_of(kref, struct sdio_uart_port, kref); -+ kfree(port); -+} -+ -+static void sdio_uart_port_put(struct sdio_uart_port *port) -+{ -+ kref_put(&port->kref, sdio_uart_port_destroy); -+} -+ -+static void sdio_uart_port_remove(struct sdio_uart_port *port) -+{ -+ struct sdio_func *func; -+ -+ BUG_ON(sdio_uart_table[port->index] != port); -+ -+ spin_lock(&sdio_uart_table_lock); -+ sdio_uart_table[port->index] = NULL; -+ spin_unlock(&sdio_uart_table_lock); -+ -+ /* -+ * We're killing a port that potentially still is in use by -+ * the tty layer. Be careful to prevent any further access -+ * to the SDIO function and arrange for the tty layer to -+ * give up on that port ASAP. -+ * Beware: the lock ordering is critical. -+ */ -+ mutex_lock(&port->open_lock); -+ mutex_lock(&port->func_lock); -+ func = port->func; -+ sdio_claim_host(func); -+ port->func = NULL; -+ mutex_unlock(&port->func_lock); -+ if (port->opened) -+ tty_hangup(port->tty); -+ mutex_unlock(&port->open_lock); -+ sdio_release_irq(func); -+ sdio_disable_func(func); -+ sdio_release_host(func); -+ -+ sdio_uart_port_put(port); -+} -+ -+static int sdio_uart_claim_func(struct sdio_uart_port *port) -+{ -+ mutex_lock(&port->func_lock); -+ if (unlikely(!port->func)) { -+ mutex_unlock(&port->func_lock); -+ return -ENODEV; -+ } -+ if (likely(port->in_sdio_uart_irq != current)) -+ sdio_claim_host(port->func); -+ mutex_unlock(&port->func_lock); -+ return 0; -+} -+ -+static inline void sdio_uart_release_func(struct sdio_uart_port *port) -+{ -+ if (likely(port->in_sdio_uart_irq != current)) -+ sdio_release_host(port->func); -+} -+ -+static inline unsigned int sdio_in(struct sdio_uart_port *port, int offset) -+{ -+ unsigned char c; -+ c = sdio_readb(port->func, port->regs_offset + offset, NULL); -+ return c; -+} -+ -+static inline void sdio_out(struct sdio_uart_port *port, int offset, int value) -+{ -+ sdio_writeb(port->func, value, port->regs_offset + offset, NULL); -+} -+ -+static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port) -+{ -+ unsigned char status; -+ unsigned int ret; -+ -+ status = sdio_in(port, UART_MSR); -+ -+ ret = 0; -+ if (status & UART_MSR_DCD) -+ ret |= TIOCM_CAR; -+ if (status & UART_MSR_RI) -+ ret |= TIOCM_RNG; -+ if (status & UART_MSR_DSR) -+ ret |= TIOCM_DSR; -+ if (status & UART_MSR_CTS) -+ ret |= TIOCM_CTS; -+ return ret; -+} -+ -+static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl) -+{ -+ unsigned char mcr = 0; -+ -+ if (mctrl & TIOCM_RTS) -+ mcr |= UART_MCR_RTS; -+ if (mctrl & TIOCM_DTR) -+ mcr |= UART_MCR_DTR; -+ if (mctrl & TIOCM_OUT1) -+ mcr |= UART_MCR_OUT1; -+ if (mctrl & TIOCM_OUT2) -+ mcr |= UART_MCR_OUT2; -+ if (mctrl & TIOCM_LOOP) -+ mcr |= UART_MCR_LOOP; -+ -+ sdio_out(port, UART_MCR, mcr); -+} -+ -+static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port, -+ unsigned int set, unsigned int clear) -+{ -+ unsigned int old; -+ -+ old = port->mctrl; -+ port->mctrl = (old & ~clear) | set; -+ if (old != port->mctrl) -+ sdio_uart_write_mctrl(port, port->mctrl); -+} -+ -+#define sdio_uart_set_mctrl(port, x) sdio_uart_update_mctrl(port, x, 0) -+#define sdio_uart_clear_mctrl(port, x) sdio_uart_update_mctrl(port, 0, x) -+ -+static void sdio_uart_change_speed(struct sdio_uart_port *port, -+ struct ktermios *termios, -+ struct ktermios *old) -+{ -+ unsigned char cval, fcr = 0; -+ unsigned int baud, quot; -+ -+ switch (termios->c_cflag & CSIZE) { -+ case CS5: -+ cval = UART_LCR_WLEN5; -+ break; -+ case CS6: -+ cval = UART_LCR_WLEN6; -+ break; -+ case CS7: -+ cval = UART_LCR_WLEN7; -+ break; -+ default: -+ case CS8: -+ cval = UART_LCR_WLEN8; -+ break; -+ } -+ -+ if (termios->c_cflag & CSTOPB) -+ cval |= UART_LCR_STOP; -+ if (termios->c_cflag & PARENB) -+ cval |= UART_LCR_PARITY; -+ if (!(termios->c_cflag & PARODD)) -+ cval |= UART_LCR_EPAR; -+ -+ for (;;) { -+ baud = tty_termios_baud_rate(termios); -+ if (baud == 0) -+ baud = 9600; /* Special case: B0 rate. */ -+ if (baud <= port->uartclk) -+ break; -+ /* -+ * Oops, the quotient was zero. Try again with the old -+ * baud rate if possible, otherwise default to 9600. -+ */ -+ termios->c_cflag &= ~CBAUD; -+ if (old) { -+ termios->c_cflag |= old->c_cflag & CBAUD; -+ old = NULL; -+ } else -+ termios->c_cflag |= B9600; -+ } -+ quot = (2 * port->uartclk + baud) / (2 * baud); -+ -+ if (baud < 2400) -+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; -+ else -+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10; -+ -+ port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; -+ if (termios->c_iflag & INPCK) -+ port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; -+ if (termios->c_iflag & (BRKINT | PARMRK)) -+ port->read_status_mask |= UART_LSR_BI; -+ -+ /* -+ * Characters to ignore -+ */ -+ port->ignore_status_mask = 0; -+ if (termios->c_iflag & IGNPAR) -+ port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; -+ if (termios->c_iflag & IGNBRK) { -+ port->ignore_status_mask |= UART_LSR_BI; -+ /* -+ * If we're ignoring parity and break indicators, -+ * ignore overruns too (for real raw support). -+ */ -+ if (termios->c_iflag & IGNPAR) -+ port->ignore_status_mask |= UART_LSR_OE; -+ } -+ -+ /* -+ * ignore all characters if CREAD is not set -+ */ -+ if ((termios->c_cflag & CREAD) == 0) -+ port->ignore_status_mask |= UART_LSR_DR; -+ -+ /* -+ * CTS flow control flag and modem status interrupts -+ */ -+ port->ier &= ~UART_IER_MSI; -+ if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL)) -+ port->ier |= UART_IER_MSI; -+ -+ port->lcr = cval; -+ -+ sdio_out(port, UART_IER, port->ier); -+ sdio_out(port, UART_LCR, cval | UART_LCR_DLAB); -+ sdio_out(port, UART_DLL, quot & 0xff); -+ sdio_out(port, UART_DLM, quot >> 8); -+ sdio_out(port, UART_LCR, cval); -+ sdio_out(port, UART_FCR, fcr); -+ -+ sdio_uart_write_mctrl(port, port->mctrl); -+} -+ -+static void sdio_uart_start_tx(struct sdio_uart_port *port) -+{ -+ if (!(port->ier & UART_IER_THRI)) { -+ port->ier |= UART_IER_THRI; -+ sdio_out(port, UART_IER, port->ier); -+ } -+} -+ -+static void sdio_uart_stop_tx(struct sdio_uart_port *port) -+{ -+ if (port->ier & UART_IER_THRI) { -+ port->ier &= ~UART_IER_THRI; -+ sdio_out(port, UART_IER, port->ier); -+ } -+} -+ -+static void sdio_uart_stop_rx(struct sdio_uart_port *port) -+{ -+ port->ier &= ~UART_IER_RLSI; -+ port->read_status_mask &= ~UART_LSR_DR; -+ sdio_out(port, UART_IER, port->ier); -+} -+ -+static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status) -+{ -+ struct tty_struct *tty = port->tty; -+ unsigned int ch, flag; -+ int max_count = 256; -+ -+ do { -+ ch = sdio_in(port, UART_RX); -+ flag = TTY_NORMAL; -+ port->icount.rx++; -+ -+ if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | -+ UART_LSR_FE | UART_LSR_OE))) { -+ /* -+ * For statistics only -+ */ -+ if (*status & UART_LSR_BI) { -+ *status &= ~(UART_LSR_FE | UART_LSR_PE); -+ port->icount.brk++; -+ } else if (*status & UART_LSR_PE) -+ port->icount.parity++; -+ else if (*status & UART_LSR_FE) -+ port->icount.frame++; -+ if (*status & UART_LSR_OE) -+ port->icount.overrun++; -+ -+ /* -+ * Mask off conditions which should be ignored. -+ */ -+ *status &= port->read_status_mask; -+ if (*status & UART_LSR_BI) { -+ flag = TTY_BREAK; -+ } else if (*status & UART_LSR_PE) -+ flag = TTY_PARITY; -+ else if (*status & UART_LSR_FE) -+ flag = TTY_FRAME; -+ } -+ -+ if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) -+ tty_insert_flip_char(tty, ch, flag); -+ -+ /* -+ * Overrun is special. Since it's reported immediately, -+ * it doesn't affect the current character. -+ */ -+ if (*status & ~port->ignore_status_mask & UART_LSR_OE) -+ tty_insert_flip_char(tty, 0, TTY_OVERRUN); -+ -+ *status = sdio_in(port, UART_LSR); -+ } while ((*status & UART_LSR_DR) && (max_count-- > 0)); -+ tty_flip_buffer_push(tty); -+} -+ -+static void sdio_uart_transmit_chars(struct sdio_uart_port *port) -+{ -+ struct circ_buf *xmit = &port->xmit; -+ int count; -+ -+ if (port->x_char) { -+ sdio_out(port, UART_TX, port->x_char); -+ port->icount.tx++; -+ port->x_char = 0; -+ return; -+ } -+ if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) { -+ sdio_uart_stop_tx(port); -+ return; -+ } -+ -+ count = 16; -+ do { -+ sdio_out(port, UART_TX, xmit->buf[xmit->tail]); -+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -+ port->icount.tx++; -+ if (circ_empty(xmit)) -+ break; -+ } while (--count > 0); -+ -+ if (circ_chars_pending(xmit) < WAKEUP_CHARS) -+ tty_wakeup(port->tty); -+ -+ if (circ_empty(xmit)) -+ sdio_uart_stop_tx(port); -+} -+ -+static void sdio_uart_check_modem_status(struct sdio_uart_port *port) -+{ -+ int status; -+ -+ status = sdio_in(port, UART_MSR); -+ -+ if ((status & UART_MSR_ANY_DELTA) == 0) -+ return; -+ -+ if (status & UART_MSR_TERI) -+ port->icount.rng++; -+ if (status & UART_MSR_DDSR) -+ port->icount.dsr++; -+ if (status & UART_MSR_DDCD) -+ port->icount.dcd++; -+ if (status & UART_MSR_DCTS) { -+ port->icount.cts++; -+ if (port->tty->termios->c_cflag & CRTSCTS) { -+ int cts = (status & UART_MSR_CTS); -+ if (port->tty->hw_stopped) { -+ if (cts) { -+ port->tty->hw_stopped = 0; -+ sdio_uart_start_tx(port); -+ tty_wakeup(port->tty); -+ } -+ } else { -+ if (!cts) { -+ port->tty->hw_stopped = 1; -+ sdio_uart_stop_tx(port); -+ } -+ } -+ } -+ } -+} -+ -+/* -+ * This handles the interrupt from one port. -+ */ -+static void sdio_uart_irq(struct sdio_func *func) -+{ -+ struct sdio_uart_port *port = sdio_get_drvdata(func); -+ unsigned int iir, lsr; -+ -+ /* -+ * In a few places sdio_uart_irq() is called directly instead of -+ * waiting for the actual interrupt to be raised and the SDIO IRQ -+ * thread scheduled in order to reduce latency. However, some -+ * interaction with the tty core may end up calling us back -+ * (serial echo, flow control, etc.) through those same places -+ * causing undesirable effects. Let's stop the recursion here. -+ */ -+ if (unlikely(port->in_sdio_uart_irq == current)) -+ return; -+ -+ iir = sdio_in(port, UART_IIR); -+ if (iir & UART_IIR_NO_INT) -+ return; -+ -+ port->in_sdio_uart_irq = current; -+ lsr = sdio_in(port, UART_LSR); -+ if (lsr & UART_LSR_DR) -+ sdio_uart_receive_chars(port, &lsr); -+ sdio_uart_check_modem_status(port); -+ if (lsr & UART_LSR_THRE) -+ sdio_uart_transmit_chars(port); -+ port->in_sdio_uart_irq = NULL; -+} -+ -+static int sdio_uart_startup(struct sdio_uart_port *port) -+{ -+ unsigned long page; -+ int ret; -+ -+ /* -+ * Set the TTY IO error marker - we will only clear this -+ * once we have successfully opened the port. -+ */ -+ set_bit(TTY_IO_ERROR, &port->tty->flags); -+ -+ /* Initialise and allocate the transmit buffer. */ -+ page = __get_free_page(GFP_KERNEL); -+ if (!page) -+ return -ENOMEM; -+ port->xmit.buf = (unsigned char *)page; -+ circ_clear(&port->xmit); -+ -+ ret = sdio_uart_claim_func(port); -+ if (ret) -+ goto err1; -+ ret = sdio_enable_func(port->func); -+ if (ret) -+ goto err2; -+ ret = sdio_claim_irq(port->func, sdio_uart_irq); -+ if (ret) -+ goto err3; -+ -+ /* -+ * Clear the FIFO buffers and disable them. -+ * (they will be reenabled in sdio_change_speed()) -+ */ -+ sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); -+ sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO | -+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); -+ sdio_out(port, UART_FCR, 0); -+ -+ /* -+ * Clear the interrupt registers. -+ */ -+ (void) sdio_in(port, UART_LSR); -+ (void) sdio_in(port, UART_RX); -+ (void) sdio_in(port, UART_IIR); -+ (void) sdio_in(port, UART_MSR); -+ -+ /* -+ * Now, initialize the UART -+ */ -+ sdio_out(port, UART_LCR, UART_LCR_WLEN8); -+ -+ port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; -+ port->mctrl = TIOCM_OUT2; -+ -+ sdio_uart_change_speed(port, port->tty->termios, NULL); -+ -+ if (port->tty->termios->c_cflag & CBAUD) -+ sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); -+ -+ if (port->tty->termios->c_cflag & CRTSCTS) -+ if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) -+ port->tty->hw_stopped = 1; -+ -+ clear_bit(TTY_IO_ERROR, &port->tty->flags); -+ -+ /* Kick the IRQ handler once while we're still holding the host lock */ -+ sdio_uart_irq(port->func); -+ -+ sdio_uart_release_func(port); -+ return 0; -+ -+err3: -+ sdio_disable_func(port->func); -+err2: -+ sdio_uart_release_func(port); -+err1: -+ free_page((unsigned long)port->xmit.buf); -+ return ret; -+} -+ -+static void sdio_uart_shutdown(struct sdio_uart_port *port) -+{ -+ int ret; -+ -+ ret = sdio_uart_claim_func(port); -+ if (ret) -+ goto skip; -+ -+ sdio_uart_stop_rx(port); -+ -+ /* TODO: wait here for TX FIFO to drain */ -+ -+ /* Turn off DTR and RTS early. */ -+ if (port->tty->termios->c_cflag & HUPCL) -+ sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); -+ -+ /* Disable interrupts from this port */ -+ sdio_release_irq(port->func); -+ port->ier = 0; -+ sdio_out(port, UART_IER, 0); -+ -+ sdio_uart_clear_mctrl(port, TIOCM_OUT2); -+ -+ /* Disable break condition and FIFOs. */ -+ port->lcr &= ~UART_LCR_SBC; -+ sdio_out(port, UART_LCR, port->lcr); -+ sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO | -+ UART_FCR_CLEAR_RCVR | -+ UART_FCR_CLEAR_XMIT); -+ sdio_out(port, UART_FCR, 0); -+ -+ sdio_disable_func(port->func); -+ -+ sdio_uart_release_func(port); -+ -+skip: -+ /* Free the transmit buffer page. */ -+ free_page((unsigned long)port->xmit.buf); -+} -+ -+static int sdio_uart_open (struct tty_struct *tty, struct file * filp) -+{ -+ struct sdio_uart_port *port; -+ int ret; -+ -+ port = sdio_uart_port_get(tty->index); -+ if (!port) -+ return -ENODEV; -+ -+ mutex_lock(&port->open_lock); -+ -+ /* -+ * Make sure not to mess up with a dead port -+ * which has not been closed yet. -+ */ -+ if (tty->driver_data && tty->driver_data != port) { -+ mutex_unlock(&port->open_lock); -+ sdio_uart_port_put(port); -+ return -EBUSY; -+ } -+ -+ if (!port->opened) { -+ tty->driver_data = port; -+ port->tty = tty; -+ ret = sdio_uart_startup(port); -+ if (ret) { -+ tty->driver_data = NULL; -+ port->tty = NULL; -+ mutex_unlock(&port->open_lock); -+ sdio_uart_port_put(port); -+ return ret; -+ } -+ } -+ port->opened++; -+ mutex_unlock(&port->open_lock); -+ return 0; -+} -+ -+static void sdio_uart_close(struct tty_struct *tty, struct file * filp) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ -+ if (!port) -+ return; -+ -+ mutex_lock(&port->open_lock); -+ BUG_ON(!port->opened); -+ -+ /* -+ * This is messy. The tty layer calls us even when open() -+ * returned an error. Ignore this close request if tty->count -+ * is larger than port->count. -+ */ -+ if (tty->count > port->opened) { -+ mutex_unlock(&port->open_lock); -+ return; -+ } -+ -+ if (--port->opened == 0) { -+ tty->closing = 1; -+ sdio_uart_shutdown(port); -+ tty_ldisc_flush(tty); -+ port->tty = NULL; -+ tty->driver_data = NULL; -+ tty->closing = 0; -+ } -+ mutex_unlock(&port->open_lock); -+ sdio_uart_port_put(port); -+} -+ -+static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf, -+ int count) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ struct circ_buf *circ = &port->xmit; -+ int c, ret = 0; -+ -+ if (!port->func) -+ return -ENODEV; -+ -+ spin_lock(&port->write_lock); -+ while (1) { -+ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); -+ if (count < c) -+ c = count; -+ if (c <= 0) -+ break; -+ memcpy(circ->buf + circ->head, buf, c); -+ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); -+ buf += c; -+ count -= c; -+ ret += c; -+ } -+ spin_unlock(&port->write_lock); -+ -+ if ( !(port->ier & UART_IER_THRI)) { -+ int err = sdio_uart_claim_func(port); -+ if (!err) { -+ sdio_uart_start_tx(port); -+ sdio_uart_irq(port->func); -+ sdio_uart_release_func(port); -+ } else -+ ret = err; -+ } -+ -+ return ret; -+} -+ -+static int sdio_uart_write_room(struct tty_struct *tty) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ return port ? circ_chars_free(&port->xmit) : 0; -+} -+ -+static int sdio_uart_chars_in_buffer(struct tty_struct *tty) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ return port ? circ_chars_pending(&port->xmit) : 0; -+} -+ -+static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ -+ port->x_char = ch; -+ if (ch && !(port->ier & UART_IER_THRI)) { -+ if (sdio_uart_claim_func(port) != 0) -+ return; -+ sdio_uart_start_tx(port); -+ sdio_uart_irq(port->func); -+ sdio_uart_release_func(port); -+ } -+} -+ -+static void sdio_uart_throttle(struct tty_struct *tty) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ -+ if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) -+ return; -+ -+ if (sdio_uart_claim_func(port) != 0) -+ return; -+ -+ if (I_IXOFF(tty)) { -+ port->x_char = STOP_CHAR(tty); -+ sdio_uart_start_tx(port); -+ } -+ -+ if (tty->termios->c_cflag & CRTSCTS) -+ sdio_uart_clear_mctrl(port, TIOCM_RTS); -+ -+ sdio_uart_irq(port->func); -+ sdio_uart_release_func(port); -+} -+ -+static void sdio_uart_unthrottle(struct tty_struct *tty) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ -+ if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) -+ return; -+ -+ if (sdio_uart_claim_func(port) != 0) -+ return; -+ -+ if (I_IXOFF(tty)) { -+ if (port->x_char) { -+ port->x_char = 0; -+ } else { -+ port->x_char = START_CHAR(tty); -+ sdio_uart_start_tx(port); -+ } -+ } -+ -+ if (tty->termios->c_cflag & CRTSCTS) -+ sdio_uart_set_mctrl(port, TIOCM_RTS); -+ -+ sdio_uart_irq(port->func); -+ sdio_uart_release_func(port); -+} -+ -+static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ unsigned int cflag = tty->termios->c_cflag; -+ -+#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) -+ -+ if ((cflag ^ old_termios->c_cflag) == 0 && -+ RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) -+ return; -+ -+ if (sdio_uart_claim_func(port) != 0) -+ return; -+ -+ sdio_uart_change_speed(port, tty->termios, old_termios); -+ -+ /* Handle transition to B0 status */ -+ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) -+ sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR); -+ -+ /* Handle transition away from B0 status */ -+ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { -+ unsigned int mask = TIOCM_DTR; -+ if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) -+ mask |= TIOCM_RTS; -+ sdio_uart_set_mctrl(port, mask); -+ } -+ -+ /* Handle turning off CRTSCTS */ -+ if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { -+ tty->hw_stopped = 0; -+ sdio_uart_start_tx(port); -+ } -+ -+ /* Handle turning on CRTSCTS */ -+ if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { -+ if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) { -+ tty->hw_stopped = 1; -+ sdio_uart_stop_tx(port); -+ } -+ } -+ -+ sdio_uart_release_func(port); -+} -+ -+static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ -+ if (sdio_uart_claim_func(port) != 0) -+ return; -+ -+ if (break_state == -1) -+ port->lcr |= UART_LCR_SBC; -+ else -+ port->lcr &= ~UART_LCR_SBC; -+ sdio_out(port, UART_LCR, port->lcr); -+ -+ sdio_uart_release_func(port); -+} -+ -+static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ int result; -+ -+ result = sdio_uart_claim_func(port); -+ if (!result) { -+ result = port->mctrl | sdio_uart_get_mctrl(port); -+ sdio_uart_release_func(port); -+ } -+ -+ return result; -+} -+ -+static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, -+ unsigned int set, unsigned int clear) -+{ -+ struct sdio_uart_port *port = tty->driver_data; -+ int result; -+ -+ result =sdio_uart_claim_func(port); -+ if(!result) { -+ sdio_uart_update_mctrl(port, set, clear); -+ sdio_uart_release_func(port); -+ } -+ -+ return result; -+} -+ -+static int sdio_uart_read_proc(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int i, len = 0; -+ off_t begin = 0; -+ -+ len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", -+ "", "", ""); -+ for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) { -+ struct sdio_uart_port *port = sdio_uart_port_get(i); -+ if (port) { -+ len += sprintf(page+len, "%d: uart:SDIO", i); -+ if(capable(CAP_SYS_ADMIN)) { -+ len += sprintf(page + len, " tx:%d rx:%d", -+ port->icount.tx, port->icount.rx); -+ if (port->icount.frame) -+ len += sprintf(page + len, " fe:%d", -+ port->icount.frame); -+ if (port->icount.parity) -+ len += sprintf(page + len, " pe:%d", -+ port->icount.parity); -+ if (port->icount.brk) -+ len += sprintf(page + len, " brk:%d", -+ port->icount.brk); -+ if (port->icount.overrun) -+ len += sprintf(page + len, " oe:%d", -+ port->icount.overrun); -+ if (port->icount.cts) -+ len += sprintf(page + len, " cts:%d", -+ port->icount.cts); -+ if (port->icount.dsr) -+ len += sprintf(page + len, " dsr:%d", -+ port->icount.dsr); -+ if (port->icount.rng) -+ len += sprintf(page + len, " rng:%d", -+ port->icount.rng); -+ if (port->icount.dcd) -+ len += sprintf(page + len, " dcd:%d", -+ port->icount.dcd); -+ } -+ strcat(page, "\n"); -+ len++; -+ sdio_uart_port_put(port); -+ } -+ -+ if (len + begin > off + count) -+ goto done; -+ if (len + begin < off) { -+ begin += len; -+ len = 0; -+ } -+ } -+ *eof = 1; -+ -+done: -+ if (off >= len + begin) -+ return 0; -+ *start = page + (off - begin); -+ return (count < begin + len - off) ? count : (begin + len - off); -+} -+ -+static const struct tty_operations sdio_uart_ops = { -+ .open = sdio_uart_open, -+ .close = sdio_uart_close, -+ .write = sdio_uart_write, -+ .write_room = sdio_uart_write_room, -+ .chars_in_buffer = sdio_uart_chars_in_buffer, -+ .send_xchar = sdio_uart_send_xchar, -+ .throttle = sdio_uart_throttle, -+ .unthrottle = sdio_uart_unthrottle, -+ .set_termios = sdio_uart_set_termios, -+ .break_ctl = sdio_uart_break_ctl, -+ .tiocmget = sdio_uart_tiocmget, -+ .tiocmset = sdio_uart_tiocmset, -+ .read_proc = sdio_uart_read_proc, -+}; -+ -+static struct tty_driver *sdio_uart_tty_driver; -+ -+static int sdio_uart_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ struct sdio_uart_port *port; -+ int ret; -+ -+ port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL); -+ if (!port) -+ return -ENOMEM; -+ -+ if (func->class == SDIO_CLASS_UART) { -+ printk(KERN_WARNING "%s: need info on UART class basic setup\n", -+ sdio_func_id(func)); -+ kfree(port); -+ return -ENOSYS; -+ } else if (func->class == SDIO_CLASS_GPS) { -+ /* -+ * We need tuple 0x91. It contains SUBTPL_SIOREG -+ * and SUBTPL_RCVCAPS. -+ */ -+ struct sdio_func_tuple *tpl; -+ for (tpl = func->tuples; tpl; tpl = tpl->next) { -+ if (tpl->code != 0x91) -+ continue; -+ if (tpl->size < 10) -+ continue; -+ if (tpl->data[1] == 0) /* SUBTPL_SIOREG */ -+ break; -+ } -+ if (!tpl) { -+ printk(KERN_WARNING -+ "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n", -+ sdio_func_id(func)); -+ kfree(port); -+ return -EINVAL; -+ } -+ printk(KERN_DEBUG "%s: Register ID = 0x%02x, Exp ID = 0x%02x\n", -+ sdio_func_id(func), tpl->data[2], tpl->data[3]); -+ port->regs_offset = (tpl->data[4] << 0) | -+ (tpl->data[5] << 8) | -+ (tpl->data[6] << 16); -+ printk(KERN_DEBUG "%s: regs offset = 0x%x\n", -+ sdio_func_id(func), port->regs_offset); -+ port->uartclk = tpl->data[7] * 115200; -+ if (port->uartclk == 0) -+ port->uartclk = 115200; -+ printk(KERN_DEBUG "%s: clk %d baudcode %u 4800-div %u\n", -+ sdio_func_id(func), port->uartclk, -+ tpl->data[7], tpl->data[8] | (tpl->data[9] << 8)); -+ } else { -+ kfree(port); -+ return -EINVAL; -+ } -+ -+ port->func = func; -+ sdio_set_drvdata(func, port); -+ -+ ret = sdio_uart_add_port(port); -+ if (ret) { -+ kfree(port); -+ } else { -+ struct device *dev; -+ dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev); -+ if (IS_ERR(dev)) { -+ sdio_uart_port_remove(port); -+ ret = PTR_ERR(dev); -+ } -+ } -+ -+ return ret; -+} -+ -+static void sdio_uart_remove(struct sdio_func *func) -+{ -+ struct sdio_uart_port *port = sdio_get_drvdata(func); -+ -+ tty_unregister_device(sdio_uart_tty_driver, port->index); -+ sdio_uart_port_remove(port); -+} -+ -+static const struct sdio_device_id sdio_uart_ids[] = { -+ { SDIO_DEVICE_CLASS(SDIO_CLASS_UART) }, -+ { SDIO_DEVICE_CLASS(SDIO_CLASS_GPS) }, -+ { /* end: all zeroes */ }, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, sdio_uart_ids); -+ -+static struct sdio_driver sdio_uart_driver = { -+ .probe = sdio_uart_probe, -+ .remove = sdio_uart_remove, -+ .name = "sdio_uart", -+ .id_table = sdio_uart_ids, -+}; -+ -+static int __init sdio_uart_init(void) -+{ -+ int ret; -+ struct tty_driver *tty_drv; -+ -+ sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR); -+ if (!tty_drv) -+ return -ENOMEM; -+ -+ tty_drv->owner = THIS_MODULE; -+ tty_drv->driver_name = "sdio_uart"; -+ tty_drv->name = "ttySDIO"; -+ tty_drv->major = 0; /* dynamically allocated */ -+ tty_drv->minor_start = 0; -+ tty_drv->type = TTY_DRIVER_TYPE_SERIAL; -+ tty_drv->subtype = SERIAL_TYPE_NORMAL; -+ tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; -+ tty_drv->init_termios = tty_std_termios; -+ tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; -+ tty_drv->init_termios.c_ispeed = 4800; -+ tty_drv->init_termios.c_ospeed = 4800; -+ tty_set_operations(tty_drv, &sdio_uart_ops); -+ -+ ret = tty_register_driver(tty_drv); -+ if (ret) -+ goto err1; -+ -+ ret = sdio_register_driver(&sdio_uart_driver); -+ if (ret) -+ goto err2; -+ -+ return 0; -+ -+err2: -+ tty_unregister_driver(tty_drv); -+err1: -+ put_tty_driver(tty_drv); -+ return ret; -+} -+ -+static void __exit sdio_uart_exit(void) -+{ -+ sdio_unregister_driver(&sdio_uart_driver); -+ tty_unregister_driver(sdio_uart_tty_driver); -+ put_tty_driver(sdio_uart_tty_driver); -+} -+ -+module_init(sdio_uart_init); -+module_exit(sdio_uart_exit); -+ -+MODULE_AUTHOR("Nicolas Pitre"); -+MODULE_LICENSE("GPL"); ---- a/drivers/mmc/core/Makefile -+++ b/drivers/mmc/core/Makefile -@@ -8,5 +8,7 @@ endif - - obj-$(CONFIG_MMC) += mmc_core.o - mmc_core-y := core.o sysfs.o bus.o host.o \ -- mmc.o mmc_ops.o sd.o sd_ops.o -+ mmc.o mmc_ops.o sd.o sd_ops.o \ -+ sdio.o sdio_ops.o sdio_bus.o \ -+ sdio_cis.o sdio_io.o sdio_irq.o - |