* 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;
 }
 
                        __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* spi */
+
+#define SPI_NAME_SIZE  32
+
+struct spi_device_id {
+       char name[SPI_NAME_SIZE];
+       kernel_ulong_t driver_data      /* Data private to the driver */
+                       __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
 /* dmi */
 enum dmi_field {
        DMI_NONE,
 
 #define __LINUX_SPI_H
 
 #include <linux/device.h>
+#include <linux/mod_devicetable.h>
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
        int                     irq;
        void                    *controller_state;
        void                    *controller_data;
-       char                    modalias[32];
+       char                    modalias[SPI_NAME_SIZE];
 
        /*
         * likely need more hooks for more protocol options affecting how
 
 /**
  * struct spi_driver - Host side "protocol" driver
+ * @id_table: List of SPI devices supported by this driver
  * @probe: Binds this driver to the spi device.  Drivers can verify
  *     that the device is actually present, and may need to configure
  *     characteristics (such as bits_per_word) which weren't needed for
  * MMC, RTC, filesystem character device nodes, and hardware monitoring.
  */
 struct spi_driver {
+       const struct spi_device_id *id_table;
        int                     (*probe)(struct spi_device *spi);
        int                     (*remove)(struct spi_device *spi);
        void                    (*shutdown)(struct spi_device *spi);
         * controller_data goes to spi_device.controller_data,
         * irq is copied too
         */
-       char            modalias[32];
+       char            modalias[SPI_NAME_SIZE];
        const void      *platform_data;
        void            *controller_data;
        int             irq;
                device_unregister(&spi->dev);
 }
 
+extern const struct spi_device_id *
+spi_get_device_id(const struct spi_device *sdev);
+
 #endif /* __LINUX_SPI_H */
 
        return 1;
 }
 
+/* Looks like: S */
+static int do_spi_entry(const char *filename, struct spi_device_id *id,
+                       char *alias)
+{
+       sprintf(alias, "%s", id->name);
+
+       return 1;
+}
+
 static const struct dmifield {
        const char *prefix;
        int field;
                do_table(symval, sym->st_size,
                         sizeof(struct i2c_device_id), "i2c",
                         do_i2c_entry, mod);
+       else if (sym_is(symname, "__mod_spi_device_table"))
+               do_table(symval, sym->st_size,
+                        sizeof(struct spi_device_id), "spi",
+                        do_spi_entry, mod);
        else if (sym_is(symname, "__mod_dmi_device_table"))
                do_table(symval, sym->st_size,
                         sizeof(struct dmi_system_id), "dmi",