From: Linus Torvalds Date: Sat, 14 Aug 2010 18:54:09 +0000 (-0700) Subject: Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6 X-Git-Tag: v2.6.36-rc1~19 X-Git-Url: https://bbs.cooldavid.org/git/?a=commitdiff_plain;h=b171aa27700c78511086a759383b033949c9d7f0;hp=-c;p=net-next-2.6.git Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6 * 'next-spi' of git://git.secretlab.ca/git/linux-2.6: spi/amba_pl022: Fix probe and remove hook section annotations. spi/mpc5121: change annotations for probe and remove functions spi/bitbang: reinitialize transfer parameters for every message spi/spi-gpio: add support for controllers without MISO or MOSI pin spi/bitbang: add support for SPI_MASTER_NO_{TX, RX} modes SPI100k: Fix 8-bit and RX-only transfers spi/mmc_spi: mmc_spi adaptations for SPI bus locking API spi/mmc_spi: SPI bus locking API, using mutex Fix trivial conflict in drivers/spi/mpc512x_psc_spi.c due to 'struct of_device' => 'struct platform_device' rename and __init/__exit to __devinit/__devexit fix. --- b171aa27700c78511086a759383b033949c9d7f0 diff --combined drivers/mmc/host/mmc_spi.c index 1145ea0792e,dfc290dd43a..62a35822003 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@@ -182,7 -182,7 +182,7 @@@ mmc_spi_readbytes(struct mmc_spi_host * 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 +541,7 @@@ mmc_spi_command_send(struct mmc_spi_hos 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 +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 +822,7 @@@ mmc_spi_readblock(struct mmc_spi_host * 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 +1018,7 @@@ mmc_spi_data_do(struct mmc_spi_host *ho 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 +1084,9 @@@ static void mmc_spi_request(struct mmc_ } #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 +1097,9 @@@ mmc_cs_off(host); } + /* release the bus */ + spi_bus_unlock(host->spi->master); + mmc_request_done(host->mmc, mrq); } @@@ -1290,23 -1296,6 +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 +1327,6 @@@ 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. * @@@ -1533,21 -1496,12 +1496,21 @@@ static int __devexit mmc_spi_remove(str return 0; } +#if defined(CONFIG_OF) +static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { + { .compatible = "mmc-spi-slot", }, + {}, +}; +#endif static struct spi_driver mmc_spi_driver = { .driver = { .name = "mmc_spi", .bus = &spi_bus_type, .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = mmc_spi_of_match_table, +#endif }, .probe = mmc_spi_probe, .remove = __devexit_p(mmc_spi_remove), diff --combined drivers/spi/mpc512x_psc_spi.c index cddbfceb324,c8d69fc393a..77d9e7ee8b2 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@@ -19,7 -19,6 +19,7 @@@ #include #include #include +#include #include #include #include @@@ -406,9 -405,9 +406,9 @@@ static irqreturn_t mpc512x_psc_spi_isr( } /* bus_num is used only for the case dev->platform_data == NULL */ - static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, - u32 size, unsigned int irq, - s16 bus_num) + static int __devinit mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, + u32 size, unsigned int irq, + s16 bus_num) { struct fsl_spi_platform_data *pdata = dev->platform_data; struct mpc512x_psc_spi *mps; @@@ -441,7 -440,6 +441,7 @@@ master->setup = mpc512x_psc_spi_setup; master->transfer = mpc512x_psc_spi_transfer; master->cleanup = mpc512x_psc_spi_cleanup; + master->dev.of_node = dev->of_node; tempp = ioremap(regaddr, size); if (!tempp) { @@@ -492,7 -490,7 +492,7 @@@ free_master return ret; } - static int __exit mpc512x_psc_spi_do_remove(struct device *dev) + static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); @@@ -507,8 -505,8 +507,8 @@@ return 0; } - static int __init mpc512x_psc_spi_of_probe(struct platform_device *op, - const struct of_device_id *match) -static int __devinit mpc512x_psc_spi_of_probe(struct of_device *op, ++static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op, + const struct of_device_id *match) { const u32 *regaddr_p; u64 regaddr64, size64; @@@ -539,7 -537,7 +539,7 @@@ irq_of_parse_and_map(op->dev.of_node, 0), id); } - static int __exit mpc512x_psc_spi_of_remove(struct platform_device *op) -static int __devexit mpc512x_psc_spi_of_remove(struct of_device *op) ++static int __devexit mpc512x_psc_spi_of_remove(struct platform_device *op) { return mpc512x_psc_spi_do_remove(&op->dev); } @@@ -553,7 -551,7 +553,7 @@@ MODULE_DEVICE_TABLE(of, mpc512x_psc_spi static struct of_platform_driver mpc512x_psc_spi_of_driver = { .probe = mpc512x_psc_spi_of_probe, - .remove = __exit_p(mpc512x_psc_spi_of_remove), + .remove = __devexit_p(mpc512x_psc_spi_of_remove), .driver = { .name = "mpc512x-psc-spi", .owner = THIS_MODULE, diff --combined drivers/spi/spi.c index 1bb1b88780c,fdde7061ef5..a9e5c79ae52 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@@ -26,7 -26,6 +26,7 @@@ #include #include #include +#include /* SPI bustype and spi_master class are registered after board init code @@@ -528,6 -527,10 +528,10 @@@ int spi_register_master(struct spi_mast dynamic = 1; } + spin_lock_init(&master->bus_lock_spinlock); + mutex_init(&master->bus_lock_mutex); + master->bus_lock_flag = 0; + /* register the device, then userspace will see it. * registration fails if the bus ID is in use. */ @@@ -541,9 -544,6 +545,9 @@@ /* populate children from any spi device tables */ scan_boardinfo(master); status = 0; + + /* Register devices from the device tree */ + of_register_spi_devices(master); done: return status; } @@@ -670,6 -670,35 +674,35 @@@ int spi_setup(struct spi_device *spi } EXPORT_SYMBOL_GPL(spi_setup); + static int __spi_async(struct spi_device *spi, struct spi_message *message) + { + struct spi_master *master = spi->master; + + /* Half-duplex links include original MicroWire, and ones with + * only one data pin like SPI_3WIRE (switches direction) or where + * either MOSI or MISO is missing. They can also be caused by + * software limitations. + */ + if ((master->flags & SPI_MASTER_HALF_DUPLEX) + || (spi->mode & SPI_3WIRE)) { + struct spi_transfer *xfer; + unsigned flags = master->flags; + + list_for_each_entry(xfer, &message->transfers, transfer_list) { + if (xfer->rx_buf && xfer->tx_buf) + return -EINVAL; + if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) + return -EINVAL; + if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) + return -EINVAL; + } + } + + message->spi = spi; + message->status = -EINPROGRESS; + return master->transfer(spi, message); + } + /** * spi_async - asynchronous SPI transfer * @spi: device with which data will be exchanged @@@ -702,33 -731,68 +735,68 @@@ int spi_async(struct spi_device *spi, struct spi_message *message) { struct spi_master *master = spi->master; + int ret; + unsigned long flags; - /* Half-duplex links include original MicroWire, and ones with - * only one data pin like SPI_3WIRE (switches direction) or where - * either MOSI or MISO is missing. They can also be caused by - * software limitations. - */ - if ((master->flags & SPI_MASTER_HALF_DUPLEX) - || (spi->mode & SPI_3WIRE)) { - struct spi_transfer *xfer; - unsigned flags = master->flags; + spin_lock_irqsave(&master->bus_lock_spinlock, flags); - list_for_each_entry(xfer, &message->transfers, transfer_list) { - if (xfer->rx_buf && xfer->tx_buf) - return -EINVAL; - if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) - return -EINVAL; - if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) - return -EINVAL; - } - } + if (master->bus_lock_flag) + ret = -EBUSY; + else + ret = __spi_async(spi, message); - message->spi = spi; - message->status = -EINPROGRESS; - return master->transfer(spi, message); + spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); + + return ret; } EXPORT_SYMBOL_GPL(spi_async); + /** + * spi_async_locked - version of spi_async with exclusive bus usage + * @spi: device with which data will be exchanged + * @message: describes the data transfers, including completion callback + * Context: any (irqs may be blocked, etc) + * + * This call may be used in_irq and other contexts which can't sleep, + * as well as from task contexts which can sleep. + * + * The completion callback is invoked in a context which can't sleep. + * Before that invocation, the value of message->status is undefined. + * When the callback is issued, message->status holds either zero (to + * indicate complete success) or a negative error code. After that + * callback returns, the driver which issued the transfer request may + * deallocate the associated memory; it's no longer in use by any SPI + * core or controller driver code. + * + * Note that although all messages to a spi_device are handled in + * FIFO order, messages may go to different devices in other orders. + * Some device might be higher priority, or have various "hard" access + * time requirements, for example. + * + * On detection of any fault during the transfer, processing of + * the entire message is aborted, and the device is deselected. + * Until returning from the associated message completion callback, + * no other spi_message queued to that device will be processed. + * (This rule applies equally to all the synchronous transfer calls, + * which are wrappers around this core asynchronous primitive.) + */ + int spi_async_locked(struct spi_device *spi, struct spi_message *message) + { + struct spi_master *master = spi->master; + int ret; + unsigned long flags; + + spin_lock_irqsave(&master->bus_lock_spinlock, flags); + + ret = __spi_async(spi, message); + + spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); + + return ret; + + } + EXPORT_SYMBOL_GPL(spi_async_locked); + /*-------------------------------------------------------------------------*/ @@@ -742,6 -806,32 +810,32 @@@ static void spi_complete(void *arg complete(arg); } + static int __spi_sync(struct spi_device *spi, struct spi_message *message, + int bus_locked) + { + DECLARE_COMPLETION_ONSTACK(done); + int status; + struct spi_master *master = spi->master; + + message->complete = spi_complete; + message->context = &done; + + if (!bus_locked) + mutex_lock(&master->bus_lock_mutex); + + status = spi_async_locked(spi, message); + + if (!bus_locked) + mutex_unlock(&master->bus_lock_mutex); + + if (status == 0) { + wait_for_completion(&done); + status = message->status; + } + message->context = NULL; + return status; + } + /** * spi_sync - blocking/synchronous SPI data transfers * @spi: device with which data will be exchanged @@@ -765,21 -855,86 +859,86 @@@ */ int spi_sync(struct spi_device *spi, struct spi_message *message) { - DECLARE_COMPLETION_ONSTACK(done); - int status; - - message->complete = spi_complete; - message->context = &done; - status = spi_async(spi, message); - if (status == 0) { - wait_for_completion(&done); - status = message->status; - } - message->context = NULL; - return status; + return __spi_sync(spi, message, 0); } EXPORT_SYMBOL_GPL(spi_sync); + /** + * spi_sync_locked - version of spi_sync with exclusive bus usage + * @spi: device with which data will be exchanged + * @message: describes the data transfers + * Context: can sleep + * + * This call may only be used from a context that may sleep. The sleep + * is non-interruptible, and has no timeout. Low-overhead controller + * drivers may DMA directly into and out of the message buffers. + * + * This call should be used by drivers that require exclusive access to the + * SPI bus. It has to be preceeded by a spi_bus_lock call. The SPI bus must + * be released by a spi_bus_unlock call when the exclusive access is over. + * + * It returns zero on success, else a negative error code. + */ + int spi_sync_locked(struct spi_device *spi, struct spi_message *message) + { + return __spi_sync(spi, message, 1); + } + EXPORT_SYMBOL_GPL(spi_sync_locked); + + /** + * spi_bus_lock - obtain a lock for exclusive SPI bus usage + * @master: SPI bus master that should be locked for exclusive bus access + * Context: can sleep + * + * This call may only be used from a context that may sleep. The sleep + * is non-interruptible, and has no timeout. + * + * This call should be used by drivers that require exclusive access to the + * SPI bus. The SPI bus must be released by a spi_bus_unlock call when the + * exclusive access is over. Data transfer must be done by spi_sync_locked + * and spi_async_locked calls when the SPI bus lock is held. + * + * It returns zero on success, else a negative error code. + */ + int spi_bus_lock(struct spi_master *master) + { + unsigned long flags; + + mutex_lock(&master->bus_lock_mutex); + + spin_lock_irqsave(&master->bus_lock_spinlock, flags); + master->bus_lock_flag = 1; + spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); + + /* mutex remains locked until spi_bus_unlock is called */ + + return 0; + } + EXPORT_SYMBOL_GPL(spi_bus_lock); + + /** + * spi_bus_unlock - release the lock for exclusive SPI bus usage + * @master: SPI bus master that was locked for exclusive bus access + * Context: can sleep + * + * This call may only be used from a context that may sleep. The sleep + * is non-interruptible, and has no timeout. + * + * This call releases an SPI bus lock previously obtained by an spi_bus_lock + * call. + * + * It returns zero on success, else a negative error code. + */ + int spi_bus_unlock(struct spi_master *master) + { + master->bus_lock_flag = 0; + + mutex_unlock(&master->bus_lock_mutex); + + return 0; + } + EXPORT_SYMBOL_GPL(spi_bus_unlock); + /* portable code must never pass more than 32 bytes */ #define SPI_BUFSIZ max(32,SMP_CACHE_BYTES)