]> git.hungrycats.org Git - linux/commitdiff
PCI: start to use common fields of struct device_driver more
authorPatrick Mochel <mochel@geena.pdx.osdl.net>
Tue, 28 May 2002 11:02:33 +0000 (04:02 -0700)
committerPatrick Mochel <mochel@hera.kernel.org>
Tue, 28 May 2002 11:02:33 +0000 (04:02 -0700)
- add struct device_driver field to struct pci_driver
- make sure those fields get set on driver registration (and register with core)
- remove internal pci_drivers

drivers/pci/hotplug.c
drivers/pci/pci-driver.c
drivers/pci/probe.c
include/linux/pci.h

index 90eb3d8d426e27ce479c2c7c82d4e0d740d98fdb..96b02d5be4befd6913dc31e5d8203cc842702e3c 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/module.h>
 #include <linux/kmod.h>                /* for hotplug_path */
 
-extern struct list_head pci_drivers;
 extern int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev);
 
 #ifndef FALSE
@@ -61,7 +60,7 @@ pci_announce_device_to_drivers(struct pci_dev *dev)
 {
        struct list_head *ln;
 
-       for(ln=pci_drivers.next; ln != &pci_drivers; ln=ln->next) {
+       for(ln=pci_bus_type.drivers.next; ln != &pci_bus_type.drivers; ln=ln->next) {
                struct pci_driver *drv = list_entry(ln, struct pci_driver, node);
                if (drv->remove && pci_announce_device(drv, dev))
                        break;
index 8ff363949d68a273b2a21b6e7b8c85167bf44629..228f10eba8b14f03d5877137733a1f6574754608 100644 (file)
@@ -10,8 +10,6 @@
  *  Registration of PCI drivers and handling of hot-pluggable devices.
  */
 
-LIST_HEAD(pci_drivers);
-
 /**
  * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
  * @ids: array of PCI device id structures to search in
@@ -61,6 +59,57 @@ out:
        return ret;
 }
 
+
+static int pci_device_probe(struct device * dev)
+{
+       int error = 0;
+
+       struct pci_driver * drv = list_entry(dev->driver,struct pci_driver,driver);
+       struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+
+       if (drv->probe)
+               error = drv->probe(pci_dev,NULL);
+       printk("%s: returning %d\n",__FUNCTION__,error);
+       return error > 0 ? 0 : -ENODEV;
+}
+
+static int pci_device_remove(struct device * dev, u32 flags)
+{
+       struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+
+       if (dev->driver) {
+               struct pci_driver * drv = list_entry(dev->driver,struct pci_driver,driver);
+               if (drv->remove)
+                       drv->remove(pci_dev);
+       }
+       return 0;
+}
+
+static int pci_device_suspend(struct device * dev, u32 state, u32 level)
+{
+       struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
+       int error = 0;
+
+       if (pci_dev->driver) {
+               if (level == SUSPEND_SAVE_STATE && pci_dev->driver->save_state)
+                       error = pci_dev->driver->save_state(pci_dev,state);
+               else if (level == SUSPEND_POWER_DOWN && pci_dev->driver->suspend)
+                       error = pci_dev->driver->suspend(pci_dev,state);
+       }
+       return error;
+}
+
+static int pci_device_resume(struct device * dev, u32 level)
+{
+       struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
+
+       if (pci_dev->driver) {
+               if (level == RESUME_POWER_ON && pci_dev->driver->resume)
+                       pci_dev->driver->resume(pci_dev);
+       }
+       return 0;
+}
+
 /**
  * pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
@@ -73,15 +122,25 @@ out:
 int
 pci_register_driver(struct pci_driver *drv)
 {
-       struct pci_dev *dev;
        int count = 0;
+       struct pci_dev * dev;
+
+       /* initialize common driver fields */
+       drv->driver.name = drv->name;
+       drv->driver.bus = &pci_bus_type;
+       drv->driver.probe = pci_device_probe;
+       drv->driver.resume = pci_device_resume;
+       drv->driver.suspend = pci_device_suspend;
+       drv->driver.remove = pci_device_remove;
+
+       /* register with core */
+       count = driver_register(&drv->driver);
 
-       list_add_tail(&drv->node, &pci_drivers);
        pci_for_each_dev(dev) {
                if (!pci_dev_driver(dev))
-                       count += pci_announce_device(drv, dev);
+                       pci_announce_device(drv, dev);
        }
-       return count;
+       return count ? count : 1;
 }
 
 /**
@@ -97,16 +156,21 @@ pci_register_driver(struct pci_driver *drv)
 void
 pci_unregister_driver(struct pci_driver *drv)
 {
-       struct pci_dev *dev;
-
-       list_del(&drv->node);
-       pci_for_each_dev(dev) {
-               if (dev->driver == drv) {
-                       if (drv->remove)
-                               drv->remove(dev);
-                       dev->driver = NULL;
-               }
+       list_t * node;
+       
+       node = drv->driver.devices.next;
+
+       while (node != &drv->driver.devices) {
+               struct device * dev = list_entry(node,struct device,driver_list);
+               struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
+
+               if (drv->remove)
+                       drv->remove(pci_dev);
+               pci_dev->driver = NULL;
+               dev->driver = NULL;
+               list_del_init(&dev->driver_list);
        }
+       put_driver(&drv->driver);
 }
 
 static struct pci_driver pci_compat_driver = {
@@ -134,36 +198,6 @@ pci_dev_driver(const struct pci_dev *dev)
        return NULL;
 }
 
-static int pci_device_suspend(struct device * dev, u32 state, u32 level)
-{
-       struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
-       int error = 0;
-
-       if (pci_dev->driver) {
-               if (level == SUSPEND_SAVE_STATE && pci_dev->driver->save_state)
-                       error = pci_dev->driver->save_state(pci_dev,state);
-               else if (level == SUSPEND_POWER_DOWN && pci_dev->driver->suspend)
-                       error = pci_dev->driver->suspend(pci_dev,state);
-       }
-       return error;
-}
-
-static int pci_device_resume(struct device * dev, u32 level)
-{
-       struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
-
-       if (pci_dev->driver) {
-               if (level == RESUME_POWER_ON && pci_dev->driver->resume)
-                       pci_dev->driver->resume(pci_dev);
-       }
-       return 0;
-}
-
-struct device_driver pci_device_driver = {
-       suspend:        pci_device_suspend,
-       resume:         pci_device_resume,
-};
-
 struct bus_type pci_bus_type = {
        name:   "pci",
 };
index a105a7b862a2b23ef340738d3e7b6bbd0e4b8da1..01db47dc97bf50bcde07c6b5d55448f716f031e8 100644 (file)
@@ -18,8 +18,6 @@
 LIST_HEAD(pci_root_buses);
 LIST_HEAD(pci_devices);
 
-extern struct device_driver pci_device_driver;
-
 /*
  * Translate the low bits of the PCI base
  * to the resource type
@@ -512,7 +510,6 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
        dev0.bus = bus;
        dev0.sysdata = bus->sysdata;
        dev0.dev.parent = bus->dev;
-       dev0.dev.driver = &pci_device_driver;
        dev0.dev.bus = &pci_bus_type;
 
        /* Go find them, Rover! */
index f6e3a68a2a0de0b39d4ed420912a34264dc1a38b..7cbc68fdb743bbceb942913229877d5d8778f15a 100644 (file)
@@ -487,6 +487,8 @@ struct pci_driver {
        int  (*suspend) (struct pci_dev *dev, u32 state);       /* Device suspended */
        int  (*resume) (struct pci_dev *dev);                   /* Device woken up */
        int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
+
+       struct device_driver    driver;
 };