#include "power/power.h"
#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_private, subsys.kobj)
/*
* sysfs bindings for drivers
static struct bus_type *bus_get(struct bus_type *bus)
{
- return bus ? container_of(kset_get(&bus->subsys),
- struct bus_type, subsys) : NULL;
+ if (bus) {
+ kset_get(&bus->p->subsys);
+ return bus;
+ }
+ return NULL;
}
static void bus_put(struct bus_type *bus)
{
- kset_put(&bus->subsys);
+ if (bus)
+ kset_put(&bus->p->subsys);
}
static ssize_t
bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
- struct bus_type * bus = to_bus(kobj);
+ struct bus_type_private *bus_priv = to_bus(kobj);
ssize_t ret = 0;
if (bus_attr->show)
- ret = bus_attr->show(bus, buf);
+ ret = bus_attr->show(bus_priv->bus, buf);
return ret;
}
const char * buf, size_t count)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
- struct bus_type * bus = to_bus(kobj);
+ struct bus_type_private *bus_priv = to_bus(kobj);
ssize_t ret = 0;
if (bus_attr->store)
- ret = bus_attr->store(bus, buf, count);
+ ret = bus_attr->store(bus_priv->bus, buf, count);
return ret;
}
{
int error;
if (bus_get(bus)) {
- error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
+ error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);
bus_put(bus);
} else
error = -EINVAL;
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
if (bus_get(bus)) {
- sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
+ sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
bus_put(bus);
}
}
static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
{
- return sprintf(buf, "%d\n", bus->drivers_autoprobe);
+ return sprintf(buf, "%d\n", bus->p->drivers_autoprobe);
}
static ssize_t store_drivers_autoprobe(struct bus_type *bus,
const char *buf, size_t count)
{
if (buf[0] == '0')
- bus->drivers_autoprobe = 0;
+ bus->p->drivers_autoprobe = 0;
else
- bus->drivers_autoprobe = 1;
+ bus->p->drivers_autoprobe = 1;
return count;
}
if (!bus)
return -EINVAL;
- klist_iter_init_node(&bus->klist_devices, &i,
+ klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
if (!bus)
return NULL;
- klist_iter_init_node(&bus->klist_devices, &i,
+ klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
if (!bus)
return -EINVAL;
- klist_iter_init_node(&bus->klist_drivers, &i,
+ klist_iter_init_node(&bus->p->klist_drivers, &i,
start ? &start->knode_bus : NULL);
while ((drv = next_driver(&i)) && !error)
error = fn(drv, data);
static int make_deprecated_bus_links(struct device *dev)
{
return sysfs_create_link(&dev->kobj,
- &dev->bus->subsys.kobj, "bus");
+ &dev->bus->p->subsys.kobj, "bus");
}
static void remove_deprecated_bus_links(struct device *dev)
error = device_add_attrs(bus, dev);
if (error)
goto out_put;
- error = sysfs_create_link(&bus->devices_kset->kobj,
+ error = sysfs_create_link(&bus->p->devices_kset->kobj,
&dev->kobj, dev->bus_id);
if (error)
goto out_id;
error = sysfs_create_link(&dev->kobj,
- &dev->bus->subsys.kobj, "subsystem");
+ &dev->bus->p->subsys.kobj, "subsystem");
if (error)
goto out_subsys;
error = make_deprecated_bus_links(dev);
out_deprecated:
sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys:
- sysfs_remove_link(&bus->devices_kset->kobj, dev->bus_id);
+ sysfs_remove_link(&bus->p->devices_kset->kobj, dev->bus_id);
out_id:
device_remove_attrs(bus, dev);
out_put:
if (bus) {
dev->is_registered = 1;
- if (bus->drivers_autoprobe)
+ if (bus->p->drivers_autoprobe)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
- klist_add_tail(&dev->knode_bus, &bus->klist_devices);
+ klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
else
dev->is_registered = 0;
}
if (dev->bus) {
sysfs_remove_link(&dev->kobj, "subsystem");
remove_deprecated_bus_links(dev);
- sysfs_remove_link(&dev->bus->devices_kset->kobj, dev->bus_id);
+ sysfs_remove_link(&dev->bus->p->devices_kset->kobj, dev->bus_id);
device_remove_attrs(dev->bus, dev);
if (dev->is_registered) {
dev->is_registered = 0;
error = kobject_set_name(&drv->kobj, "%s", drv->name);
if (error)
goto out_put_bus;
- drv->kobj.kset = bus->drivers_kset;
+ drv->kobj.kset = bus->p->drivers_kset;
drv->kobj.ktype = &driver_ktype;
error = kobject_register(&drv->kobj);
if (error)
goto out_put_bus;
- if (drv->bus->drivers_autoprobe) {
+ if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
- klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
+ klist_add_tail(&drv->knode_bus, &bus->p->klist_drivers);
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
enum kobject_action action;
if (kobject_action_type(buf, count, &action) == 0)
- kobject_uevent(&bus->subsys.kobj, action);
+ kobject_uevent(&bus->p->subsys.kobj, action);
return count;
}
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
int bus_register(struct bus_type * bus)
{
int retval;
+ struct bus_type_private *priv;
+
+ priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = bus;
+ bus->p = priv;
- BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
- retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);
+ retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
if (retval)
goto out;
- bus->subsys.kobj.kset = bus_kset;
- bus->subsys.kobj.ktype = &bus_ktype;
+ priv->subsys.kobj.kset = bus_kset;
+ priv->subsys.kobj.ktype = &bus_ktype;
+ priv->drivers_autoprobe = 1;
- retval = kset_register(&bus->subsys);
+ retval = kset_register(&priv->subsys);
if (retval)
goto out;
if (retval)
goto bus_uevent_fail;
- bus->devices_kset = kset_create_and_add("devices", NULL,
- &bus->subsys.kobj);
- if (!bus->devices_kset) {
+ priv->devices_kset = kset_create_and_add("devices", NULL,
+ &priv->subsys.kobj);
+ if (!priv->devices_kset) {
retval = -ENOMEM;
goto bus_devices_fail;
}
- bus->drivers_kset = kset_create_and_add("drivers", NULL,
- &bus->subsys.kobj);
- if (!bus->drivers_kset) {
+ priv->drivers_kset = kset_create_and_add("drivers", NULL,
+ &priv->subsys.kobj);
+ if (!priv->drivers_kset) {
retval = -ENOMEM;
goto bus_drivers_fail;
}
- klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
- klist_init(&bus->klist_drivers, NULL, NULL);
+ klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
+ klist_init(&priv->klist_drivers, NULL, NULL);
- bus->drivers_autoprobe = 1;
retval = add_probe_files(bus);
if (retval)
goto bus_probe_files_fail;
bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
- kset_unregister(bus->drivers_kset);
+ kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
- kset_unregister(bus->devices_kset);
+ kset_unregister(bus->p->devices_kset);
bus_devices_fail:
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
- kset_unregister(&bus->subsys);
+ kset_unregister(&bus->p->subsys);
+ kfree(bus->p);
out:
return retval;
}
pr_debug("bus %s: unregistering\n", bus->name);
bus_remove_attrs(bus);
remove_probe_files(bus);
- kset_unregister(bus->drivers_kset);
- kset_unregister(bus->devices_kset);
+ kset_unregister(bus->p->drivers_kset);
+ kset_unregister(bus->p->devices_kset);
bus_remove_file(bus, &bus_attr_uevent);
- kset_unregister(&bus->subsys);
+ kset_unregister(&bus->p->subsys);
+ kfree(bus->p);
}
int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
{
- return blocking_notifier_chain_register(&bus->bus_notifier, nb);
+ return blocking_notifier_chain_register(&bus->p->bus_notifier, nb);
}
EXPORT_SYMBOL_GPL(bus_register_notifier);
int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
{
- return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
+ return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb);
}
EXPORT_SYMBOL_GPL(bus_unregister_notifier);
struct kset *bus_get_kset(struct bus_type *bus)
{
- return &bus->subsys;
+ return &bus->p->subsys;
}
EXPORT_SYMBOL_GPL(bus_get_kset);
struct klist *bus_get_device_klist(struct bus_type *bus)
{
- return &bus->klist_devices;
+ return &bus->p->klist_devices;
}
EXPORT_SYMBOL_GPL(bus_get_device_klist);