aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/bus.c')
-rw-r--r--drivers/base/bus.c116
1 files changed, 74 insertions, 42 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 61c67526a656..9a19b071c573 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -30,6 +30,17 @@
30static int __must_check bus_rescan_devices_helper(struct device *dev, 30static int __must_check bus_rescan_devices_helper(struct device *dev,
31 void *data); 31 void *data);
32 32
33static struct bus_type *bus_get(struct bus_type *bus)
34{
35 return bus ? container_of(kset_get(&bus->subsys),
36 struct bus_type, subsys) : NULL;
37}
38
39static void bus_put(struct bus_type *bus)
40{
41 kset_put(&bus->subsys);
42}
43
33static ssize_t 44static ssize_t
34drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 45drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
35{ 46{
@@ -78,7 +89,7 @@ static void driver_release(struct kobject * kobj)
78 */ 89 */
79} 90}
80 91
81static struct kobj_type ktype_driver = { 92static struct kobj_type driver_ktype = {
82 .sysfs_ops = &driver_sysfs_ops, 93 .sysfs_ops = &driver_sysfs_ops,
83 .release = driver_release, 94 .release = driver_release,
84}; 95};
@@ -122,9 +133,9 @@ static struct sysfs_ops bus_sysfs_ops = {
122int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) 133int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
123{ 134{
124 int error; 135 int error;
125 if (get_bus(bus)) { 136 if (bus_get(bus)) {
126 error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); 137 error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
127 put_bus(bus); 138 bus_put(bus);
128 } else 139 } else
129 error = -EINVAL; 140 error = -EINVAL;
130 return error; 141 return error;
@@ -132,9 +143,9 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
132 143
133void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) 144void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
134{ 145{
135 if (get_bus(bus)) { 146 if (bus_get(bus)) {
136 sysfs_remove_file(&bus->subsys.kobj, &attr->attr); 147 sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
137 put_bus(bus); 148 bus_put(bus);
138 } 149 }
139} 150}
140 151
@@ -172,7 +183,7 @@ static int driver_helper(struct device *dev, void *data)
172static ssize_t driver_unbind(struct device_driver *drv, 183static ssize_t driver_unbind(struct device_driver *drv,
173 const char *buf, size_t count) 184 const char *buf, size_t count)
174{ 185{
175 struct bus_type *bus = get_bus(drv->bus); 186 struct bus_type *bus = bus_get(drv->bus);
176 struct device *dev; 187 struct device *dev;
177 int err = -ENODEV; 188 int err = -ENODEV;
178 189
@@ -186,7 +197,7 @@ static ssize_t driver_unbind(struct device_driver *drv,
186 err = count; 197 err = count;
187 } 198 }
188 put_device(dev); 199 put_device(dev);
189 put_bus(bus); 200 bus_put(bus);
190 return err; 201 return err;
191} 202}
192static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 203static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
@@ -199,7 +210,7 @@ static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
199static ssize_t driver_bind(struct device_driver *drv, 210static ssize_t driver_bind(struct device_driver *drv,
200 const char *buf, size_t count) 211 const char *buf, size_t count)
201{ 212{
202 struct bus_type *bus = get_bus(drv->bus); 213 struct bus_type *bus = bus_get(drv->bus);
203 struct device *dev; 214 struct device *dev;
204 int err = -ENODEV; 215 int err = -ENODEV;
205 216
@@ -219,7 +230,7 @@ static ssize_t driver_bind(struct device_driver *drv,
219 err = -ENODEV; 230 err = -ENODEV;
220 } 231 }
221 put_device(dev); 232 put_device(dev);
222 put_bus(bus); 233 bus_put(bus);
223 return err; 234 return err;
224} 235}
225static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); 236static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
@@ -430,7 +441,7 @@ static inline void remove_deprecated_bus_links(struct device *dev) { }
430 */ 441 */
431int bus_add_device(struct device * dev) 442int bus_add_device(struct device * dev)
432{ 443{
433 struct bus_type * bus = get_bus(dev->bus); 444 struct bus_type * bus = bus_get(dev->bus);
434 int error = 0; 445 int error = 0;
435 446
436 if (bus) { 447 if (bus) {
@@ -459,7 +470,7 @@ out_subsys:
459out_id: 470out_id:
460 device_remove_attrs(bus, dev); 471 device_remove_attrs(bus, dev);
461out_put: 472out_put:
462 put_bus(dev->bus); 473 bus_put(dev->bus);
463 return error; 474 return error;
464} 475}
465 476
@@ -509,7 +520,7 @@ void bus_remove_device(struct device * dev)
509 } 520 }
510 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); 521 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
511 device_release_driver(dev); 522 device_release_driver(dev);
512 put_bus(dev->bus); 523 bus_put(dev->bus);
513 } 524 }
514} 525}
515 526
@@ -568,32 +579,29 @@ static void remove_bind_files(struct device_driver *drv)
568 driver_remove_file(drv, &driver_attr_unbind); 579 driver_remove_file(drv, &driver_attr_unbind);
569} 580}
570 581
582static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);
583static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,
584 show_drivers_autoprobe, store_drivers_autoprobe);
585
571static int add_probe_files(struct bus_type *bus) 586static int add_probe_files(struct bus_type *bus)
572{ 587{
573 int retval; 588 int retval;
574 589
575 bus->drivers_probe_attr.attr.name = "drivers_probe"; 590 retval = bus_create_file(bus, &bus_attr_drivers_probe);
576 bus->drivers_probe_attr.attr.mode = S_IWUSR;
577 bus->drivers_probe_attr.store = store_drivers_probe;
578 retval = bus_create_file(bus, &bus->drivers_probe_attr);
579 if (retval) 591 if (retval)
580 goto out; 592 goto out;
581 593
582 bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; 594 retval = bus_create_file(bus, &bus_attr_drivers_autoprobe);
583 bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
584 bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
585 bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
586 retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
587 if (retval) 595 if (retval)
588 bus_remove_file(bus, &bus->drivers_probe_attr); 596 bus_remove_file(bus, &bus_attr_drivers_probe);
589out: 597out:
590 return retval; 598 return retval;
591} 599}
592 600
593static void remove_probe_files(struct bus_type *bus) 601static void remove_probe_files(struct bus_type *bus)
594{ 602{
595 bus_remove_file(bus, &bus->drivers_autoprobe_attr); 603 bus_remove_file(bus, &bus_attr_drivers_autoprobe);
596 bus_remove_file(bus, &bus->drivers_probe_attr); 604 bus_remove_file(bus, &bus_attr_drivers_probe);
597} 605}
598#else 606#else
599static inline int add_bind_files(struct device_driver *drv) { return 0; } 607static inline int add_bind_files(struct device_driver *drv) { return 0; }
@@ -602,6 +610,17 @@ static inline int add_probe_files(struct bus_type *bus) { return 0; }
602static inline void remove_probe_files(struct bus_type *bus) {} 610static inline void remove_probe_files(struct bus_type *bus) {}
603#endif 611#endif
604 612
613static ssize_t driver_uevent_store(struct device_driver *drv,
614 const char *buf, size_t count)
615{
616 enum kobject_action action;
617
618 if (kobject_action_type(buf, count, &action) == 0)
619 kobject_uevent(&drv->kobj, action);
620 return count;
621}
622static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
623
605/** 624/**
606 * bus_add_driver - Add a driver to the bus. 625 * bus_add_driver - Add a driver to the bus.
607 * @drv: driver. 626 * @drv: driver.
@@ -609,7 +628,7 @@ static inline void remove_probe_files(struct bus_type *bus) {}
609 */ 628 */
610int bus_add_driver(struct device_driver *drv) 629int bus_add_driver(struct device_driver *drv)
611{ 630{
612 struct bus_type * bus = get_bus(drv->bus); 631 struct bus_type * bus = bus_get(drv->bus);
613 int error = 0; 632 int error = 0;
614 633
615 if (!bus) 634 if (!bus)
@@ -632,6 +651,11 @@ int bus_add_driver(struct device_driver *drv)
632 klist_add_tail(&drv->knode_bus, &bus->klist_drivers); 651 klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
633 module_add_driver(drv->owner, drv); 652 module_add_driver(drv->owner, drv);
634 653
654 error = driver_create_file(drv, &driver_attr_uevent);
655 if (error) {
656 printk(KERN_ERR "%s: uevent attr (%s) failed\n",
657 __FUNCTION__, drv->name);
658 }
635 error = driver_add_attrs(bus, drv); 659 error = driver_add_attrs(bus, drv);
636 if (error) { 660 if (error) {
637 /* How the hell do we get out of this pickle? Give up */ 661 /* How the hell do we get out of this pickle? Give up */
@@ -649,7 +673,7 @@ int bus_add_driver(struct device_driver *drv)
649out_unregister: 673out_unregister:
650 kobject_unregister(&drv->kobj); 674 kobject_unregister(&drv->kobj);
651out_put_bus: 675out_put_bus:
652 put_bus(bus); 676 bus_put(bus);
653 return error; 677 return error;
654} 678}
655 679
@@ -669,12 +693,13 @@ void bus_remove_driver(struct device_driver * drv)
669 693
670 remove_bind_files(drv); 694 remove_bind_files(drv);
671 driver_remove_attrs(drv->bus, drv); 695 driver_remove_attrs(drv->bus, drv);
696 driver_remove_file(drv, &driver_attr_uevent);
672 klist_remove(&drv->knode_bus); 697 klist_remove(&drv->knode_bus);
673 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 698 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
674 driver_detach(drv); 699 driver_detach(drv);
675 module_remove_driver(drv); 700 module_remove_driver(drv);
676 kobject_unregister(&drv->kobj); 701 kobject_unregister(&drv->kobj);
677 put_bus(drv->bus); 702 bus_put(drv->bus);
678} 703}
679 704
680 705
@@ -729,18 +754,6 @@ int device_reprobe(struct device *dev)
729} 754}
730EXPORT_SYMBOL_GPL(device_reprobe); 755EXPORT_SYMBOL_GPL(device_reprobe);
731 756
732struct bus_type *get_bus(struct bus_type *bus)
733{
734 return bus ? container_of(subsys_get(&bus->subsys),
735 struct bus_type, subsys) : NULL;
736}
737
738void put_bus(struct bus_type * bus)
739{
740 subsys_put(&bus->subsys);
741}
742
743
744/** 757/**
745 * find_bus - locate bus by name. 758 * find_bus - locate bus by name.
746 * @name: name of bus. 759 * @name: name of bus.
@@ -808,6 +821,17 @@ static void klist_devices_put(struct klist_node *n)
808 put_device(dev); 821 put_device(dev);
809} 822}
810 823
824static ssize_t bus_uevent_store(struct bus_type *bus,
825 const char *buf, size_t count)
826{
827 enum kobject_action action;
828
829 if (kobject_action_type(buf, count, &action) == 0)
830 kobject_uevent(&bus->subsys.kobj, action);
831 return count;
832}
833static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
834
811/** 835/**
812 * bus_register - register a bus with the system. 836 * bus_register - register a bus with the system.
813 * @bus: bus. 837 * @bus: bus.
@@ -826,11 +850,16 @@ int bus_register(struct bus_type * bus)
826 if (retval) 850 if (retval)
827 goto out; 851 goto out;
828 852
829 subsys_set_kset(bus, bus_subsys); 853 bus->subsys.kobj.kset = &bus_subsys;
854
830 retval = subsystem_register(&bus->subsys); 855 retval = subsystem_register(&bus->subsys);
831 if (retval) 856 if (retval)
832 goto out; 857 goto out;
833 858
859 retval = bus_create_file(bus, &bus_attr_uevent);
860 if (retval)
861 goto bus_uevent_fail;
862
834 kobject_set_name(&bus->devices.kobj, "devices"); 863 kobject_set_name(&bus->devices.kobj, "devices");
835 bus->devices.kobj.parent = &bus->subsys.kobj; 864 bus->devices.kobj.parent = &bus->subsys.kobj;
836 retval = kset_register(&bus->devices); 865 retval = kset_register(&bus->devices);
@@ -839,7 +868,7 @@ int bus_register(struct bus_type * bus)
839 868
840 kobject_set_name(&bus->drivers.kobj, "drivers"); 869 kobject_set_name(&bus->drivers.kobj, "drivers");
841 bus->drivers.kobj.parent = &bus->subsys.kobj; 870 bus->drivers.kobj.parent = &bus->subsys.kobj;
842 bus->drivers.ktype = &ktype_driver; 871 bus->drivers.ktype = &driver_ktype;
843 retval = kset_register(&bus->drivers); 872 retval = kset_register(&bus->drivers);
844 if (retval) 873 if (retval)
845 goto bus_drivers_fail; 874 goto bus_drivers_fail;
@@ -866,6 +895,8 @@ bus_probe_files_fail:
866bus_drivers_fail: 895bus_drivers_fail:
867 kset_unregister(&bus->devices); 896 kset_unregister(&bus->devices);
868bus_devices_fail: 897bus_devices_fail:
898 bus_remove_file(bus, &bus_attr_uevent);
899bus_uevent_fail:
869 subsystem_unregister(&bus->subsys); 900 subsystem_unregister(&bus->subsys);
870out: 901out:
871 return retval; 902 return retval;
@@ -876,7 +907,7 @@ out:
876 * @bus: bus. 907 * @bus: bus.
877 * 908 *
878 * Unregister the child subsystems and the bus itself. 909 * Unregister the child subsystems and the bus itself.
879 * Finally, we call put_bus() to release the refcount 910 * Finally, we call bus_put() to release the refcount
880 */ 911 */
881void bus_unregister(struct bus_type * bus) 912void bus_unregister(struct bus_type * bus)
882{ 913{
@@ -885,6 +916,7 @@ void bus_unregister(struct bus_type * bus)
885 remove_probe_files(bus); 916 remove_probe_files(bus);
886 kset_unregister(&bus->drivers); 917 kset_unregister(&bus->drivers);
887 kset_unregister(&bus->devices); 918 kset_unregister(&bus->devices);
919 bus_remove_file(bus, &bus_attr_uevent);
888 subsystem_unregister(&bus->subsys); 920 subsystem_unregister(&bus->subsys);
889} 921}
890 922