Staging: ipack: Implement device matching on the bus level.
authorJens Taprogge <jens.taprogge@taprogge.org>
Tue, 4 Sep 2012 15:01:19 +0000 (17:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Sep 2012 22:13:51 +0000 (15:13 -0700)
Devices are match based upon their vendor and device ids.  Since
the individual drivers provide a list of supported ids they do not
need to implement the matching themselves.

Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/ipack/devices/ipoctal.c
drivers/staging/ipack/ipack.c
drivers/staging/ipack/ipack.h

index 829b8870a8682a74a2da2124557ad9a11b2b6da9..c94a9dffd1e5cf2fbcb70a81ff07c4ce43501866 100644 (file)
@@ -777,27 +777,6 @@ static const struct tty_operations ipoctal_fops = {
        .hangup =               ipoctal_hangup,
 };
 
-static int ipoctal_match(struct ipack_device *dev)
-{
-       int res;
-       unsigned char board_id;
-
-       if ((!dev->bus->ops) || (!dev->bus->ops->map_space) ||
-           (!dev->bus->ops->unmap_space))
-               return 0;
-
-       res = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE);
-       if (res)
-               return 0;
-
-       res = ipoctal_check_model(dev, &board_id);
-       dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE);
-       if (!res)
-               return 1;
-
-       return 0;
-}
-
 static int ipoctal_probe(struct ipack_device *dev)
 {
        int res;
@@ -858,8 +837,7 @@ static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
 MODULE_DEVICE_TABLE(ipack, ipoctal_ids);
 
 static const struct ipack_driver_ops ipoctal_drv_ops = {
-       .match = ipoctal_match,
-       .probe = ipoctal_probe,
+       .probe  = ipoctal_probe,
        .remove = ipoctal_remove,
 };
 
index 9474226dd8e2e9e444ce318e8b772c00f21d637b..a3286290c79bbbfae5aa25468f1a37d2defd4966 100644 (file)
@@ -26,20 +26,43 @@ static void ipack_device_release(struct device *dev)
        kfree(device);
 }
 
-static int ipack_bus_match(struct device *device, struct device_driver *driver)
+static inline const struct ipack_device_id *
+ipack_match_one_device(const struct ipack_device_id *id,
+                      const struct ipack_device *device)
 {
-       int ret;
-       struct ipack_device *dev = to_ipack_dev(device);
-       struct ipack_driver *drv = to_ipack_driver(driver);
+       if ((id->format == IPACK_ANY_ID || id->format == device->id_format) &&
+           (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) &&
+           (id->device == IPACK_ANY_ID || id->device == device->id_device))
+               return id;
+       return NULL;
+}
 
-       if ((!drv->ops) || (!drv->ops->match))
-               return -EINVAL;
+static const struct ipack_device_id *
+ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev)
+{
+       if (ids) {
+               while (ids->vendor || ids->device) {
+                       if (ipack_match_one_device(ids, idev))
+                               return ids;
+                       ids++;
+               }
+       }
+       return NULL;
+}
 
-       ret = drv->ops->match(dev);
-       if (ret)
-               dev->driver = drv;
+static int ipack_bus_match(struct device *dev, struct device_driver *drv)
+{
+       struct ipack_device *idev = to_ipack_dev(dev);
+       struct ipack_driver *idrv = to_ipack_driver(drv);
+       const struct ipack_device_id *found_id;
 
-       return ret;
+       found_id = ipack_match_id(idrv->id_table, idev);
+       if (found_id) {
+               idev->driver = idrv;
+               return 1;
+       }
+
+       return 0;
 }
 
 static int ipack_bus_probe(struct device *device)
index e6e38e7dd9f1b4e7233e703a3b6a4a9e8f504ba2..0f482fd205d9c07d87793e342e716b8c3a885d9d 100644 (file)
@@ -84,13 +84,11 @@ struct ipack_device {
 /**
  *     struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device
  *
- *     @match: Match function
  *     @probe: Probe function
  *     @remove: tell the driver that the carrier board wants to remove one device
  */
 
 struct ipack_driver_ops {
-       int (*match) (struct ipack_device *dev);
        int (*probe) (struct ipack_device *dev);
        void (*remove) (struct ipack_device *dev);
 };