summaryrefslogtreecommitdiff
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-09-23 03:46:04 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 18:39:43 +0400
commit75368bf6c2876d8f33abfe77aa3864869a3893eb (patch)
tree97a543508a8aeb45646d059f8cdd561ae0a76ef2 /drivers/spi/spi.c
parentb5f3294f0be5496aec01e5aa709a5fab8bb2f225 (diff)
downloadlinux-75368bf6c2876d8f33abfe77aa3864869a3893eb.tar.xz
spi: add support for device table matching
With this patch spi drivers can use standard spi_driver.id_table and MODULE_DEVICE_TABLE() mechanisms to bind against the devices. Just like we do with I2C drivers. This is useful when a single driver supports several variants of devices but it is not possible to detect them in run-time (like non-JEDEC chips probing in drivers/mtd/devices/m25p80.c), and when platform_data usage is overkill. This patch also makes life a lot easier on OpenFirmware platforms, since with OF we extensively use proper device IDs in modaliases. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Jean Delvare <khali@linux-fr.org> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 70845ccd85c3..8518a6eb63f3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -59,9 +59,32 @@ static struct device_attribute spi_dev_attrs[] = {
* and the sysfs version makes coldplug work too.
*/
+static const struct spi_device_id *spi_match_id(const struct spi_device_id *id,
+ const struct spi_device *sdev)
+{
+ while (id->name[0]) {
+ if (!strcmp(sdev->modalias, id->name))
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
+const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev)
+{
+ const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver);
+
+ return spi_match_id(sdrv->id_table, sdev);
+}
+EXPORT_SYMBOL_GPL(spi_get_device_id);
+
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
+ const struct spi_driver *sdrv = to_spi_driver(drv);
+
+ if (sdrv->id_table)
+ return !!spi_match_id(sdrv->id_table, spi);
return strcmp(spi->modalias, drv->name) == 0;
}