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 000000000..d6ad3d4e9 --- /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. + 	 *  | 
