diff options
author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-08-31 20:06:42 +0000 |
---|---|---|
committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-08-31 20:06:42 +0000 |
commit | c433567bd3abf153f116b01fec22538a3c9d7fe7 (patch) | |
tree | bdcefc9d858bf0d7168f7b83bfb25fab886669df /target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch | |
parent | 2bbe78f8f61b86eebfe2972358f11c9a28a2ffb7 (diff) |
generic: bacport SPI bus locking API
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22862 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch')
-rw-r--r-- | target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch b/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch new file mode 100644 index 0000000000..d6ad3d4e9b --- /dev/null +++ b/target/linux/generic/patches-2.6.34/911-backport-mmc_spi-use-spi-bus-locking-api.patch @@ -0,0 +1,143 @@ +From 4751c1c74bc7b596db5de0c93be1a22a570145c0 Mon Sep 17 00:00:00 2001 +From: Ernst Schwab <eschwab@online.de> +Date: Thu, 18 Feb 2010 12:47:46 +0100 +Subject: [PATCH] spi/mmc_spi: mmc_spi adaptations for SPI bus locking API + +Modification of the mmc_spi driver to use the SPI bus locking API. +With this, the mmc_spi driver can be used together with other SPI +devices on the same SPI bus. The exclusive access to the SPI bus is +now managed in the SPI layer. The counting of chip selects in the probe +function is no longer needed. + +Signed-off-by: Ernst Schwab <eschwab@online.de> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +Tested-by: Matt Fleming <matt@console-pimps.org> +Tested-by: Antonio Ospite <ospite@studenti.unina.it> +--- + drivers/mmc/host/mmc_spi.c | 59 ++++++++----------------------------------- + 1 files changed, 11 insertions(+), 48 deletions(-) + +--- a/drivers/mmc/host/mmc_spi.c ++++ b/drivers/mmc/host/mmc_spi.c +@@ -182,7 +182,7 @@ mmc_spi_readbytes(struct mmc_spi_host *h + host->data_dma, sizeof(*host->data), + DMA_FROM_DEVICE); + +- status = spi_sync(host->spi, &host->readback); ++ status = spi_sync_locked(host->spi, &host->readback); + + if (host->dma_dev) + dma_sync_single_for_cpu(host->dma_dev, +@@ -541,7 +541,7 @@ mmc_spi_command_send(struct mmc_spi_host + host->data_dma, sizeof(*host->data), + DMA_BIDIRECTIONAL); + } +- status = spi_sync(host->spi, &host->m); ++ status = spi_sync_locked(host->spi, &host->m); + + if (host->dma_dev) + dma_sync_single_for_cpu(host->dma_dev, +@@ -685,7 +685,7 @@ mmc_spi_writeblock(struct mmc_spi_host * + host->data_dma, sizeof(*scratch), + DMA_BIDIRECTIONAL); + +- status = spi_sync(spi, &host->m); ++ status = spi_sync_locked(spi, &host->m); + + if (status != 0) { + dev_dbg(&spi->dev, "write error (%d)\n", status); +@@ -822,7 +822,7 @@ mmc_spi_readblock(struct mmc_spi_host *h + DMA_FROM_DEVICE); + } + +- status = spi_sync(spi, &host->m); ++ status = spi_sync_locked(spi, &host->m); + + if (host->dma_dev) { + dma_sync_single_for_cpu(host->dma_dev, +@@ -1018,7 +1018,7 @@ mmc_spi_data_do(struct mmc_spi_host *hos + host->data_dma, sizeof(*scratch), + DMA_BIDIRECTIONAL); + +- tmp = spi_sync(spi, &host->m); ++ tmp = spi_sync_locked(spi, &host->m); + + if (host->dma_dev) + dma_sync_single_for_cpu(host->dma_dev, +@@ -1084,6 +1084,9 @@ static void mmc_spi_request(struct mmc_h + } + #endif + ++ /* request exclusive bus access */ ++ spi_bus_lock(host->spi->master); ++ + /* issue command; then optionally data and stop */ + status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL); + if (status == 0 && mrq->data) { +@@ -1094,6 +1097,9 @@ static void mmc_spi_request(struct mmc_h + mmc_cs_off(host); + } + ++ /* release the bus */ ++ spi_bus_unlock(host->spi->master); ++ + mmc_request_done(host->mmc, mrq); + } + +@@ -1290,23 +1296,6 @@ mmc_spi_detect_irq(int irq, void *mmc) + 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; +@@ -1338,32 +1327,6 @@ static int mmc_spi_probe(struct spi_devi + 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. + * |