bk://kernel.bkbits.net/gregkh/linux/driver-2.6 dtor_core@ameritech.net|ChangeSet|20040708234647|23132 dtor_core # This is a BitKeeper generated diff -Nru style patch. # # drivers/pci/hotplug/rpaphp_vio.c # 2004/07/07 17:55:49-07:00 dtor_core@ameritech.net +8 -1 # Driver core: kset_find_obj should increment refcount of the found object # # lib/kobject.c # 2004/07/07 17:55:49-07:00 dtor_core@ameritech.net +4 -3 # Driver core: kset_find_obj should increment refcount of the found object # # ChangeSet # 2004/07/08 16:46:47-07:00 dtor_core@ameritech.net # [PATCH] Driver core: add driver_find helper to find a driver by its name # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # include/linux/device.h # 2004/07/07 17:56:21-07:00 dtor_core@ameritech.net +1 -0 # Driver core: add driver_find helper to find a driver by its name # # drivers/base/driver.c # 2004/07/07 17:56:21-07:00 dtor_core@ameritech.net +19 -0 # Driver core: add driver_find helper to find a driver by its name # # ChangeSet # 2004/07/08 16:46:10-07:00 dtor_core@ameritech.net # [PATCH] Driver core: kset_find_obj should increment refcount of the found object # # kset_find_obj should increment refcount of the found object so users of # the function can safely use returned object # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # drivers/base/core.c # 2004/07/07 17:55:49-07:00 dtor_core@ameritech.net +10 -0 # Driver core: kset_find_obj should increment refcount of the found object # # drivers/base/bus.c # 2004/07/07 17:55:49-07:00 dtor_core@ameritech.net +2 -0 # Driver core: kset_find_obj should increment refcount of the found object # # ChangeSet # 2004/07/08 16:41:56-07:00 dtor_core@ameritech.net # [PATCH] Driver core: add default driver attributes to struct bus_type # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # include/linux/device.h # 2004/07/07 16:56:42-07:00 dtor_core@ameritech.net +1 -0 # Driver core: add default driver attributes to struct bus_type # # drivers/base/bus.c # 2004/07/07 16:56:42-07:00 dtor_core@ameritech.net +35 -2 # Driver core: add default driver attributes to struct bus_type # # ChangeSet # 2004/07/08 16:40:09-07:00 dtor_core@ameritech.net # [PATCH] Driver core: add platform_device_register_simple to register platform # # Add platform_device_register_simple to register platform devices # requiring minimal resource and memory management. The device # will have standard release function that just frees memory # occupied by the platform device. By having release function in # the driver core modules using such devices can be unloaded # without waiting for the last reference to the device to be # dropped. # # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Greg Kroah-Hartman # # include/linux/device.h # 2004/07/07 16:28:03-07:00 dtor_core@ameritech.net +2 -0 # Driver core: add platform_device_register_simple to register platform # # drivers/base/platform.c # 2004/07/07 16:28:03-07:00 dtor_core@ameritech.net +68 -0 # Driver core: add platform_device_register_simple to register platform # # ChangeSet # 2004/06/30 09:59:10-07:00 greg@kroah.com # Driver Core: remove extra space in Kconfig file. # # Signed-off-by: Greg Kroah-Hartman # # drivers/base/Kconfig # 2004/06/30 09:58:53-07:00 greg@kroah.com +1 -1 # Driver Core: remove extra space in Kconfig file. # # Signed-off-by: Greg Kroah-Hartman # # ChangeSet # 2004/06/22 16:24:54-07:00 akpm@osdl.org # [PATCH] raw.c cleanups # # - pass the raw_config_request by reference, not by value. # # - fix whitespace drainbamage # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # drivers/char/raw.c # 2004/06/22 08:01:30-07:00 akpm@osdl.org +8 -7 # raw.c cleanups # diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig --- a/drivers/base/Kconfig 2004-07-08 18:13:19 -07:00 +++ b/drivers/base/Kconfig 2004-07-08 18:13:19 -07:00 @@ -18,7 +18,7 @@ the kernel tree does. config DEBUG_DRIVER - bool "Driver Core verbose debug messages" + bool "Driver Core verbose debug messages" depends on DEBUG_KERNEL help Say Y here if you want the Driver core to produce a bunch of diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c --- a/drivers/base/bus.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/base/bus.c 2004-07-08 18:13:19 -07:00 @@ -415,7 +415,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) { int i; - + if (bus->dev_attrs) { for (i = 0; attr_name(bus->dev_attrs[i]); i++) device_remove_file(dev,&bus->dev_attrs[i]); @@ -471,6 +471,37 @@ } } +static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) +{ + int error = 0; + int i; + + if (bus->drv_attrs) { + for (i = 0; attr_name(bus->drv_attrs[i]); i++) { + error = driver_create_file(drv, &bus->drv_attrs[i]); + if (error) + goto Err; + } + } + Done: + return error; + Err: + while (--i >= 0) + driver_remove_file(drv, &bus->drv_attrs[i]); + goto Done; +} + + +static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv) +{ + int i; + + if (bus->drv_attrs) { + for (i = 0; attr_name(bus->drv_attrs[i]); i++) + driver_remove_file(drv, &bus->drv_attrs[i]); + } +} + /** * bus_add_driver - Add a driver to the bus. @@ -499,6 +530,7 @@ driver_attach(drv); up_write(&bus->subsys.rwsem); + driver_add_attrs(bus, drv); } return error; } @@ -516,6 +548,7 @@ void bus_remove_driver(struct device_driver * drv) { if (drv->bus) { + driver_remove_attrs(drv->bus, drv); down_write(&drv->bus->subsys.rwsem); pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); driver_detach(drv); @@ -574,6 +607,8 @@ * * Call kset_find_obj() to iterate over list of buses to * find a bus by name. Return bus if found. + * + * Note that kset_find_obj increments bus' reference count. */ struct bus_type * find_bus(char * name) @@ -610,7 +645,7 @@ static void bus_remove_attrs(struct bus_type * bus) { int i; - + if (bus->bus_attrs) { for (i = 0; attr_name(bus->bus_attrs[i]); i++) bus_remove_file(bus,&bus->bus_attrs[i]); diff -Nru a/drivers/base/core.c b/drivers/base/core.c --- a/drivers/base/core.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/base/core.c 2004-07-08 18:13:19 -07:00 @@ -378,6 +378,16 @@ return error; } +/** + * device_find - locate device on a bus by name. + * @name: name of the device. + * @bus: bus to scan for the device. + * + * Call kset_find_obj() to iterate over list of devices on + * a bus to find device by name. Return device if found. + * + * Note that kset_find_obj increments device's reference count. + */ struct device *device_find(const char *name, struct bus_type *bus) { struct kobject *k = kset_find_obj(&bus->devices, name); diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c --- a/drivers/base/driver.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/base/driver.c 2004-07-08 18:13:19 -07:00 @@ -111,10 +111,29 @@ up(&drv->unload_sem); } +/** + * driver_find - locate driver on a bus by its name. + * @name: name of the driver. + * @bus: bus to scan for the driver. + * + * Call kset_find_obj() to iterate over list of drivers on + * a bus to find driver by name. Return driver if found. + * + * Note that kset_find_obj increments driver's reference count. + */ +struct device_driver *driver_find(const char *name, struct bus_type *bus) +{ + struct kobject *k = kset_find_obj(&bus->drivers, name); + if (k) + return to_drv(k); + return NULL; +} + EXPORT_SYMBOL(driver_register); EXPORT_SYMBOL(driver_unregister); EXPORT_SYMBOL(get_driver); EXPORT_SYMBOL(put_driver); +EXPORT_SYMBOL(driver_find); EXPORT_SYMBOL(driver_create_file); EXPORT_SYMBOL(driver_remove_file); diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c --- a/drivers/base/platform.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/base/platform.c 2004-07-08 18:13:19 -07:00 @@ -15,6 +15,7 @@ #include #include #include +#include struct device platform_bus = { .bus_id = "platform", @@ -133,6 +134,13 @@ return ret; } +/** + * platform_device_unregister - remove a platform-level device + * @dev: platform device we're removing + * + * Note that this function will also release all memory- and port-based + * resources owned by the device (@dev->resource). + */ void platform_device_unregister(struct platform_device * pdev) { int i; @@ -148,6 +156,65 @@ } } +struct platform_object { + struct platform_device pdev; + struct resource resources[0]; +}; + +static void platform_device_release_simple(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + kfree(container_of(pdev, struct platform_object, pdev)); +} + +/** + * platform_device_register_simple + * @name: base name of the device we're adding + * @id: instance id + * @res: set of resources that needs to be allocated for the device + * @num: number of resources + * + * This function creates a simple platform device that requires minimal + * resource and memory management. Canned release function freeing + * memory allocated for the device allows drivers using such devices + * to be unloaded iwithout waiting for the last reference to the device + * to be dropped. + */ +struct platform_device *platform_device_register_simple(char *name, unsigned int id, + struct resource *res, unsigned int num) +{ + struct platform_object *pobj; + int retval; + + pobj = kmalloc(sizeof(struct platform_object) + sizeof(struct resource) * num, GFP_KERNEL); + if (!pobj) { + retval = -ENOMEM; + goto error; + } + + memset(pobj, 0, sizeof(*pobj)); + pobj->pdev.name = name; + pobj->pdev.id = id; + pobj->pdev.dev.release = platform_device_release_simple; + + if (num) { + memcpy(pobj->resources, res, sizeof(struct resource) * num); + pobj->pdev.resource = pobj->resources; + pobj->pdev.num_resources = num; + } + + retval = platform_device_register(&pobj->pdev); + if (retval) + goto error; + + return &pobj->pdev; + +error: + kfree(pobj); + return ERR_PTR(retval); +} + /** * platform_match - bind platform device to platform driver. @@ -237,6 +304,7 @@ EXPORT_SYMBOL(platform_bus); EXPORT_SYMBOL(platform_bus_type); EXPORT_SYMBOL(platform_device_register); +EXPORT_SYMBOL(platform_device_register_simple); EXPORT_SYMBOL(platform_device_unregister); EXPORT_SYMBOL(platform_get_irq); EXPORT_SYMBOL(platform_get_resource); diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c --- a/drivers/char/raw.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/char/raw.c 2004-07-08 18:13:19 -07:00 @@ -125,11 +125,11 @@ return ioctl_by_bdev(bdev, command, arg); } -static void bind_device(struct raw_config_request rq) +static void bind_device(struct raw_config_request *rq) { - class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor)); - class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq.raw_minor), - NULL, "raw%d", rq.raw_minor); + class_simple_device_remove(MKDEV(RAW_MAJOR, rq->raw_minor)); + class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor), + NULL, "raw%d", rq->raw_minor); } /* @@ -200,15 +200,16 @@ if (rq.block_major == 0 && rq.block_minor == 0) { /* unbind */ rawdev->binding = NULL; - class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor)); + class_simple_device_remove(MKDEV(RAW_MAJOR, + rq.raw_minor)); } else { rawdev->binding = bdget(dev); if (rawdev->binding == NULL) err = -ENOMEM; else { __module_get(THIS_MODULE); - bind_device(rq); - } + bind_device(&rq); + } } up(&raw_mutex); } else { diff -Nru a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c --- a/drivers/pci/hotplug/rpaphp_vio.c 2004-07-08 18:13:19 -07:00 +++ b/drivers/pci/hotplug/rpaphp_vio.c 2004-07-08 18:13:19 -07:00 @@ -86,7 +86,14 @@ } slot->dev_type = VIO_DEV; slot->dev.vio_dev = vio_find_node(dn); - if (!slot->dev.vio_dev) + if (slot->dev.vio_dev) { + /* + * rpaphp is the only owner of vio devices and + * does not need extra reference taken by + * vio_find_node + */ + put_device(&slot->dev.vio_dev->dev); + } else slot->dev.vio_dev = vio_register_device_node(dn); if (slot->dev.vio_dev) slot->state = CONFIGURED; diff -Nru a/include/linux/device.h b/include/linux/device.h --- a/include/linux/device.h 2004-07-08 18:13:19 -07:00 +++ b/include/linux/device.h 2004-07-08 18:13:19 -07:00 @@ -56,6 +56,7 @@ struct bus_attribute * bus_attrs; struct device_attribute * dev_attrs; + struct driver_attribute * drv_attrs; int (*match)(struct device * dev, struct device_driver * drv); struct device * (*add) (struct device * parent, char * bus_id); @@ -119,6 +120,7 @@ extern struct device_driver * get_driver(struct device_driver * drv); extern void put_driver(struct device_driver * drv); +extern struct device_driver *driver_find(const char *name, struct bus_type *bus); /* driverfs interface for exporting driver attributes */ @@ -380,6 +382,8 @@ extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); extern int platform_get_irq(struct platform_device *, unsigned int); extern int platform_add_devices(struct platform_device **, int); + +extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int); /* drivers/base/power.c */ extern void device_shutdown(void); diff -Nru a/lib/kobject.c b/lib/kobject.c --- a/lib/kobject.c 2004-07-08 18:13:19 -07:00 +++ b/lib/kobject.c 2004-07-08 18:13:19 -07:00 @@ -537,7 +537,8 @@ * @name: object's name. * * Lock kset via @kset->subsys, and iterate over @kset->list, - * looking for a matching kobject. Return object if found. + * looking for a matching kobject. If matching object is found + * take a reference and return the object. */ struct kobject * kset_find_obj(struct kset * kset, const char * name) @@ -548,8 +549,8 @@ down_read(&kset->subsys->rwsem); list_for_each(entry,&kset->list) { struct kobject * k = to_kobj(entry); - if (kobject_name(k) && (!strcmp(kobject_name(k),name))) { - ret = k; + if (kobject_name(k) && !strcmp(kobject_name(k),name)) { + ret = kobject_get(k); break; } }