Commit 85e865ec authored by Patrick Mochel's avatar Patrick Mochel

kobjects: Remove kobject::subsys and subsystem::kobj.

The kobject core no longer references a subsystem directly through a kobject,
instead using the kobject's dominant kset to reference the subsystem. The 
registrants of kobjects have been fixed up. 

To aid in this process, a few helpers were introdcuced: 

- kobj_set_kset_s(obj,subsys)
- kset_set_kset_s(obj,subsys)
- subsys_set_kset(obj,subsys)

that set the kset ptr of embedded kobjects for objects that have different
embedded types. See include/linux/kobject.h for more description and usage.


struct subsystem::kobj is also removed, relying solely on a subsystem's
embedded kset for hierarchy information.  Since this requires modification
of the subsystem declarations, a helper macro has been defined:

decl_subsys(name,type)

which initializes the name and ktype fields of the subsystem's embedded
kset. All the subsystem declarations have been fixed up.
parent 3e815107
......@@ -20,7 +20,7 @@
#define to_drv(node) container_of(node,struct device_driver,kobj.entry)
#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
#define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj)
#define to_bus(obj) container_of(obj,struct bus_type,subsys.kset.kobj)
/*
* sysfs bindings for drivers
......@@ -114,7 +114,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
int error;
if (get_bus(bus)) {
error = sysfs_create_file(&bus->subsys.kobj,&attr->attr);
error = sysfs_create_file(&bus->subsys.kset.kobj,&attr->attr);
put_bus(bus);
} else
error = -EINVAL;
......@@ -124,7 +124,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
if (get_bus(bus)) {
sysfs_remove_file(&bus->subsys.kobj,&attr->attr);
sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr);
put_bus(bus);
}
}
......@@ -134,10 +134,7 @@ static struct kobj_type ktype_bus = {
};
struct subsystem bus_subsys = {
.kobj = { .name = "bus" },
};
decl_subsys(bus,&ktype_bus);
/**
* bus_for_each_dev - device iterator.
......@@ -438,8 +435,7 @@ int bus_add_driver(struct device_driver * drv)
pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
drv->kobj.ktype = &ktype_driver;
drv->kobj.subsys = &bus->drivers;
drv->kobj.kset = &bus->drivers;
kobject_register(&drv->kobj);
down_write(&bus->subsys.rwsem);
......@@ -493,9 +489,8 @@ void put_bus(struct bus_type * bus)
*/
int bus_register(struct bus_type * bus)
{
strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
bus->subsys.kobj.ktype = &ktype_bus;
bus->subsys.kobj.subsys = &bus_subsys;
strncpy(bus->subsys.kset.kobj.name,bus->name,KOBJ_NAME_LEN);
subsys_set_kset(bus,bus_subsys);
subsystem_register(&bus->subsys);
snprintf(bus->devices.kobj.name,KOBJ_NAME_LEN,"devices");
......@@ -504,6 +499,7 @@ int bus_register(struct bus_type * bus)
snprintf(bus->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
bus->drivers.subsys = &bus->subsys;
bus->drivers.ktype = &ktype_driver;
kset_register(&bus->drivers);
pr_debug("bus type '%s' registered\n",bus->name);
......
......@@ -11,7 +11,7 @@
#include "base.h"
#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
#define to_class(obj) container_of(obj,struct device_class,subsys.kobj)
#define to_class(obj) container_of(obj,struct device_class,subsys.kset.kobj)
static ssize_t
devclass_attr_show(struct kobject * kobj, struct attribute * attr,
......@@ -48,9 +48,7 @@ static struct kobj_type ktype_devclass = {
.sysfs_ops = &class_sysfs_ops,
};
static struct subsystem class_subsys = {
.kobj = { .name = "class", },
};
static decl_subsys(class,&ktype_devclass);
static int devclass_dev_link(struct device_class * cls, struct device * dev)
......@@ -228,9 +226,8 @@ void put_devclass(struct device_class * cls)
int devclass_register(struct device_class * cls)
{
pr_debug("device class '%s': registering\n",cls->name);
strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN);
cls->subsys.kobj.subsys = &class_subsys;
cls->subsys.kobj.ktype = &ktype_devclass;
strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
subsys_set_kset(cls,class_subsys);
subsystem_register(&cls->subsys);
snprintf(cls->devices.kobj.name,KOBJ_NAME_LEN,"devices");
......
......@@ -90,11 +90,8 @@ static struct kobj_type ktype_device = {
/**
* device_subsys - structure to be registered with kobject core.
*/
struct subsystem device_subsys = {
.kobj = {
.name = "devices",
},
};
decl_subsys(devices,&ktype_device);
/**
......@@ -177,8 +174,7 @@ int device_add(struct device *dev)
/* first, register with generic layer. */
strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
dev->kobj.ktype = &ktype_device;
dev->kobj.subsys = &device_subsys;
kobj_set_kset_s(dev,devices_subsys);
if (parent)
dev->kobj.parent = &parent->kobj;
......@@ -317,7 +313,7 @@ void device_unregister(struct device * dev)
static int __init device_subsys_init(void)
{
return subsystem_register(&device_subsys);
return subsystem_register(&devices_subsys);
}
core_initcall(device_subsys_init);
......
......@@ -6,13 +6,11 @@
#include <linux/module.h>
#include <linux/init.h>
static struct subsystem firmware_subsys = {
.kobj = { .name = "firmware" },
};
static decl_subsys(firmware,NULL);
int firmware_register(struct subsystem * s)
{
s->kobj.kset = &firmware_subsys.kset;
kset_set_kset_s(s,firmware_subsys);
return subsystem_register(s);
}
......
......@@ -10,7 +10,7 @@
#include "base.h"
#define to_intf(node) container_of(node,struct device_interface,subsys.kobj.entry)
#define to_intf(node) container_of(node,struct device_interface,kset.kobj.entry)
#define to_data(e) container_of(e,struct intf_data,kobj.entry)
......@@ -25,7 +25,7 @@ static int intf_dev_link(struct intf_data * data)
{
char name[16];
snprintf(name,16,"%d",data->intf_num);
return sysfs_create_link(&data->intf->subsys.kset.kobj,&data->dev->kobj,name);
return sysfs_create_link(&data->intf->kset.kobj,&data->dev->kobj,name);
}
/**
......@@ -38,7 +38,7 @@ static void intf_dev_unlink(struct intf_data * data)
{
char name[16];
snprintf(name,16,"%d",data->intf_num);
sysfs_remove_link(&data->intf->subsys.kset.kobj,name);
sysfs_remove_link(&data->intf->kset.kobj,name);
}
......@@ -62,7 +62,7 @@ int interface_add_data(struct intf_data * data)
if (intf) {
data->intf_num = intf->devnum++;
data->kobj.subsys = &intf->subsys;
data->kobj.kset = &intf->kset;
kobject_register(&data->kobj);
list_add_tail(&data->dev_entry,&data->dev->intf_list);
......@@ -169,9 +169,9 @@ int interface_register(struct device_interface * intf)
pr_debug("register interface '%s' with class '%s'\n",
intf->name,cls->name);
strncpy(intf->subsys.kobj.name,intf->name,KOBJ_NAME_LEN);
intf->subsys.kobj.subsys = &cls->subsys;
subsystem_register(&intf->subsys);
strncpy(intf->kset.kobj.name,intf->name,KOBJ_NAME_LEN);
kset_set_kset_s(intf,cls->subsys);
kset_register(&intf->kset);
add_intf(intf);
}
return 0;
......@@ -192,7 +192,7 @@ static void del_intf(struct device_interface * intf)
struct list_head * entry;
down_write(&intf->devclass->subsys.rwsem);
list_for_each(entry,&intf->subsys.kset.list) {
list_for_each(entry,&intf->kset.list) {
struct intf_data * data = to_data(entry);
del(data);
}
......@@ -215,7 +215,7 @@ void interface_unregister(struct device_interface * intf)
pr_debug("unregistering interface '%s' from class '%s'\n",
intf->name,cls->name);
del_intf(intf);
subsystem_unregister(&intf->subsys);
kset_unregister(&intf->kset);
put_devclass(cls);
}
}
......
......@@ -17,7 +17,7 @@
#define to_dev(node) container_of(node,struct device,kobj.entry)
extern struct subsystem device_subsys;
extern struct subsystem devices_subsys;
/**
* device_suspend - suspend/remove all devices on the device ree
......@@ -37,8 +37,8 @@ int device_suspend(u32 state, u32 level)
printk(KERN_EMERG "Suspending devices\n");
down_write(&device_subsys.rwsem);
list_for_each(node,&device_subsys.kset.list) {
down_write(&devices_subsys.rwsem);
list_for_each(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->suspend) {
pr_debug("suspending device %s\n",dev->name);
......@@ -47,7 +47,7 @@ int device_suspend(u32 state, u32 level)
printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
return error;
}
......@@ -63,15 +63,15 @@ void device_resume(u32 level)
{
struct list_head * node;
down_write(&device_subsys.rwsem);
list_for_each_prev(node,&device_subsys.kset.list) {
down_write(&devices_subsys.rwsem);
list_for_each_prev(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->resume) {
pr_debug("resuming device %s\n",dev->name);
dev->driver->resume(dev,level);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
printk(KERN_EMERG "Devices Resumed\n");
}
......@@ -85,15 +85,15 @@ void device_shutdown(void)
printk(KERN_EMERG "Shutting down devices\n");
down_write(&device_subsys.rwsem);
list_for_each(entry,&device_subsys.kset.list) {
down_write(&devices_subsys.rwsem);
list_for_each(entry,&devices_subsys.kset.list) {
struct device * dev = to_dev(entry);
if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name);
dev->driver->shutdown(dev);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
}
EXPORT_SYMBOL(device_suspend);
......
......@@ -390,9 +390,7 @@ static struct kobj_type ktype_block = {
.default_attrs = default_attrs,
};
struct subsystem block_subsys = {
.kobj = { .name = "block" },
};
decl_subsys(block,&ktype_block);
struct gendisk *alloc_disk(int minors)
{
......@@ -411,8 +409,7 @@ struct gendisk *alloc_disk(int minors)
disk->minors = minors;
while (minors >>= 1)
disk->minor_shift++;
disk->kobj.subsys = &block_subsys;
disk->kobj.ktype = &ktype_block;
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
INIT_LIST_HEAD(&disk->full_list);
rand_initialize_disk(disk);
......
......@@ -145,7 +145,7 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char *
return error;
}
#define to_subsys(k) container_of(k,struct subsystem,kobj)
#define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
/**
......@@ -306,7 +306,9 @@ static int check_perm(struct inode * inode, struct file * file)
/* if the kobject has no ktype, then we assume that it is a subsystem
* itself, and use ops for it.
*/
if (kobj->ktype)
if (kobj->kset && kobj->kset->ktype)
ops = kobj->kset->ktype->sysfs_ops;
else if (kobj->ktype)
ops = kobj->ktype->sysfs_ops;
else
ops = &subsys_sysfs_ops;
......
......@@ -212,7 +212,7 @@ struct device_interface {
char * name;
struct device_class * devclass;
struct subsystem subsys;
struct kset kset;
u32 devnum;
int (*add_device) (struct device *);
......
......@@ -19,7 +19,6 @@ struct kobject {
atomic_t refcount;
struct list_head entry;
struct kobject * parent;
struct subsystem * subsys;
struct kset * kset;
struct kobj_type * ktype;
struct dentry * dentry;
......@@ -90,11 +89,62 @@ static inline void kset_put(struct kset * k)
struct subsystem {
struct kset kset;
struct kobject kobj;
struct rw_semaphore rwsem;
};
#define decl_subsys(_name,_type) \
struct subsystem _name##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
} \
}
/**
* Helpers for setting the kset of registered objects.
* Often, a registered object belongs to a kset embedded in a
* subsystem. These do no magic, just make the resulting code
* easier to follow.
*/
/**
* kobj_set_kset_s(obj,subsys) - set kset for embedded kobject.
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->kobj.
*/
#define kobj_set_kset_s(obj,subsys) \
(obj)->kobj.kset = &(subsys).kset
/**
* kset_set_kset_s(obj,subsys) - set kset for embedded kset.
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->kset.
* Sets the kset of @obj's embedded kobject (via its embedded
* kset) to @subsys.kset. This makes @obj a member of that
* kset.
*/
#define kset_set_kset_s(obj,subsys) \
(obj)->kset.kobj.kset = &(subsys).kset
/**
* subsys_set_kset(obj,subsys) - set kset for subsystem
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->subsys.
* Sets the kset of @obj's kobject to @subsys.kset. This makes
* the object a member of that kset.
*/
#define subsys_set_kset(obj,_subsys) \
(obj)->subsys.kset.kobj.kset = &(_subsys).kset
extern void subsystem_init(struct subsystem *);
extern int subsystem_register(struct subsystem *);
......
......@@ -11,6 +11,14 @@
static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static inline struct kobj_type * get_ktype(struct kobject * k)
{
if (k->kset && k->kset->ktype)
return k->kset->ktype;
else
return k->ktype;
}
/**
* populate_dir - populate directory with attributes.
* @kobj: object we're working on.
......@@ -25,7 +33,7 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static int populate_dir(struct kobject * kobj)
{
struct kobj_type * t = kobj->ktype;
struct kobj_type * t = get_ktype(kobj);
struct attribute * attr;
int error = 0;
int i;
......@@ -84,11 +92,6 @@ int kobject_add(struct kobject * kobj)
kobj->name, parent ? parent->name : "<NULL>",
kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
if (kobj->subsys) {
if (!kobj->kset)
kobj->kset = &kobj->subsys->kset;
}
if (kobj->kset) {
down_write(&kobj->kset->subsys->rwsem);
if (parent)
......@@ -177,7 +180,7 @@ struct kobject * kobject_get(struct kobject * kobj)
void kobject_cleanup(struct kobject * kobj)
{
struct kobj_type * t = kobj->ktype;
struct kobj_type * t = get_ktype(kobj);
struct kset * s = kobj->kset;
pr_debug("kobject %s: cleaning up\n",kobj->name);
......@@ -263,7 +266,6 @@ void kset_unregister(struct kset * k)
void subsystem_init(struct subsystem * s)
{
memcpy(&s->kset.kobj,&s->kobj,sizeof(struct kobject));
init_rwsem(&s->rwsem);
kset_init(&s->kset);
}
......@@ -308,7 +310,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
{
int error = 0;
if (subsys_get(s)) {
error = sysfs_create_file(&s->kobj,&a->attr);
error = sysfs_create_file(&s->kset.kobj,&a->attr);
subsys_put(s);
}
return error;
......@@ -324,7 +326,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
{
if (subsys_get(s)) {
sysfs_remove_file(&s->kobj,&a->attr);
sysfs_remove_file(&s->kset.kobj,&a->attr);
subsys_put(s);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment