]> Pileus Git - ~andy/linux/blobdiff - drivers/base/bus.c
cpu hotplug: topology: remove topology_dev_map
[~andy/linux] / drivers / base / bus.c
index 4f53b758ac2b672ce970a7ac1887491f3e502d5b..9a19b071c573aaa7d6fc17cdaa1f86e4a1d38580 100644 (file)
 static int __must_check bus_rescan_devices_helper(struct device *dev,
                                                void *data);
 
+static struct bus_type *bus_get(struct bus_type *bus)
+{
+       return bus ? container_of(kset_get(&bus->subsys),
+                               struct bus_type, subsys) : NULL;
+}
+
 static void bus_put(struct bus_type *bus)
 {
        kset_put(&bus->subsys);
@@ -83,7 +89,7 @@ static void driver_release(struct kobject * kobj)
         */
 }
 
-static struct kobj_type ktype_driver = {
+static struct kobj_type driver_ktype = {
        .sysfs_ops      = &driver_sysfs_ops,
        .release        = driver_release,
 };
@@ -127,7 +133,7 @@ static struct sysfs_ops bus_sysfs_ops = {
 int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
 {
        int error;
-       if (get_bus(bus)) {
+       if (bus_get(bus)) {
                error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
                bus_put(bus);
        } else
@@ -137,7 +143,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)) {
+       if (bus_get(bus)) {
                sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
                bus_put(bus);
        }
@@ -177,7 +183,7 @@ static int driver_helper(struct device *dev, void *data)
 static ssize_t driver_unbind(struct device_driver *drv,
                             const char *buf, size_t count)
 {
-       struct bus_type *bus = get_bus(drv->bus);
+       struct bus_type *bus = bus_get(drv->bus);
        struct device *dev;
        int err = -ENODEV;
 
@@ -204,7 +210,7 @@ static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
 static ssize_t driver_bind(struct device_driver *drv,
                           const char *buf, size_t count)
 {
-       struct bus_type *bus = get_bus(drv->bus);
+       struct bus_type *bus = bus_get(drv->bus);
        struct device *dev;
        int err = -ENODEV;
 
@@ -435,7 +441,7 @@ static inline void remove_deprecated_bus_links(struct device *dev) { }
  */
 int bus_add_device(struct device * dev)
 {
-       struct bus_type * bus = get_bus(dev->bus);
+       struct bus_type * bus = bus_get(dev->bus);
        int error = 0;
 
        if (bus) {
@@ -604,6 +610,17 @@ static inline int add_probe_files(struct bus_type *bus) { return 0; }
 static inline void remove_probe_files(struct bus_type *bus) {}
 #endif
 
+static ssize_t driver_uevent_store(struct device_driver *drv,
+                                  const char *buf, size_t count)
+{
+       enum kobject_action action;
+
+       if (kobject_action_type(buf, count, &action) == 0)
+               kobject_uevent(&drv->kobj, action);
+       return count;
+}
+static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
+
 /**
  *     bus_add_driver - Add a driver to the bus.
  *     @drv:   driver.
@@ -611,7 +628,7 @@ static inline void remove_probe_files(struct bus_type *bus) {}
  */
 int bus_add_driver(struct device_driver *drv)
 {
-       struct bus_type * bus = get_bus(drv->bus);
+       struct bus_type * bus = bus_get(drv->bus);
        int error = 0;
 
        if (!bus)
@@ -634,6 +651,11 @@ int bus_add_driver(struct device_driver *drv)
        klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
        module_add_driver(drv->owner, drv);
 
+       error = driver_create_file(drv, &driver_attr_uevent);
+       if (error) {
+               printk(KERN_ERR "%s: uevent attr (%s) failed\n",
+                       __FUNCTION__, drv->name);
+       }
        error = driver_add_attrs(bus, drv);
        if (error) {
                /* How the hell do we get out of this pickle? Give up */
@@ -671,6 +693,7 @@ void bus_remove_driver(struct device_driver * drv)
 
        remove_bind_files(drv);
        driver_remove_attrs(drv->bus, drv);
+       driver_remove_file(drv, &driver_attr_uevent);
        klist_remove(&drv->knode_bus);
        pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
        driver_detach(drv);
@@ -731,12 +754,6 @@ int device_reprobe(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(device_reprobe);
 
-struct bus_type *get_bus(struct bus_type *bus)
-{
-       return bus ? container_of(kset_get(&bus->subsys),
-                               struct bus_type, subsys) : NULL;
-}
-
 /**
  *     find_bus - locate bus by name.
  *     @name:  name of bus.
@@ -804,6 +821,17 @@ static void klist_devices_put(struct klist_node *n)
        put_device(dev);
 }
 
+static ssize_t bus_uevent_store(struct bus_type *bus,
+                               const char *buf, size_t count)
+{
+       enum kobject_action action;
+
+       if (kobject_action_type(buf, count, &action) == 0)
+               kobject_uevent(&bus->subsys.kobj, action);
+       return count;
+}
+static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
+
 /**
  *     bus_register - register a bus with the system.
  *     @bus:   bus.
@@ -828,6 +856,10 @@ int bus_register(struct bus_type * bus)
        if (retval)
                goto out;
 
+       retval = bus_create_file(bus, &bus_attr_uevent);
+       if (retval)
+               goto bus_uevent_fail;
+
        kobject_set_name(&bus->devices.kobj, "devices");
        bus->devices.kobj.parent = &bus->subsys.kobj;
        retval = kset_register(&bus->devices);
@@ -836,7 +868,7 @@ int bus_register(struct bus_type * bus)
 
        kobject_set_name(&bus->drivers.kobj, "drivers");
        bus->drivers.kobj.parent = &bus->subsys.kobj;
-       bus->drivers.ktype = &ktype_driver;
+       bus->drivers.ktype = &driver_ktype;
        retval = kset_register(&bus->drivers);
        if (retval)
                goto bus_drivers_fail;
@@ -863,6 +895,8 @@ bus_probe_files_fail:
 bus_drivers_fail:
        kset_unregister(&bus->devices);
 bus_devices_fail:
+       bus_remove_file(bus, &bus_attr_uevent);
+bus_uevent_fail:
        subsystem_unregister(&bus->subsys);
 out:
        return retval;
@@ -882,6 +916,7 @@ void bus_unregister(struct bus_type * bus)
        remove_probe_files(bus);
        kset_unregister(&bus->drivers);
        kset_unregister(&bus->devices);
+       bus_remove_file(bus, &bus_attr_uevent);
        subsystem_unregister(&bus->subsys);
 }