pr_debug("device class '%s': release.\n", cd->class_id);
- kfree(cd->devt_attr);
- cd->devt_attr = NULL;
-
if (cd->release)
cd->release(cd);
else if (cls->release)
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)
{
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)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
&parent_class->subsys.kobj, "subsystem");
if (error)
goto out3;
- class_dev->uevent_attr.attr.name = "uevent";
- class_dev->uevent_attr.attr.mode = S_IWUSR;
- class_dev->uevent_attr.store = store_uevent;
- error = class_device_create_file(class_dev, &class_dev->uevent_attr);
+
+ error = class_device_create_file(class_dev, &class_uevent_attr);
if (error)
goto out3;
if (MAJOR(class_dev->devt)) {
- struct class_device_attribute *attr;
- attr = kzalloc(sizeof(*attr), GFP_KERNEL);
- if (!attr) {
- error = -ENOMEM;
- goto out4;
- }
- attr->attr.name = "dev";
- attr->attr.mode = S_IRUGO;
- attr->show = show_dev;
- error = class_device_create_file(class_dev, attr);
- if (error) {
- kfree(attr);
+ error = class_device_create_file(class_dev, &class_devt_attr);
+ if (error)
goto out4;
- }
-
- class_dev->devt_attr = attr;
}
error = class_device_add_attrs(class_dev);
out6:
class_device_remove_attrs(class_dev);
out5:
- if (class_dev->devt_attr)
- class_device_remove_file(class_dev, class_dev->devt_attr);
+ if (MAJOR(class_dev->devt))
+ class_device_remove_file(class_dev, &class_devt_attr);
out4:
- class_device_remove_file(class_dev, &class_dev->uevent_attr);
+ class_device_remove_file(class_dev, &class_uevent_attr);
out3:
kobject_del(&class_dev->kobj);
out2:
sysfs_remove_link(&class_dev->kobj, "device");
}
sysfs_remove_link(&class_dev->kobj, "subsystem");
- class_device_remove_file(class_dev, &class_dev->uevent_attr);
- if (class_dev->devt_attr)
- class_device_remove_file(class_dev, class_dev->devt_attr);
+ 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);
return count;
}
+static struct device_attribute uevent_attr =
+ __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
+
static int device_add_attributes(struct device *dev,
struct device_attribute *attrs)
{
return print_dev_t(buf, dev->devt);
}
+static struct device_attribute devt_attr =
+ __ATTR(dev, S_IRUGO, show_dev, NULL);
+
/*
* devices_subsys - structure to be registered with kobject core.
*/
blocking_notifier_call_chain(&dev->bus->bus_notifier,
BUS_NOTIFY_ADD_DEVICE, dev);
- dev->uevent_attr.attr.name = "uevent";
- dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR;
- dev->uevent_attr.store = store_uevent;
- dev->uevent_attr.show = show_uevent;
- error = device_create_file(dev, &dev->uevent_attr);
+ error = device_create_file(dev, &uevent_attr);
if (error)
goto attrError;
if (MAJOR(dev->devt)) {
- struct device_attribute *attr;
- attr = kzalloc(sizeof(*attr), GFP_KERNEL);
- if (!attr) {
- error = -ENOMEM;
- goto ueventattrError;
- }
- attr->attr.name = "dev";
- attr->attr.mode = S_IRUGO;
- attr->show = show_dev;
- error = device_create_file(dev, attr);
- if (error) {
- kfree(attr);
+ error = device_create_file(dev, &devt_attr);
+ if (error)
goto ueventattrError;
- }
-
- dev->devt_attr = attr;
}
if (dev->class) {
BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_attrs(dev);
AttrsError:
- if (dev->devt_attr) {
- device_remove_file(dev, dev->devt_attr);
- kfree(dev->devt_attr);
- }
+ if (MAJOR(dev->devt))
+ device_remove_file(dev, &devt_attr);
if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem");
}
}
ueventattrError:
- device_remove_file(dev, &dev->uevent_attr);
+ device_remove_file(dev, &uevent_attr);
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
if (parent)
klist_del(&dev->knode_parent);
- if (dev->devt_attr) {
- device_remove_file(dev, dev->devt_attr);
- kfree(dev->devt_attr);
- }
+ if (MAJOR(dev->devt))
+ device_remove_file(dev, &devt_attr);
if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem");
/* If this is not a "fake" compatible device, remove the
up(&dev->class->sem);
}
}
- device_remove_file(dev, &dev->uevent_attr);
+ device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
bus_remove_device(dev);
* @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.
- * @devt_attr: 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.
struct kobject kobj;
struct class * class; /* required */
dev_t devt; /* dev_t, creates the sysfs "dev" */
- struct class_device_attribute *devt_attr;
- struct class_device_attribute uevent_attr;
struct device * dev; /* not necessary, but nice to have */
void * class_data; /* class-specific data */
struct class_device *parent; /* parent of this child device, if there is one */
struct device_type *type;
unsigned is_registered:1;
unsigned uevent_suppress:1;
- struct device_attribute uevent_attr;
- struct device_attribute *devt_attr;
struct semaphore sem; /* semaphore to synchronize calls to
* its driver.