driver core: remove fields from struct bus_type
struct bus_type is static everywhere in the kernel. This moves the kobject in the structure out of it, and a bunch of other private only to the driver core fields are now moved to a private structure. This lets us dynamically create the backing kobject properly and gives us the chance to be able to document to users exactly how to use the struct bus_type as there are no fields they can improperly access. Thanks to Kay for the build fixes on this patch. Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
@@ -1,6 +1,34 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.
|
||||||
|
*
|
||||||
|
* @subsys - the struct kset that defines this bus. This is the main kobject
|
||||||
|
* @drivers_kset - the list of drivers associated with this bus
|
||||||
|
* @devices_kset - the list of devices associated with this bus
|
||||||
|
* @klist_devices - the klist to iterate over the @devices_kset
|
||||||
|
* @klist_drivers - the klist to iterate over the @drivers_kset
|
||||||
|
* @bus_notifier - the bus notifier list for anything that cares about things
|
||||||
|
* on this bus.
|
||||||
|
* @bus - pointer back to the struct bus_type that this structure is associated
|
||||||
|
* with.
|
||||||
|
*
|
||||||
|
* This structure is the one that is the actual kobject allowing struct
|
||||||
|
* bus_type to be statically allocated safely. Nothing outside of the driver
|
||||||
|
* core should ever touch these fields.
|
||||||
|
*/
|
||||||
|
struct bus_type_private {
|
||||||
|
struct kset subsys;
|
||||||
|
struct kset *drivers_kset;
|
||||||
|
struct kset *devices_kset;
|
||||||
|
struct klist klist_devices;
|
||||||
|
struct klist klist_drivers;
|
||||||
|
struct blocking_notifier_head bus_notifier;
|
||||||
|
unsigned int drivers_autoprobe:1;
|
||||||
|
struct bus_type *bus;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* initialisation functions */
|
/* initialisation functions */
|
||||||
|
|
||||||
extern int devices_init(void);
|
extern int devices_init(void);
|
||||||
extern int buses_init(void);
|
extern int buses_init(void);
|
||||||
extern int classes_init(void);
|
extern int classes_init(void);
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#include "power/power.h"
|
#include "power/power.h"
|
||||||
|
|
||||||
#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
|
#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
|
* sysfs bindings for drivers
|
||||||
@@ -32,13 +32,17 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
|
|||||||
|
|
||||||
static struct bus_type *bus_get(struct bus_type *bus)
|
static struct bus_type *bus_get(struct bus_type *bus)
|
||||||
{
|
{
|
||||||
return bus ? container_of(kset_get(&bus->subsys),
|
if (bus) {
|
||||||
struct bus_type, subsys) : NULL;
|
kset_get(&bus->p->subsys);
|
||||||
|
return bus;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bus_put(struct bus_type *bus)
|
static void bus_put(struct bus_type *bus)
|
||||||
{
|
{
|
||||||
kset_put(&bus->subsys);
|
if (bus)
|
||||||
|
kset_put(&bus->p->subsys);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@@ -104,11 +108,11 @@ static ssize_t
|
|||||||
bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
|
||||||
{
|
{
|
||||||
struct bus_attribute * bus_attr = to_bus_attr(attr);
|
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;
|
ssize_t ret = 0;
|
||||||
|
|
||||||
if (bus_attr->show)
|
if (bus_attr->show)
|
||||||
ret = bus_attr->show(bus, buf);
|
ret = bus_attr->show(bus_priv->bus, buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,11 +121,11 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr,
|
|||||||
const char * buf, size_t count)
|
const char * buf, size_t count)
|
||||||
{
|
{
|
||||||
struct bus_attribute * bus_attr = to_bus_attr(attr);
|
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;
|
ssize_t ret = 0;
|
||||||
|
|
||||||
if (bus_attr->store)
|
if (bus_attr->store)
|
||||||
ret = bus_attr->store(bus, buf, count);
|
ret = bus_attr->store(bus_priv->bus, buf, count);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +138,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
if (bus_get(bus)) {
|
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);
|
bus_put(bus);
|
||||||
} else
|
} else
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
@@ -144,7 +148,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)
|
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
|
||||||
{
|
{
|
||||||
if (bus_get(bus)) {
|
if (bus_get(bus)) {
|
||||||
sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
|
sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
|
||||||
bus_put(bus);
|
bus_put(bus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,16 +241,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
|
|||||||
|
|
||||||
static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
|
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,
|
static ssize_t store_drivers_autoprobe(struct bus_type *bus,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
if (buf[0] == '0')
|
if (buf[0] == '0')
|
||||||
bus->drivers_autoprobe = 0;
|
bus->p->drivers_autoprobe = 0;
|
||||||
else
|
else
|
||||||
bus->drivers_autoprobe = 1;
|
bus->p->drivers_autoprobe = 1;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +304,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
|
|||||||
if (!bus)
|
if (!bus)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
klist_iter_init_node(&bus->klist_devices, &i,
|
klist_iter_init_node(&bus->p->klist_devices, &i,
|
||||||
(start ? &start->knode_bus : NULL));
|
(start ? &start->knode_bus : NULL));
|
||||||
while ((dev = next_device(&i)) && !error)
|
while ((dev = next_device(&i)) && !error)
|
||||||
error = fn(dev, data);
|
error = fn(dev, data);
|
||||||
@@ -333,7 +337,7 @@ struct device * bus_find_device(struct bus_type *bus,
|
|||||||
if (!bus)
|
if (!bus)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
klist_iter_init_node(&bus->klist_devices, &i,
|
klist_iter_init_node(&bus->p->klist_devices, &i,
|
||||||
(start ? &start->knode_bus : NULL));
|
(start ? &start->knode_bus : NULL));
|
||||||
while ((dev = next_device(&i)))
|
while ((dev = next_device(&i)))
|
||||||
if (match(dev, data) && get_device(dev))
|
if (match(dev, data) && get_device(dev))
|
||||||
@@ -379,7 +383,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
|
|||||||
if (!bus)
|
if (!bus)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
klist_iter_init_node(&bus->klist_drivers, &i,
|
klist_iter_init_node(&bus->p->klist_drivers, &i,
|
||||||
start ? &start->knode_bus : NULL);
|
start ? &start->knode_bus : NULL);
|
||||||
while ((drv = next_driver(&i)) && !error)
|
while ((drv = next_driver(&i)) && !error)
|
||||||
error = fn(drv, data);
|
error = fn(drv, data);
|
||||||
@@ -420,7 +424,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev)
|
|||||||
static int make_deprecated_bus_links(struct device *dev)
|
static int make_deprecated_bus_links(struct device *dev)
|
||||||
{
|
{
|
||||||
return sysfs_create_link(&dev->kobj,
|
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)
|
static void remove_deprecated_bus_links(struct device *dev)
|
||||||
@@ -449,12 +453,12 @@ int bus_add_device(struct device * dev)
|
|||||||
error = device_add_attrs(bus, dev);
|
error = device_add_attrs(bus, dev);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put;
|
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);
|
&dev->kobj, dev->bus_id);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_id;
|
goto out_id;
|
||||||
error = sysfs_create_link(&dev->kobj,
|
error = sysfs_create_link(&dev->kobj,
|
||||||
&dev->bus->subsys.kobj, "subsystem");
|
&dev->bus->p->subsys.kobj, "subsystem");
|
||||||
if (error)
|
if (error)
|
||||||
goto out_subsys;
|
goto out_subsys;
|
||||||
error = make_deprecated_bus_links(dev);
|
error = make_deprecated_bus_links(dev);
|
||||||
@@ -466,7 +470,7 @@ int bus_add_device(struct device * dev)
|
|||||||
out_deprecated:
|
out_deprecated:
|
||||||
sysfs_remove_link(&dev->kobj, "subsystem");
|
sysfs_remove_link(&dev->kobj, "subsystem");
|
||||||
out_subsys:
|
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:
|
out_id:
|
||||||
device_remove_attrs(bus, dev);
|
device_remove_attrs(bus, dev);
|
||||||
out_put:
|
out_put:
|
||||||
@@ -488,11 +492,11 @@ void bus_attach_device(struct device * dev)
|
|||||||
|
|
||||||
if (bus) {
|
if (bus) {
|
||||||
dev->is_registered = 1;
|
dev->is_registered = 1;
|
||||||
if (bus->drivers_autoprobe)
|
if (bus->p->drivers_autoprobe)
|
||||||
ret = device_attach(dev);
|
ret = device_attach(dev);
|
||||||
WARN_ON(ret < 0);
|
WARN_ON(ret < 0);
|
||||||
if (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
|
else
|
||||||
dev->is_registered = 0;
|
dev->is_registered = 0;
|
||||||
}
|
}
|
||||||
@@ -512,7 +516,7 @@ void bus_remove_device(struct device * dev)
|
|||||||
if (dev->bus) {
|
if (dev->bus) {
|
||||||
sysfs_remove_link(&dev->kobj, "subsystem");
|
sysfs_remove_link(&dev->kobj, "subsystem");
|
||||||
remove_deprecated_bus_links(dev);
|
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);
|
device_remove_attrs(dev->bus, dev);
|
||||||
if (dev->is_registered) {
|
if (dev->is_registered) {
|
||||||
dev->is_registered = 0;
|
dev->is_registered = 0;
|
||||||
@@ -638,18 +642,18 @@ int bus_add_driver(struct device_driver *drv)
|
|||||||
error = kobject_set_name(&drv->kobj, "%s", drv->name);
|
error = kobject_set_name(&drv->kobj, "%s", drv->name);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put_bus;
|
goto out_put_bus;
|
||||||
drv->kobj.kset = bus->drivers_kset;
|
drv->kobj.kset = bus->p->drivers_kset;
|
||||||
drv->kobj.ktype = &driver_ktype;
|
drv->kobj.ktype = &driver_ktype;
|
||||||
error = kobject_register(&drv->kobj);
|
error = kobject_register(&drv->kobj);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put_bus;
|
goto out_put_bus;
|
||||||
|
|
||||||
if (drv->bus->drivers_autoprobe) {
|
if (drv->bus->p->drivers_autoprobe) {
|
||||||
error = driver_attach(drv);
|
error = driver_attach(drv);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_unregister;
|
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);
|
module_add_driver(drv->owner, drv);
|
||||||
|
|
||||||
error = driver_create_file(drv, &driver_attr_uevent);
|
error = driver_create_file(drv, &driver_attr_uevent);
|
||||||
@@ -828,7 +832,7 @@ static ssize_t bus_uevent_store(struct bus_type *bus,
|
|||||||
enum kobject_action action;
|
enum kobject_action action;
|
||||||
|
|
||||||
if (kobject_action_type(buf, count, &action) == 0)
|
if (kobject_action_type(buf, count, &action) == 0)
|
||||||
kobject_uevent(&bus->subsys.kobj, action);
|
kobject_uevent(&bus->p->subsys.kobj, action);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
|
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
|
||||||
@@ -844,17 +848,26 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
|
|||||||
int bus_register(struct bus_type * bus)
|
int bus_register(struct bus_type * bus)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
struct bus_type_private *priv;
|
||||||
|
|
||||||
BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
|
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);
|
priv->bus = bus;
|
||||||
|
bus->p = priv;
|
||||||
|
|
||||||
|
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
|
||||||
|
|
||||||
|
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
bus->subsys.kobj.kset = bus_kset;
|
priv->subsys.kobj.kset = bus_kset;
|
||||||
bus->subsys.kobj.ktype = &bus_ktype;
|
priv->subsys.kobj.ktype = &bus_ktype;
|
||||||
|
priv->drivers_autoprobe = 1;
|
||||||
|
|
||||||
retval = kset_register(&bus->subsys);
|
retval = kset_register(&priv->subsys);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -862,24 +875,23 @@ int bus_register(struct bus_type * bus)
|
|||||||
if (retval)
|
if (retval)
|
||||||
goto bus_uevent_fail;
|
goto bus_uevent_fail;
|
||||||
|
|
||||||
bus->devices_kset = kset_create_and_add("devices", NULL,
|
priv->devices_kset = kset_create_and_add("devices", NULL,
|
||||||
&bus->subsys.kobj);
|
&priv->subsys.kobj);
|
||||||
if (!bus->devices_kset) {
|
if (!priv->devices_kset) {
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto bus_devices_fail;
|
goto bus_devices_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
bus->drivers_kset = kset_create_and_add("drivers", NULL,
|
priv->drivers_kset = kset_create_and_add("drivers", NULL,
|
||||||
&bus->subsys.kobj);
|
&priv->subsys.kobj);
|
||||||
if (!bus->drivers_kset) {
|
if (!priv->drivers_kset) {
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto bus_drivers_fail;
|
goto bus_drivers_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
|
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
|
||||||
klist_init(&bus->klist_drivers, NULL, NULL);
|
klist_init(&priv->klist_drivers, NULL, NULL);
|
||||||
|
|
||||||
bus->drivers_autoprobe = 1;
|
|
||||||
retval = add_probe_files(bus);
|
retval = add_probe_files(bus);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto bus_probe_files_fail;
|
goto bus_probe_files_fail;
|
||||||
@@ -894,13 +906,14 @@ int bus_register(struct bus_type * bus)
|
|||||||
bus_attrs_fail:
|
bus_attrs_fail:
|
||||||
remove_probe_files(bus);
|
remove_probe_files(bus);
|
||||||
bus_probe_files_fail:
|
bus_probe_files_fail:
|
||||||
kset_unregister(bus->drivers_kset);
|
kset_unregister(bus->p->drivers_kset);
|
||||||
bus_drivers_fail:
|
bus_drivers_fail:
|
||||||
kset_unregister(bus->devices_kset);
|
kset_unregister(bus->p->devices_kset);
|
||||||
bus_devices_fail:
|
bus_devices_fail:
|
||||||
bus_remove_file(bus, &bus_attr_uevent);
|
bus_remove_file(bus, &bus_attr_uevent);
|
||||||
bus_uevent_fail:
|
bus_uevent_fail:
|
||||||
kset_unregister(&bus->subsys);
|
kset_unregister(&bus->p->subsys);
|
||||||
|
kfree(bus->p);
|
||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -917,33 +930,34 @@ void bus_unregister(struct bus_type * bus)
|
|||||||
pr_debug("bus %s: unregistering\n", bus->name);
|
pr_debug("bus %s: unregistering\n", bus->name);
|
||||||
bus_remove_attrs(bus);
|
bus_remove_attrs(bus);
|
||||||
remove_probe_files(bus);
|
remove_probe_files(bus);
|
||||||
kset_unregister(bus->drivers_kset);
|
kset_unregister(bus->p->drivers_kset);
|
||||||
kset_unregister(bus->devices_kset);
|
kset_unregister(bus->p->devices_kset);
|
||||||
bus_remove_file(bus, &bus_attr_uevent);
|
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)
|
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);
|
EXPORT_SYMBOL_GPL(bus_register_notifier);
|
||||||
|
|
||||||
int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb)
|
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);
|
EXPORT_SYMBOL_GPL(bus_unregister_notifier);
|
||||||
|
|
||||||
struct kset *bus_get_kset(struct bus_type *bus)
|
struct kset *bus_get_kset(struct bus_type *bus)
|
||||||
{
|
{
|
||||||
return &bus->subsys;
|
return &bus->p->subsys;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(bus_get_kset);
|
EXPORT_SYMBOL_GPL(bus_get_kset);
|
||||||
|
|
||||||
struct klist *bus_get_device_klist(struct bus_type *bus)
|
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);
|
EXPORT_SYMBOL_GPL(bus_get_device_klist);
|
||||||
|
|
||||||
|
@@ -769,7 +769,7 @@ int device_add(struct device *dev)
|
|||||||
|
|
||||||
/* notify clients of device entry (new way) */
|
/* notify clients of device entry (new way) */
|
||||||
if (dev->bus)
|
if (dev->bus)
|
||||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_ADD_DEVICE, dev);
|
BUS_NOTIFY_ADD_DEVICE, dev);
|
||||||
|
|
||||||
error = device_create_file(dev, &uevent_attr);
|
error = device_create_file(dev, &uevent_attr);
|
||||||
@@ -820,7 +820,7 @@ int device_add(struct device *dev)
|
|||||||
dpm_sysfs_remove(dev);
|
dpm_sysfs_remove(dev);
|
||||||
PMError:
|
PMError:
|
||||||
if (dev->bus)
|
if (dev->bus)
|
||||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_DEL_DEVICE, dev);
|
BUS_NOTIFY_DEL_DEVICE, dev);
|
||||||
device_remove_attrs(dev);
|
device_remove_attrs(dev);
|
||||||
AttrsError:
|
AttrsError:
|
||||||
@@ -999,7 +999,7 @@ void device_del(struct device * dev)
|
|||||||
if (platform_notify_remove)
|
if (platform_notify_remove)
|
||||||
platform_notify_remove(dev);
|
platform_notify_remove(dev);
|
||||||
if (dev->bus)
|
if (dev->bus)
|
||||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_DEL_DEVICE, dev);
|
BUS_NOTIFY_DEL_DEVICE, dev);
|
||||||
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
|
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
|
||||||
kobject_del(&dev->kobj);
|
kobject_del(&dev->kobj);
|
||||||
|
@@ -38,7 +38,7 @@ static void driver_bound(struct device *dev)
|
|||||||
dev->bus_id, dev->driver->name);
|
dev->bus_id, dev->driver->name);
|
||||||
|
|
||||||
if (dev->bus)
|
if (dev->bus)
|
||||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_BOUND_DRIVER, dev);
|
BUS_NOTIFY_BOUND_DRIVER, dev);
|
||||||
|
|
||||||
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
|
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
|
||||||
@@ -296,7 +296,7 @@ static void __device_release_driver(struct device * dev)
|
|||||||
klist_remove(&dev->knode_driver);
|
klist_remove(&dev->knode_driver);
|
||||||
|
|
||||||
if (dev->bus)
|
if (dev->bus)
|
||||||
blocking_notifier_call_chain(&dev->bus->bus_notifier,
|
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
|
||||||
BUS_NOTIFY_UNBIND_DRIVER,
|
BUS_NOTIFY_UNBIND_DRIVER,
|
||||||
dev);
|
dev);
|
||||||
|
|
||||||
|
@@ -185,7 +185,7 @@ void driver_unregister(struct device_driver * drv)
|
|||||||
*/
|
*/
|
||||||
struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
||||||
{
|
{
|
||||||
struct kobject *k = kset_find_obj(bus->drivers_kset, name);
|
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
|
||||||
if (k)
|
if (k)
|
||||||
return to_drv(k);
|
return to_drv(k);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -497,12 +497,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
|
|||||||
* if the probe was successful, and make sure any forced probes of
|
* if the probe was successful, and make sure any forced probes of
|
||||||
* new devices fail.
|
* new devices fail.
|
||||||
*/
|
*/
|
||||||
spin_lock(&platform_bus_type.klist_drivers.k_lock);
|
spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
|
||||||
drv->probe = NULL;
|
drv->probe = NULL;
|
||||||
if (code == 0 && list_empty(&drv->driver.klist_devices.k_list))
|
if (code == 0 && list_empty(&drv->driver.klist_devices.k_list))
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
drv->driver.probe = platform_drv_probe_fail;
|
drv->driver.probe = platform_drv_probe_fail;
|
||||||
spin_unlock(&platform_bus_type.klist_drivers.k_lock);
|
spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
|
||||||
|
|
||||||
if (code != retval)
|
if (code != retval)
|
||||||
platform_driver_unregister(drv);
|
platform_driver_unregister(drv);
|
||||||
|
@@ -35,6 +35,7 @@ struct device_driver;
|
|||||||
struct class;
|
struct class;
|
||||||
struct class_device;
|
struct class_device;
|
||||||
struct bus_type;
|
struct bus_type;
|
||||||
|
struct bus_type_private;
|
||||||
|
|
||||||
struct bus_attribute {
|
struct bus_attribute {
|
||||||
struct attribute attr;
|
struct attribute attr;
|
||||||
@@ -51,15 +52,6 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
|||||||
|
|
||||||
struct bus_type {
|
struct bus_type {
|
||||||
const char * name;
|
const char * name;
|
||||||
|
|
||||||
struct kset subsys;
|
|
||||||
struct kset *drivers_kset;
|
|
||||||
struct kset *devices_kset;
|
|
||||||
struct klist klist_devices;
|
|
||||||
struct klist klist_drivers;
|
|
||||||
|
|
||||||
struct blocking_notifier_head bus_notifier;
|
|
||||||
|
|
||||||
struct bus_attribute * bus_attrs;
|
struct bus_attribute * bus_attrs;
|
||||||
struct device_attribute * dev_attrs;
|
struct device_attribute * dev_attrs;
|
||||||
struct driver_attribute * drv_attrs;
|
struct driver_attribute * drv_attrs;
|
||||||
@@ -75,7 +67,7 @@ struct bus_type {
|
|||||||
int (*resume_early)(struct device * dev);
|
int (*resume_early)(struct device * dev);
|
||||||
int (*resume)(struct device * dev);
|
int (*resume)(struct device * dev);
|
||||||
|
|
||||||
unsigned int drivers_autoprobe:1;
|
struct bus_type_private *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int __must_check bus_register(struct bus_type * bus);
|
extern int __must_check bus_register(struct bus_type * bus);
|
||||||
|
Reference in New Issue
Block a user