aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 70845ccd85c3..b76f2468a84a 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -23,6 +23,7 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/cache.h> 24#include <linux/cache.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/mod_devicetable.h>
26#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
27 28
28 29
@@ -59,9 +60,32 @@ static struct device_attribute spi_dev_attrs[] = {
59 * and the sysfs version makes coldplug work too. 60 * and the sysfs version makes coldplug work too.
60 */ 61 */
61 62
63static const struct spi_device_id *spi_match_id(const struct spi_device_id *id,
64 const struct spi_device *sdev)
65{
66 while (id->name[0]) {
67 if (!strcmp(sdev->modalias, id->name))
68 return id;
69 id++;
70 }
71 return NULL;
72}
73
74const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev)
75{
76 const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver);
77
78 return spi_match_id(sdrv->id_table, sdev);
79}
80EXPORT_SYMBOL_GPL(spi_get_device_id);
81
62static int spi_match_device(struct device *dev, struct device_driver *drv) 82static int spi_match_device(struct device *dev, struct device_driver *drv)
63{ 83{
64 const struct spi_device *spi = to_spi_device(dev); 84 const struct spi_device *spi = to_spi_device(dev);
85 const struct spi_driver *sdrv = to_spi_driver(drv);
86
87 if (sdrv->id_table)
88 return !!spi_match_id(sdrv->id_table, spi);
65 89
66 return strcmp(spi->modalias, drv->name) == 0; 90 return strcmp(spi->modalias, drv->name) == 0;
67} 91}
@@ -70,7 +94,7 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
70{ 94{
71 const struct spi_device *spi = to_spi_device(dev); 95 const struct spi_device *spi = to_spi_device(dev);
72 96
73 add_uevent_var(env, "MODALIAS=%s", spi->modalias); 97 add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
74 return 0; 98 return 0;
75} 99}
76 100
@@ -639,6 +663,65 @@ int spi_setup(struct spi_device *spi)
639} 663}
640EXPORT_SYMBOL_GPL(spi_setup); 664EXPORT_SYMBOL_GPL(spi_setup);
641 665
666/**
667 * spi_async - asynchronous SPI transfer
668 * @spi: device with which data will be exchanged
669 * @message: describes the data transfers, including completion callback
670 * Context: any (irqs may be blocked, etc)
671 *
672 * This call may be used in_irq and other contexts which can't sleep,
673 * as well as from task contexts which can sleep.
674 *
675 * The completion callback is invoked in a context which can't sleep.
676 * Before that invocation, the value of message->status is undefined.
677 * When the callback is issued, message->status holds either zero (to
678 * indicate complete success) or a negative error code. After that
679 * callback returns, the driver which issued the transfer request may
680 * deallocate the associated memory; it's no longer in use by any SPI
681 * core or controller driver code.
682 *
683 * Note that although all messages to a spi_device are handled in
684 * FIFO order, messages may go to different devices in other orders.
685 * Some device might be higher priority, or have various "hard" access
686 * time requirements, for example.
687 *
688 * On detection of any fault during the transfer, processing of
689 * the entire message is aborted, and the device is deselected.
690 * Until returning from the associated message completion callback,
691 * no other spi_message queued to that device will be processed.
692 * (This rule applies equally to all the synchronous transfer calls,
693 * which are wrappers around this core asynchronous primitive.)
694 */
695int spi_async(struct spi_device *spi, struct spi_message *message)
696{
697 struct spi_master *master = spi->master;
698
699 /* Half-duplex links include original MicroWire, and ones with
700 * only one data pin like SPI_3WIRE (switches direction) or where
701 * either MOSI or MISO is missing. They can also be caused by
702 * software limitations.
703 */
704 if ((master->flags & SPI_MASTER_HALF_DUPLEX)
705 || (spi->mode & SPI_3WIRE)) {
706 struct spi_transfer *xfer;
707 unsigned flags = master->flags;
708
709 list_for_each_entry(xfer, &message->transfers, transfer_list) {
710 if (xfer->rx_buf && xfer->tx_buf)
711 return -EINVAL;
712 if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)
713 return -EINVAL;
714 if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)
715 return -EINVAL;
716 }
717 }
718
719 message->spi = spi;
720 message->status = -EINPROGRESS;
721 return master->transfer(spi, message);
722}
723EXPORT_SYMBOL_GPL(spi_async);
724
642 725
643/*-------------------------------------------------------------------------*/ 726/*-------------------------------------------------------------------------*/
644 727