Subject: driver core: move stuff out of device into a private structure --- drivers/base/base.h | 8 ++++++++ drivers/base/bus.c | 29 ++++++++++++++++++++++------- drivers/base/core.c | 43 ++++++++++++++++++++++++++++++------------- drivers/base/dd.c | 13 ++++++++----- drivers/base/driver.c | 13 ++++++++++--- include/linux/device.h | 7 +++---- 6 files changed, 81 insertions(+), 32 deletions(-) --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -36,6 +36,14 @@ struct driver_private { }; #define to_driver(obj) container_of(obj, struct driver_private, kobj) +struct device_private { + struct klist klist_children; + struct klist_node knode_parent; /* node in sibling list */ + struct klist_node knode_driver; + struct klist_node knode_bus; + struct device *device; +}; + /* initialisation functions */ extern int devices_init(void); extern int buses_init(void); --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -253,9 +253,17 @@ static ssize_t store_drivers_probe(struc static struct device *next_device(struct klist_iter *i) { struct klist_node *n = klist_next(i); - return n ? container_of(n, struct device, knode_bus) : NULL; + struct device_private *dev_prv; + struct device *dev = NULL; + + if (n) { + dev_prv = container_of(n, struct device_private, knode_bus); + dev = dev_prv->device; + } + return dev; } + /** * bus_for_each_dev - device iterator. * @bus: bus type. @@ -286,7 +294,7 @@ int bus_for_each_dev(struct bus_type *bu return -EINVAL; klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->knode_bus : NULL)); + (start ? &start->p->knode_bus : NULL)); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); @@ -320,7 +328,7 @@ struct device *bus_find_device(struct bu return NULL; klist_iter_init_node(&bus->p->klist_devices, &i, - (start ? &start->knode_bus : NULL)); + (start ? &start->p->knode_bus : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; @@ -510,7 +518,8 @@ void bus_attach_device(struct device *de ret = device_attach(dev); WARN_ON(ret < 0); if (ret >= 0) - klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); + klist_add_tail(&dev->p->knode_bus, + &bus->p->klist_devices); else dev->is_registered = 0; } @@ -535,7 +544,7 @@ void bus_remove_device(struct device *de device_remove_attrs(dev->bus, dev); if (dev->is_registered) { dev->is_registered = 0; - klist_del(&dev->knode_bus); + klist_del(&dev->p->knode_bus); } pr_debug("bus: '%s': remove device %s\n", dev->bus->name, dev->bus_id); @@ -836,15 +845,21 @@ static void bus_remove_attrs(struct bus_ static void klist_devices_get(struct klist_node *n) { - struct device *dev = container_of(n, struct device, knode_bus); + struct device_private *dev_prv; + struct device *dev; + dev_prv = container_of(n, struct device_private, knode_bus); + dev = dev_prv->device; get_device(dev); } static void klist_devices_put(struct klist_node *n) { - struct device *dev = container_of(n, struct device, knode_bus); + struct device_private *dev_prv; + struct device *dev; + dev_prv = container_of(n, struct device_private, knode_bus); + dev = dev_prv->device; put_device(dev); } --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -501,15 +501,21 @@ EXPORT_SYMBOL_GPL(device_schedule_callba static void klist_children_get(struct klist_node *n) { - struct device *dev = container_of(n, struct device, knode_parent); + struct device_private *dev_prv; + struct device *dev; + dev_prv = container_of(n, struct device_private, knode_parent); + dev = dev_prv->device; get_device(dev); } static void klist_children_put(struct klist_node *n) { - struct device *dev = container_of(n, struct device, knode_parent); + struct device_private *dev_prv; + struct device *dev; + dev_prv = container_of(n, struct device_private, knode_parent); + dev = dev_prv->device; put_device(dev); } @@ -527,7 +533,7 @@ void device_initialize(struct device *de { dev->kobj.kset = devices_kset; kobject_init(&dev->kobj, &device_ktype); - klist_init(&dev->klist_children, klist_children_get, + klist_init(&dev->p->klist_children, klist_children_get, klist_children_put); INIT_LIST_HEAD(&dev->dma_pools); INIT_LIST_HEAD(&dev->node); @@ -829,7 +835,8 @@ int device_add(struct device *dev) kobject_uevent(&dev->kobj, KOBJ_ADD); bus_attach_device(dev); if (parent) - klist_add_tail(&dev->knode_parent, &parent->klist_children); + klist_add_tail(&dev->p->knode_parent, + &parent->p->klist_children); if (dev->class) { down(&dev->class->sem); @@ -932,7 +939,7 @@ void device_del(struct device *dev) device_pm_remove(dev); if (parent) - klist_del(&dev->knode_parent); + klist_del(&dev->p->knode_parent); if (MAJOR(dev->devt)) device_remove_file(dev, &devt_attr); if (dev->class) { @@ -993,7 +1000,14 @@ void device_unregister(struct device *de static struct device *next_device(struct klist_iter *i) { struct klist_node *n = klist_next(i); - return n ? container_of(n, struct device, knode_parent) : NULL; + struct device_private *dev_prv; + struct device *dev = NULL; + + if (n) { + dev_prv = container_of(n, struct device_private, knode_parent); + dev = dev_prv->device; + } + return dev; } /** @@ -1015,7 +1029,7 @@ int device_for_each_child(struct device struct device *child; int error = 0; - klist_iter_init(&parent->klist_children, &i); + klist_iter_init(&parent->p->klist_children, &i); while ((child = next_device(&i)) && !error) error = fn(child, data); klist_iter_exit(&i); @@ -1046,7 +1060,7 @@ struct device *device_find_child(struct if (!parent) return NULL; - klist_iter_init(&parent->klist_children, &i); + klist_iter_init(&parent->p->klist_children, &i); while ((child = next_device(&i))) if (match(child, data) && get_device(child)) break; @@ -1320,6 +1334,7 @@ int device_move(struct device *dev, stru int error; struct device *old_parent; struct kobject *new_parent_kobj; + struct device_private *dev_prv; dev = get_device(dev); if (!dev) @@ -1338,10 +1353,12 @@ int device_move(struct device *dev, stru } old_parent = dev->parent; dev->parent = new_parent; + dev_prv = dev->p; if (old_parent) - klist_remove(&dev->knode_parent); + klist_remove(&dev_prv->knode_parent); if (new_parent) - klist_add_tail(&dev->knode_parent, &new_parent->klist_children); + klist_add_tail(&dev_prv->knode_parent, + &new_parent->p->klist_children); if (!dev->class) goto out_put; error = device_move_class_links(dev, old_parent, new_parent); @@ -1350,10 +1367,10 @@ int device_move(struct device *dev, stru device_move_class_links(dev, new_parent, old_parent); if (!kobject_move(&dev->kobj, &old_parent->kobj)) { if (new_parent) - klist_remove(&dev->knode_parent); + klist_remove(&dev_prv->knode_parent); if (old_parent) - klist_add_tail(&dev->knode_parent, - &old_parent->klist_children); + klist_add_tail(&dev_prv->knode_parent, + &old_parent->p->klist_children); } cleanup_glue_dir(dev, new_parent_kobj); put_device(new_parent); --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -28,7 +28,7 @@ static void driver_bound(struct device *dev) { - if (klist_node_attached(&dev->knode_driver)) { + if (klist_node_attached(&dev->p->knode_driver)) { printk(KERN_WARNING "%s: device %s already bound\n", __FUNCTION__, kobject_name(&dev->kobj)); return; @@ -41,7 +41,7 @@ static void driver_bound(struct device * blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_BOUND_DRIVER, dev); - klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); + klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); } static int driver_sysfs_add(struct device *dev) @@ -308,7 +308,7 @@ static void __device_release_driver(stru drv->remove(dev); devres_release_all(dev); dev->driver = NULL; - klist_remove(&dev->knode_driver); + klist_remove(&dev->p->knode_driver); } } @@ -338,6 +338,7 @@ EXPORT_SYMBOL_GPL(device_release_driver) */ void driver_detach(struct device_driver *drv) { + struct device_private *dev_prv; struct device *dev; for (;;) { @@ -346,8 +347,10 @@ void driver_detach(struct device_driver spin_unlock(&drv->p->klist_devices.k_lock); break; } - dev = list_entry(drv->p->klist_devices.k_list.prev, - struct device, knode_driver.n_node); + dev_prv = list_entry(drv->p->klist_devices.k_list.prev, + struct device_private, + knode_driver.n_node); + dev = dev_prv->device; get_device(dev); spin_unlock(&drv->p->klist_devices.k_lock); --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -22,7 +22,14 @@ static struct device *next_device(struct klist_iter *i) { struct klist_node *n = klist_next(i); - return n ? container_of(n, struct device, knode_driver) : NULL; + struct device_private *dev_prv; + struct device *dev = NULL; + + if (n) { + dev_prv = container_of(n, struct device_private, knode_driver); + dev = dev_prv->device; + } + return dev; } /** @@ -45,7 +52,7 @@ int driver_for_each_device(struct device return -EINVAL; klist_iter_init_node(&drv->p->klist_devices, &i, - start ? &start->knode_driver : NULL); + start ? &start->p->knode_driver : NULL); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); @@ -79,7 +86,7 @@ struct device *driver_find_device(struct return NULL; klist_iter_init_node(&drv->p->klist_devices, &i, - (start ? &start->knode_driver : NULL)); + (start ? &start->p->knode_driver : NULL)); while ((dev = next_device(&i))) if (match(dev, data) && get_device(dev)) break; --- a/include/linux/device.h +++ b/include/linux/device.h @@ -32,6 +32,7 @@ struct device; +struct device_private; struct device_driver; struct driver_private; struct class; @@ -420,12 +421,10 @@ struct device_dma_parameters { }; struct device { - struct klist klist_children; - struct klist_node knode_parent; /* node in sibling list */ - struct klist_node knode_driver; - struct klist_node knode_bus; struct device *parent; + struct device_private *p; + struct kobject kobj; char bus_id[BUS_ID_SIZE]; /* position on parent bus */ struct device_type *type;