From 16dc42e018c2868211b4928f20a957c0c216126c Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Sat, 26 Apr 2008 19:52:35 +0400 Subject: driver core: warn about duplicate driver names on the same bus Currently an attempt to register multiple drivers with the same name causes the stack trace with some cryptic error message. The attached patch adds the necessary check and the clear error message. Signed-off-by: Stas Sergeev Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 9a6537f1440..2ef5acf4368 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -217,12 +217,22 @@ static void driver_remove_groups(struct device_driver *drv, int driver_register(struct device_driver *drv) { int ret; + struct device_driver *other; if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) printk(KERN_WARNING "Driver '%s' needs updating - please use " "bus_type methods\n", drv->name); + + other = driver_find(drv->name, drv->bus); + if (other) { + put_driver(other); + printk(KERN_ERR "Error: Driver '%s' is already registered, " + "aborting...\n", drv->name); + return -EEXIST; + } + ret = bus_add_driver(drv); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 4356d73d028ad0726cfaf31ad30c5d28fcd98795 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 28 Apr 2008 01:03:20 -0700 Subject: pcmcia: remove pccard_sysfs_interface warnings Make the PCMCIA core stop using class_interface to hide socket attribute registration. This removes the associated section mismatch warnings, and helps get to the point where that mechanism can finally be removed. Simplify that attribute registration by using an attribute_group. This is a net shrink in object size. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/cs.c | 13 +++++------ drivers/pcmcia/cs_internal.h | 3 ++- drivers/pcmcia/socket_sysfs.c | 52 +++++++++++++++++-------------------------- 3 files changed, 28 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 56230dbd347..29276bd2829 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -652,6 +652,9 @@ static int pccardd(void *__skt) complete(&skt->thread_done); return 0; } + ret = pccard_sysfs_add_socket(&skt->dev); + if (ret) + dev_warn(&skt->dev, "err %d adding socket attributes\n", ret); add_wait_queue(&skt->thread_wait, &wait); complete(&skt->thread_done); @@ -694,6 +697,7 @@ static int pccardd(void *__skt) remove_wait_queue(&skt->thread_wait, &wait); /* remove from the device core */ + pccard_sysfs_remove_socket(&skt->dev); device_unregister(&skt->dev); return 0; @@ -940,20 +944,13 @@ EXPORT_SYMBOL(pcmcia_socket_class); static int __init init_pcmcia_cs(void) { - int ret; - init_completion(&pcmcia_unload); - ret = class_register(&pcmcia_socket_class); - if (ret) - return (ret); - return class_interface_register(&pccard_sysfs_interface); + return class_register(&pcmcia_socket_class); } static void __exit exit_pcmcia_cs(void) { - class_interface_unregister(&pccard_sysfs_interface); class_unregister(&pcmcia_socket_class); - wait_for_completion(&pcmcia_unload); } diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 9fa207e3c7b..e7d5d141f24 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -121,7 +121,8 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, void release_resource_db(struct pcmcia_socket *s); /* In socket_sysfs.c */ -extern struct class_interface pccard_sysfs_interface; +extern int pccard_sysfs_add_socket(struct device *dev); +extern void pccard_sysfs_remove_socket(struct device *dev); /* In cs.c */ extern struct rw_semaphore pcmcia_socket_list_rwsem; diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index b4409002b7f..562384d6f32 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -356,19 +356,23 @@ static ssize_t pccard_store_cis(struct kobject *kobj, } -static struct device_attribute *pccard_socket_attributes[] = { - &dev_attr_card_type, - &dev_attr_card_voltage, - &dev_attr_card_vpp, - &dev_attr_card_vcc, - &dev_attr_card_insert, - &dev_attr_card_pm_state, - &dev_attr_card_eject, - &dev_attr_card_irq_mask, - &dev_attr_available_resources_setup_done, +static struct attribute *pccard_socket_attributes[] = { + &dev_attr_card_type.attr, + &dev_attr_card_voltage.attr, + &dev_attr_card_vpp.attr, + &dev_attr_card_vcc.attr, + &dev_attr_card_insert.attr, + &dev_attr_card_pm_state.attr, + &dev_attr_card_eject.attr, + &dev_attr_card_irq_mask.attr, + &dev_attr_available_resources_setup_done.attr, NULL, }; +static const struct attribute_group socket_attrs = { + .attrs = pccard_socket_attributes, +}; + static struct bin_attribute pccard_cis_attr = { .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR }, .size = 0x200, @@ -376,35 +380,21 @@ static struct bin_attribute pccard_cis_attr = { .write = pccard_store_cis, }; -static int __devinit pccard_sysfs_add_socket(struct device *dev, - struct class_interface *class_intf) +int pccard_sysfs_add_socket(struct device *dev) { - struct device_attribute **attr; int ret = 0; - for (attr = pccard_socket_attributes; *attr; attr++) { - ret = device_create_file(dev, *attr); + ret = sysfs_create_group(&dev->kobj, &socket_attrs); + if (!ret) { + ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr); if (ret) - break; + sysfs_remove_group(&dev->kobj, &socket_attrs); } - if (!ret) - ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr); - return ret; } -static void __devexit pccard_sysfs_remove_socket(struct device *dev, - struct class_interface *class_intf) +void pccard_sysfs_remove_socket(struct device *dev) { - struct device_attribute **attr; - sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr); - for (attr = pccard_socket_attributes; *attr; attr++) - device_remove_file(dev, *attr); + sysfs_remove_group(&dev->kobj, &socket_attrs); } - -struct class_interface pccard_sysfs_interface = { - .class = &pcmcia_socket_class, - .add_dev = &pccard_sysfs_add_socket, - .remove_dev = __devexit_p(&pccard_sysfs_remove_socket), -}; -- cgit v1.2.3-70-g09d2 From c3b19ff06e0808555403491d61e8f0cbbb53e933 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 12 Mar 2008 20:47:35 +0100 Subject: driver core: remove no longer used "struct class_device" Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 11 - drivers/base/class.c | 638 +------------------------------------------------ include/linux/device.h | 97 -------- 3 files changed, 1 insertion(+), 745 deletions(-) (limited to 'drivers') diff --git a/drivers/base/base.h b/drivers/base/base.h index c0444146c09..2c9ae43e221 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -64,17 +64,6 @@ extern void sysdev_shutdown(void); extern int sysdev_suspend(pm_message_t state); extern int sysdev_resume(void); -static inline struct class_device *to_class_dev(struct kobject *obj) -{ - return container_of(obj, struct class_device, kobj); -} - -static inline -struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) -{ - return container_of(_attr, struct class_device_attribute, attr); -} - extern char *make_class_name(const char *name, struct kobject *kobj); extern int devres_release_all(struct device *dev); diff --git a/drivers/base/class.c b/drivers/base/class.c index b4901799308..0ef00e8d415 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -179,27 +179,13 @@ static void class_create_release(struct class *cls) kfree(cls); } -static void class_device_create_release(struct class_device *class_dev) -{ - pr_debug("%s called for %s\n", __func__, class_dev->class_id); - kfree(class_dev); -} - -/* needed to allow these devices to have parent class devices */ -static int class_device_create_uevent(struct class_device *class_dev, - struct kobj_uevent_env *env) -{ - pr_debug("%s called for %s\n", __func__, class_dev->class_id); - return 0; -} - /** * class_create - create a struct class structure * @owner: pointer to the module that is to "own" this struct class * @name: pointer to a string for the name of this class. * * This is used to create a struct class pointer that can then be used - * in calls to class_device_create(). + * in calls to device_create(). * * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). @@ -218,7 +204,6 @@ struct class *class_create(struct module *owner, const char *name) cls->name = name; cls->owner = owner; cls->class_release = class_create_release; - cls->release = class_device_create_release; retval = class_register(cls); if (retval) @@ -246,113 +231,6 @@ void class_destroy(struct class *cls) class_unregister(cls); } -/* Class Device Stuff */ - -int class_device_create_file(struct class_device *class_dev, - const struct class_device_attribute *attr) -{ - int error = -EINVAL; - if (class_dev) - error = sysfs_create_file(&class_dev->kobj, &attr->attr); - return error; -} - -void class_device_remove_file(struct class_device *class_dev, - const struct class_device_attribute *attr) -{ - if (class_dev) - sysfs_remove_file(&class_dev->kobj, &attr->attr); -} - -int class_device_create_bin_file(struct class_device *class_dev, - struct bin_attribute *attr) -{ - int error = -EINVAL; - if (class_dev) - error = sysfs_create_bin_file(&class_dev->kobj, attr); - return error; -} - -void class_device_remove_bin_file(struct class_device *class_dev, - struct bin_attribute *attr) -{ - if (class_dev) - sysfs_remove_bin_file(&class_dev->kobj, attr); -} - -static ssize_t class_device_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); - struct class_device *cd = to_class_dev(kobj); - ssize_t ret = 0; - - if (class_dev_attr->show) - ret = class_dev_attr->show(cd, buf); - return ret; -} - -static ssize_t class_device_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, size_t count) -{ - struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); - struct class_device *cd = to_class_dev(kobj); - ssize_t ret = 0; - - if (class_dev_attr->store) - ret = class_dev_attr->store(cd, buf, count); - return ret; -} - -static struct sysfs_ops class_dev_sysfs_ops = { - .show = class_device_attr_show, - .store = class_device_attr_store, -}; - -static void class_dev_release(struct kobject *kobj) -{ - struct class_device *cd = to_class_dev(kobj); - struct class *cls = cd->class; - - pr_debug("device class '%s': release.\n", cd->class_id); - - if (cd->release) - cd->release(cd); - else if (cls->release) - cls->release(cd); - else { - printk(KERN_ERR "Class Device '%s' does not have a release() " - "function, it is broken and must be fixed.\n", - cd->class_id); - WARN_ON(1); - } -} - -static struct kobj_type class_device_ktype = { - .sysfs_ops = &class_dev_sysfs_ops, - .release = class_dev_release, -}; - -static int class_uevent_filter(struct kset *kset, struct kobject *kobj) -{ - struct kobj_type *ktype = get_ktype(kobj); - - if (ktype == &class_device_ktype) { - struct class_device *class_dev = to_class_dev(kobj); - if (class_dev->class) - return 1; - } - return 0; -} - -static const char *class_uevent_name(struct kset *kset, struct kobject *kobj) -{ - struct class_device *class_dev = to_class_dev(kobj); - - return class_dev->class->name; -} - #ifdef CONFIG_SYSFS_DEPRECATED char *make_class_name(const char *name, struct kobject *kobj) { @@ -370,445 +248,8 @@ char *make_class_name(const char *name, struct kobject *kobj) strcat(class_name, kobject_name(kobj)); return class_name; } - -static int make_deprecated_class_device_links(struct class_device *class_dev) -{ - char *class_name; - int error; - - if (!class_dev->dev) - return 0; - - class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - if (class_name) - error = sysfs_create_link(&class_dev->dev->kobj, - &class_dev->kobj, class_name); - else - error = -ENOMEM; - kfree(class_name); - return error; -} - -static void remove_deprecated_class_device_links(struct class_device *class_dev) -{ - char *class_name; - - if (!class_dev->dev) - return; - - class_name = make_class_name(class_dev->class->name, &class_dev->kobj); - if (class_name) - sysfs_remove_link(&class_dev->dev->kobj, class_name); - kfree(class_name); -} -#else -static inline int make_deprecated_class_device_links(struct class_device *cd) -{ return 0; } -static void remove_deprecated_class_device_links(struct class_device *cd) -{ } #endif -static int class_uevent(struct kset *kset, struct kobject *kobj, - struct kobj_uevent_env *env) -{ - struct class_device *class_dev = to_class_dev(kobj); - struct device *dev = class_dev->dev; - int retval = 0; - - pr_debug("%s - name = %s\n", __func__, class_dev->class_id); - - if (MAJOR(class_dev->devt)) { - add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt)); - - add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt)); - } - - if (dev) { - const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); - if (path) { - add_uevent_var(env, "PHYSDEVPATH=%s", path); - kfree(path); - } - - if (dev->bus) - add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); - - if (dev->driver) - add_uevent_var(env, "PHYSDEVDRIVER=%s", - dev->driver->name); - } - - if (class_dev->uevent) { - /* have the class device specific function add its stuff */ - retval = class_dev->uevent(class_dev, env); - if (retval) - pr_debug("class_dev->uevent() returned %d\n", retval); - } else if (class_dev->class->uevent) { - /* have the class specific function add its stuff */ - retval = class_dev->class->uevent(class_dev, env); - if (retval) - pr_debug("class->uevent() returned %d\n", retval); - } - - return retval; -} - -static struct kset_uevent_ops class_uevent_ops = { - .filter = class_uevent_filter, - .name = class_uevent_name, - .uevent = class_uevent, -}; - -/* - * DO NOT copy how this is created, kset_create_and_add() should be - * called, but this is a hold-over from the old-way and will be deleted - * entirely soon. - */ -static struct kset class_obj_subsys = { - .uevent_ops = &class_uevent_ops, -}; - -static int class_device_add_attrs(struct class_device *cd) -{ - int i; - int error = 0; - struct class *cls = cd->class; - - if (cls->class_dev_attrs) { - for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { - error = class_device_create_file(cd, - &cls->class_dev_attrs[i]); - if (error) - goto err; - } - } -done: - return error; -err: - while (--i >= 0) - class_device_remove_file(cd, &cls->class_dev_attrs[i]); - goto done; -} - -static void class_device_remove_attrs(struct class_device *cd) -{ - int i; - struct class *cls = cd->class; - - if (cls->class_dev_attrs) { - for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) - class_device_remove_file(cd, &cls->class_dev_attrs[i]); - } -} - -static int class_device_add_groups(struct class_device *cd) -{ - int i; - int error = 0; - - if (cd->groups) { - for (i = 0; cd->groups[i]; i++) { - error = sysfs_create_group(&cd->kobj, cd->groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&cd->kobj, - cd->groups[i]); - goto out; - } - } - } -out: - return error; -} - -static void class_device_remove_groups(struct class_device *cd) -{ - int i; - if (cd->groups) - for (i = 0; cd->groups[i]; i++) - sysfs_remove_group(&cd->kobj, cd->groups[i]); -} - -static ssize_t show_dev(struct class_device *class_dev, char *buf) -{ - return print_dev_t(buf, class_dev->devt); -} - -static struct class_device_attribute class_devt_attr = - __ATTR(dev, S_IRUGO, show_dev, NULL); - -static ssize_t store_uevent(struct class_device *class_dev, - const char *buf, size_t count) -{ - kobject_uevent(&class_dev->kobj, KOBJ_ADD); - return count; -} - -static struct class_device_attribute class_uevent_attr = - __ATTR(uevent, S_IWUSR, NULL, store_uevent); - -void class_device_initialize(struct class_device *class_dev) -{ - class_dev->kobj.kset = &class_obj_subsys; - kobject_init(&class_dev->kobj, &class_device_ktype); - INIT_LIST_HEAD(&class_dev->node); -} - -int class_device_add(struct class_device *class_dev) -{ - struct class *parent_class = NULL; - struct class_device *parent_class_dev = NULL; - struct class_interface *class_intf; - int error = -EINVAL; - - class_dev = class_device_get(class_dev); - if (!class_dev) - return -EINVAL; - - if (!strlen(class_dev->class_id)) - goto out1; - - parent_class = class_get(class_dev->class); - if (!parent_class) - goto out1; - - parent_class_dev = class_device_get(class_dev->parent); - - pr_debug("CLASS: registering class device: ID = '%s'\n", - class_dev->class_id); - - /* first, register with generic layer. */ - if (parent_class_dev) - class_dev->kobj.parent = &parent_class_dev->kobj; - else - class_dev->kobj.parent = &parent_class->subsys.kobj; - - error = kobject_add(&class_dev->kobj, class_dev->kobj.parent, - "%s", class_dev->class_id); - if (error) - goto out2; - - /* add the needed attributes to this device */ - error = sysfs_create_link(&class_dev->kobj, - &parent_class->subsys.kobj, "subsystem"); - if (error) - goto out3; - - error = class_device_create_file(class_dev, &class_uevent_attr); - if (error) - goto out3; - - if (MAJOR(class_dev->devt)) { - error = class_device_create_file(class_dev, &class_devt_attr); - if (error) - goto out4; - } - - error = class_device_add_attrs(class_dev); - if (error) - goto out5; - - if (class_dev->dev) { - error = sysfs_create_link(&class_dev->kobj, - &class_dev->dev->kobj, "device"); - if (error) - goto out6; - } - - error = class_device_add_groups(class_dev); - if (error) - goto out7; - - error = make_deprecated_class_device_links(class_dev); - if (error) - goto out8; - - kobject_uevent(&class_dev->kobj, KOBJ_ADD); - - /* notify any interfaces this device is now here */ - down(&parent_class->sem); - list_add_tail(&class_dev->node, &parent_class->children); - list_for_each_entry(class_intf, &parent_class->interfaces, node) { - if (class_intf->add) - class_intf->add(class_dev, class_intf); - } - up(&parent_class->sem); - - goto out1; - - out8: - class_device_remove_groups(class_dev); - out7: - if (class_dev->dev) - sysfs_remove_link(&class_dev->kobj, "device"); - out6: - class_device_remove_attrs(class_dev); - out5: - if (MAJOR(class_dev->devt)) - class_device_remove_file(class_dev, &class_devt_attr); - out4: - class_device_remove_file(class_dev, &class_uevent_attr); - out3: - kobject_del(&class_dev->kobj); - out2: - if (parent_class_dev) - class_device_put(parent_class_dev); - class_put(parent_class); - out1: - class_device_put(class_dev); - return error; -} - -int class_device_register(struct class_device *class_dev) -{ - class_device_initialize(class_dev); - return class_device_add(class_dev); -} - -/** - * class_device_create - creates a class device and registers it with sysfs - * @cls: pointer to the struct class that this device should be registered to. - * @parent: pointer to the parent struct class_device of this new device, if - * any. - * @devt: the dev_t for the char device to be added. - * @device: a pointer to a struct device that is assiociated with this class - * device. - * @fmt: string for the class device's name - * - * This function can be used by char device classes. A struct - * class_device will be created in sysfs, registered to the specified - * class. - * A "dev" file will be created, showing the dev_t for the device, if - * the dev_t is not 0,0. - * If a pointer to a parent struct class_device is passed in, the newly - * created struct class_device will be a child of that device in sysfs. - * The pointer to the struct class_device will be returned from the - * call. Any further sysfs files that might be required can be created - * using this pointer. - * - * Note: the struct class passed to this function must have previously - * been created with a call to class_create(). - */ -struct class_device *class_device_create(struct class *cls, - struct class_device *parent, - dev_t devt, - struct device *device, - const char *fmt, ...) -{ - va_list args; - struct class_device *class_dev = NULL; - int retval = -ENODEV; - - if (cls == NULL || IS_ERR(cls)) - goto error; - - class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL); - if (!class_dev) { - retval = -ENOMEM; - goto error; - } - - class_dev->devt = devt; - class_dev->dev = device; - class_dev->class = cls; - class_dev->parent = parent; - class_dev->release = class_device_create_release; - class_dev->uevent = class_device_create_uevent; - - va_start(args, fmt); - vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); - va_end(args); - retval = class_device_register(class_dev); - if (retval) - goto error; - - return class_dev; - -error: - kfree(class_dev); - return ERR_PTR(retval); -} - -void class_device_del(struct class_device *class_dev) -{ - struct class *parent_class = class_dev->class; - struct class_device *parent_device = class_dev->parent; - struct class_interface *class_intf; - - if (parent_class) { - down(&parent_class->sem); - list_del_init(&class_dev->node); - list_for_each_entry(class_intf, &parent_class->interfaces, node) - if (class_intf->remove) - class_intf->remove(class_dev, class_intf); - up(&parent_class->sem); - } - - if (class_dev->dev) { - remove_deprecated_class_device_links(class_dev); - sysfs_remove_link(&class_dev->kobj, "device"); - } - sysfs_remove_link(&class_dev->kobj, "subsystem"); - class_device_remove_file(class_dev, &class_uevent_attr); - if (MAJOR(class_dev->devt)) - class_device_remove_file(class_dev, &class_devt_attr); - class_device_remove_attrs(class_dev); - class_device_remove_groups(class_dev); - - kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); - kobject_del(&class_dev->kobj); - - class_device_put(parent_device); - class_put(parent_class); -} - -void class_device_unregister(struct class_device *class_dev) -{ - pr_debug("CLASS: Unregistering class device. ID = '%s'\n", - class_dev->class_id); - class_device_del(class_dev); - class_device_put(class_dev); -} - -/** - * class_device_destroy - removes a class device that was created with class_device_create() - * @cls: the pointer to the struct class that this device was registered * with. - * @devt: the dev_t of the device that was previously registered. - * - * This call unregisters and cleans up a class device that was created with a - * call to class_device_create() - */ -void class_device_destroy(struct class *cls, dev_t devt) -{ - struct class_device *class_dev = NULL; - struct class_device *class_dev_tmp; - - down(&cls->sem); - list_for_each_entry(class_dev_tmp, &cls->children, node) { - if (class_dev_tmp->devt == devt) { - class_dev = class_dev_tmp; - break; - } - } - up(&cls->sem); - - if (class_dev) - class_device_unregister(class_dev); -} - -struct class_device *class_device_get(struct class_device *class_dev) -{ - if (class_dev) - return to_class_dev(kobject_get(&class_dev->kobj)); - return NULL; -} - -void class_device_put(struct class_device *class_dev) -{ - if (class_dev) - kobject_put(&class_dev->kobj); -} - /** * class_for_each_device - device iterator * @class: the class we're iterating @@ -897,56 +338,9 @@ struct device *class_find_device(struct class *class, void *data, } EXPORT_SYMBOL_GPL(class_find_device); -/** - * class_find_child - device iterator for locating a particular class_device - * @class: the class we're iterating - * @data: data for the match function - * @match: function to check class_device - * - * This function returns a reference to a class_device that is 'found' for - * later use, as determined by the @match callback. - * - * The callback should return 0 if the class_device doesn't match and non-zero - * if it does. If the callback returns non-zero, this function will - * return to the caller and not iterate over any more class_devices. - * - * Note, you will need to drop the reference with class_device_put() after use. - * - * We hold class->sem in this function, so it can not be - * re-acquired in @match, otherwise it will self-deadlocking. For - * example, calls to add or remove class members would be verboten. - */ -struct class_device *class_find_child(struct class *class, void *data, - int (*match)(struct class_device *, void *)) -{ - struct class_device *dev; - int found = 0; - - if (!class) - return NULL; - - down(&class->sem); - list_for_each_entry(dev, &class->children, node) { - dev = class_device_get(dev); - if (dev) { - if (match(dev, data)) { - found = 1; - break; - } else - class_device_put(dev); - } else - break; - } - up(&class->sem); - - return found ? dev : NULL; -} -EXPORT_SYMBOL_GPL(class_find_child); - int class_interface_register(struct class_interface *class_intf) { struct class *parent; - struct class_device *class_dev; struct device *dev; if (!class_intf || !class_intf->class) @@ -958,10 +352,6 @@ int class_interface_register(struct class_interface *class_intf) down(&parent->sem); list_add_tail(&class_intf->node, &parent->interfaces); - if (class_intf->add) { - list_for_each_entry(class_dev, &parent->children, node) - class_intf->add(class_dev, class_intf); - } if (class_intf->add_dev) { list_for_each_entry(dev, &parent->devices, node) class_intf->add_dev(dev, class_intf); @@ -974,7 +364,6 @@ int class_interface_register(struct class_interface *class_intf) void class_interface_unregister(struct class_interface *class_intf) { struct class *parent = class_intf->class; - struct class_device *class_dev; struct device *dev; if (!parent) @@ -982,10 +371,6 @@ void class_interface_unregister(struct class_interface *class_intf) down(&parent->sem); list_del_init(&class_intf->node); - if (class_intf->remove) { - list_for_each_entry(class_dev, &parent->children, node) - class_intf->remove(class_dev, class_intf); - } if (class_intf->remove_dev) { list_for_each_entry(dev, &parent->devices, node) class_intf->remove_dev(dev, class_intf); @@ -1000,13 +385,6 @@ int __init classes_init(void) class_kset = kset_create_and_add("class", NULL, NULL); if (!class_kset) return -ENOMEM; - - /* ick, this is ugly, the things we go through to keep from showing up - * in sysfs... */ - kset_init(&class_obj_subsys); - kobject_set_name(&class_obj_subsys.kobj, "class_obj"); - if (!class_obj_subsys.kobj.parent) - class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; return 0; } @@ -1017,19 +395,5 @@ EXPORT_SYMBOL_GPL(class_unregister); EXPORT_SYMBOL_GPL(class_create); EXPORT_SYMBOL_GPL(class_destroy); -EXPORT_SYMBOL_GPL(class_device_register); -EXPORT_SYMBOL_GPL(class_device_unregister); -EXPORT_SYMBOL_GPL(class_device_initialize); -EXPORT_SYMBOL_GPL(class_device_add); -EXPORT_SYMBOL_GPL(class_device_del); -EXPORT_SYMBOL_GPL(class_device_get); -EXPORT_SYMBOL_GPL(class_device_put); -EXPORT_SYMBOL_GPL(class_device_create); -EXPORT_SYMBOL_GPL(class_device_destroy); -EXPORT_SYMBOL_GPL(class_device_create_file); -EXPORT_SYMBOL_GPL(class_device_remove_file); -EXPORT_SYMBOL_GPL(class_device_create_bin_file); -EXPORT_SYMBOL_GPL(class_device_remove_bin_file); - EXPORT_SYMBOL_GPL(class_interface_register); EXPORT_SYMBOL_GPL(class_interface_unregister); diff --git a/include/linux/device.h b/include/linux/device.h index 1a060265ace..832fb0eb293 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -35,7 +35,6 @@ struct device; struct device_driver; struct driver_private; struct class; -struct class_device; struct bus_type; struct bus_type_private; @@ -190,13 +189,10 @@ struct class { struct kset class_dirs; struct semaphore sem; /* locks children, devices, interfaces */ struct class_attribute *class_attrs; - struct class_device_attribute *class_dev_attrs; struct device_attribute *dev_attrs; - int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env); int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); - void (*release)(struct class_device *dev); void (*class_release)(struct class *class); void (*dev_release)(struct device *dev); @@ -210,9 +206,6 @@ extern int class_for_each_device(struct class *class, void *data, int (*fn)(struct device *dev, void *data)); extern struct device *class_find_device(struct class *class, void *data, int (*match)(struct device *, void *)); -extern struct class_device *class_find_child(struct class *class, void *data, - int (*match)(struct class_device *, void *)); - struct class_attribute { struct attribute attr; @@ -228,92 +221,10 @@ extern int __must_check class_create_file(struct class *class, extern void class_remove_file(struct class *class, const struct class_attribute *attr); -struct class_device_attribute { - struct attribute attr; - ssize_t (*show)(struct class_device *, char *buf); - ssize_t (*store)(struct class_device *, const char *buf, size_t count); -}; - -#define CLASS_DEVICE_ATTR(_name, _mode, _show, _store) \ -struct class_device_attribute class_device_attr_##_name = \ - __ATTR(_name, _mode, _show, _store) - -extern int __must_check class_device_create_file(struct class_device *, - const struct class_device_attribute *); - -/** - * struct class_device - class devices - * @class: pointer to the parent class for this class device. This is required. - * @devt: for internal use by the driver core only. - * @node: for internal use by the driver core only. - * @kobj: for internal use by the driver core only. - * @groups: optional additional groups to be created - * @dev: if set, a symlink to the struct device is created in the sysfs - * directory for this struct class device. - * @class_data: pointer to whatever you want to store here for this struct - * class_device. Use class_get_devdata() and class_set_devdata() to get and - * set this pointer. - * @parent: pointer to a struct class_device that is the parent of this struct - * class_device. If NULL, this class_device will show up at the root of the - * struct class in sysfs (which is probably what you want to have happen.) - * @release: pointer to a release function for this struct class_device. If - * set, this will be called instead of the class specific release function. - * Only use this if you want to override the default release function, like - * when you are nesting class_device structures. - * @uevent: pointer to a uevent function for this struct class_device. If - * set, this will be called instead of the class specific uevent function. - * Only use this if you want to override the default uevent function, like - * when you are nesting class_device structures. - */ -struct class_device { - struct list_head node; - - struct kobject kobj; - struct class *class; - dev_t devt; - struct device *dev; - void *class_data; - struct class_device *parent; - struct attribute_group **groups; - - void (*release)(struct class_device *dev); - int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env); - char class_id[BUS_ID_SIZE]; -}; - -static inline void *class_get_devdata(struct class_device *dev) -{ - return dev->class_data; -} - -static inline void class_set_devdata(struct class_device *dev, void *data) -{ - dev->class_data = data; -} - - -extern int __must_check class_device_register(struct class_device *); -extern void class_device_unregister(struct class_device *); -extern void class_device_initialize(struct class_device *); -extern int __must_check class_device_add(struct class_device *); -extern void class_device_del(struct class_device *); - -extern struct class_device *class_device_get(struct class_device *); -extern void class_device_put(struct class_device *); - -extern void class_device_remove_file(struct class_device *, - const struct class_device_attribute *); -extern int __must_check class_device_create_bin_file(struct class_device *, - struct bin_attribute *); -extern void class_device_remove_bin_file(struct class_device *, - struct bin_attribute *); - struct class_interface { struct list_head node; struct class *class; - int (*add) (struct class_device *, struct class_interface *); - void (*remove) (struct class_device *, struct class_interface *); int (*add_dev) (struct device *, struct class_interface *); void (*remove_dev) (struct device *, struct class_interface *); }; @@ -323,13 +234,6 @@ extern void class_interface_unregister(struct class_interface *); extern struct class *class_create(struct module *owner, const char *name); extern void class_destroy(struct class *cls); -extern struct class_device *class_device_create(struct class *cls, - struct class_device *parent, - dev_t devt, - struct device *device, - const char *fmt, ...) - __attribute__((format(printf, 5, 6))); -extern void class_device_destroy(struct class *cls, dev_t devt); /* * The type of device, "struct device" is embedded in. A class @@ -465,7 +369,6 @@ struct device { spinlock_t devres_lock; struct list_head devres_head; - /* class_device migration path */ struct list_head node; struct class *class; dev_t devt; /* dev_t, creates the sysfs "dev" */ -- cgit v1.2.3-70-g09d2