diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/attribute_container.c | 1 | ||||
-rw-r--r-- | drivers/base/base.h | 2 | ||||
-rw-r--r-- | drivers/base/bus.c | 24 | ||||
-rw-r--r-- | drivers/base/class.c | 46 | ||||
-rw-r--r-- | drivers/base/core.c | 58 | ||||
-rw-r--r-- | drivers/base/dd.c | 21 | ||||
-rw-r--r-- | drivers/base/devres.c | 2 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 6 | ||||
-rw-r--r-- | drivers/base/power/main.c | 44 | ||||
-rw-r--r-- | drivers/base/power/power.h | 4 | ||||
-rw-r--r-- | drivers/base/power/resume.c | 23 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 12 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 72 | ||||
-rw-r--r-- | drivers/base/sys.c | 24 |
14 files changed, 134 insertions, 205 deletions
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 1ec0654665cf..7370d7cf5988 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/mutex.h> | ||
21 | 22 | ||
22 | #include "base.h" | 23 | #include "base.h" |
23 | 24 | ||
diff --git a/drivers/base/base.h b/drivers/base/base.h index 5512d84452f2..47eb02d9f1af 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -44,6 +44,6 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) | |||
44 | 44 | ||
45 | extern char *make_class_name(const char *name, struct kobject *kobj); | 45 | extern char *make_class_name(const char *name, struct kobject *kobj); |
46 | 46 | ||
47 | extern void devres_release_all(struct device *dev); | 47 | extern int devres_release_all(struct device *dev); |
48 | 48 | ||
49 | extern struct kset devices_subsys; | 49 | extern struct kset devices_subsys; |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index dca734819e50..61c67526a656 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -138,12 +138,24 @@ void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) | |||
138 | } | 138 | } |
139 | } | 139 | } |
140 | 140 | ||
141 | static struct kobj_type ktype_bus = { | 141 | static struct kobj_type bus_ktype = { |
142 | .sysfs_ops = &bus_sysfs_ops, | 142 | .sysfs_ops = &bus_sysfs_ops, |
143 | }; | ||
144 | |||
145 | static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) | ||
146 | { | ||
147 | struct kobj_type *ktype = get_ktype(kobj); | ||
143 | 148 | ||
149 | if (ktype == &bus_ktype) | ||
150 | return 1; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static struct kset_uevent_ops bus_uevent_ops = { | ||
155 | .filter = bus_uevent_filter, | ||
144 | }; | 156 | }; |
145 | 157 | ||
146 | static decl_subsys(bus, &ktype_bus, NULL); | 158 | static decl_subsys(bus, &bus_ktype, &bus_uevent_ops); |
147 | 159 | ||
148 | 160 | ||
149 | #ifdef CONFIG_HOTPLUG | 161 | #ifdef CONFIG_HOTPLUG |
@@ -562,7 +574,6 @@ static int add_probe_files(struct bus_type *bus) | |||
562 | 574 | ||
563 | bus->drivers_probe_attr.attr.name = "drivers_probe"; | 575 | bus->drivers_probe_attr.attr.name = "drivers_probe"; |
564 | bus->drivers_probe_attr.attr.mode = S_IWUSR; | 576 | bus->drivers_probe_attr.attr.mode = S_IWUSR; |
565 | bus->drivers_probe_attr.attr.owner = bus->owner; | ||
566 | bus->drivers_probe_attr.store = store_drivers_probe; | 577 | bus->drivers_probe_attr.store = store_drivers_probe; |
567 | retval = bus_create_file(bus, &bus->drivers_probe_attr); | 578 | retval = bus_create_file(bus, &bus->drivers_probe_attr); |
568 | if (retval) | 579 | if (retval) |
@@ -570,7 +581,6 @@ static int add_probe_files(struct bus_type *bus) | |||
570 | 581 | ||
571 | bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; | 582 | bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; |
572 | bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO; | 583 | bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO; |
573 | bus->drivers_autoprobe_attr.attr.owner = bus->owner; | ||
574 | bus->drivers_autoprobe_attr.show = show_drivers_autoprobe; | 584 | bus->drivers_autoprobe_attr.show = show_drivers_autoprobe; |
575 | bus->drivers_autoprobe_attr.store = store_drivers_autoprobe; | 585 | bus->drivers_autoprobe_attr.store = store_drivers_autoprobe; |
576 | retval = bus_create_file(bus, &bus->drivers_autoprobe_attr); | 586 | retval = bus_create_file(bus, &bus->drivers_autoprobe_attr); |
@@ -610,7 +620,8 @@ int bus_add_driver(struct device_driver *drv) | |||
610 | if (error) | 620 | if (error) |
611 | goto out_put_bus; | 621 | goto out_put_bus; |
612 | drv->kobj.kset = &bus->drivers; | 622 | drv->kobj.kset = &bus->drivers; |
613 | if ((error = kobject_register(&drv->kobj))) | 623 | error = kobject_register(&drv->kobj); |
624 | if (error) | ||
614 | goto out_put_bus; | 625 | goto out_put_bus; |
615 | 626 | ||
616 | if (drv->bus->drivers_autoprobe) { | 627 | if (drv->bus->drivers_autoprobe) { |
@@ -760,7 +771,8 @@ static int bus_add_attrs(struct bus_type * bus) | |||
760 | 771 | ||
761 | if (bus->bus_attrs) { | 772 | if (bus->bus_attrs) { |
762 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 773 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { |
763 | if ((error = bus_create_file(bus,&bus->bus_attrs[i]))) | 774 | error = bus_create_file(bus,&bus->bus_attrs[i]); |
775 | if (error) | ||
764 | goto Err; | 776 | goto Err; |
765 | } | 777 | } |
766 | } | 778 | } |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 8c506dbe3913..4d2222618b78 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -312,9 +312,6 @@ static void class_dev_release(struct kobject * kobj) | |||
312 | 312 | ||
313 | pr_debug("device class '%s': release.\n", cd->class_id); | 313 | pr_debug("device class '%s': release.\n", cd->class_id); |
314 | 314 | ||
315 | kfree(cd->devt_attr); | ||
316 | cd->devt_attr = NULL; | ||
317 | |||
318 | if (cd->release) | 315 | if (cd->release) |
319 | cd->release(cd); | 316 | cd->release(cd); |
320 | else if (cls->release) | 317 | else if (cls->release) |
@@ -547,6 +544,9 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf) | |||
547 | return print_dev_t(buf, class_dev->devt); | 544 | return print_dev_t(buf, class_dev->devt); |
548 | } | 545 | } |
549 | 546 | ||
547 | static struct class_device_attribute class_devt_attr = | ||
548 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
549 | |||
550 | static ssize_t store_uevent(struct class_device *class_dev, | 550 | static ssize_t store_uevent(struct class_device *class_dev, |
551 | const char *buf, size_t count) | 551 | const char *buf, size_t count) |
552 | { | 552 | { |
@@ -554,6 +554,9 @@ static ssize_t store_uevent(struct class_device *class_dev, | |||
554 | return count; | 554 | return count; |
555 | } | 555 | } |
556 | 556 | ||
557 | static struct class_device_attribute class_uevent_attr = | ||
558 | __ATTR(uevent, S_IWUSR, NULL, store_uevent); | ||
559 | |||
557 | void class_device_initialize(struct class_device *class_dev) | 560 | void class_device_initialize(struct class_device *class_dev) |
558 | { | 561 | { |
559 | kobj_set_kset_s(class_dev, class_obj_subsys); | 562 | kobj_set_kset_s(class_dev, class_obj_subsys); |
@@ -603,32 +606,15 @@ int class_device_add(struct class_device *class_dev) | |||
603 | &parent_class->subsys.kobj, "subsystem"); | 606 | &parent_class->subsys.kobj, "subsystem"); |
604 | if (error) | 607 | if (error) |
605 | goto out3; | 608 | goto out3; |
606 | class_dev->uevent_attr.attr.name = "uevent"; | 609 | |
607 | class_dev->uevent_attr.attr.mode = S_IWUSR; | 610 | error = class_device_create_file(class_dev, &class_uevent_attr); |
608 | class_dev->uevent_attr.attr.owner = parent_class->owner; | ||
609 | class_dev->uevent_attr.store = store_uevent; | ||
610 | error = class_device_create_file(class_dev, &class_dev->uevent_attr); | ||
611 | if (error) | 611 | if (error) |
612 | goto out3; | 612 | goto out3; |
613 | 613 | ||
614 | if (MAJOR(class_dev->devt)) { | 614 | if (MAJOR(class_dev->devt)) { |
615 | struct class_device_attribute *attr; | 615 | error = class_device_create_file(class_dev, &class_devt_attr); |
616 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 616 | if (error) |
617 | if (!attr) { | ||
618 | error = -ENOMEM; | ||
619 | goto out4; | ||
620 | } | ||
621 | attr->attr.name = "dev"; | ||
622 | attr->attr.mode = S_IRUGO; | ||
623 | attr->attr.owner = parent_class->owner; | ||
624 | attr->show = show_dev; | ||
625 | error = class_device_create_file(class_dev, attr); | ||
626 | if (error) { | ||
627 | kfree(attr); | ||
628 | goto out4; | 617 | goto out4; |
629 | } | ||
630 | |||
631 | class_dev->devt_attr = attr; | ||
632 | } | 618 | } |
633 | 619 | ||
634 | error = class_device_add_attrs(class_dev); | 620 | error = class_device_add_attrs(class_dev); |
@@ -671,10 +657,10 @@ int class_device_add(struct class_device *class_dev) | |||
671 | out6: | 657 | out6: |
672 | class_device_remove_attrs(class_dev); | 658 | class_device_remove_attrs(class_dev); |
673 | out5: | 659 | out5: |
674 | if (class_dev->devt_attr) | 660 | if (MAJOR(class_dev->devt)) |
675 | class_device_remove_file(class_dev, class_dev->devt_attr); | 661 | class_device_remove_file(class_dev, &class_devt_attr); |
676 | out4: | 662 | out4: |
677 | class_device_remove_file(class_dev, &class_dev->uevent_attr); | 663 | class_device_remove_file(class_dev, &class_uevent_attr); |
678 | out3: | 664 | out3: |
679 | kobject_del(&class_dev->kobj); | 665 | kobject_del(&class_dev->kobj); |
680 | out2: | 666 | out2: |
@@ -774,9 +760,9 @@ void class_device_del(struct class_device *class_dev) | |||
774 | sysfs_remove_link(&class_dev->kobj, "device"); | 760 | sysfs_remove_link(&class_dev->kobj, "device"); |
775 | } | 761 | } |
776 | sysfs_remove_link(&class_dev->kobj, "subsystem"); | 762 | sysfs_remove_link(&class_dev->kobj, "subsystem"); |
777 | class_device_remove_file(class_dev, &class_dev->uevent_attr); | 763 | class_device_remove_file(class_dev, &class_uevent_attr); |
778 | if (class_dev->devt_attr) | 764 | if (MAJOR(class_dev->devt)) |
779 | class_device_remove_file(class_dev, class_dev->devt_attr); | 765 | class_device_remove_file(class_dev, &class_devt_attr); |
780 | class_device_remove_attrs(class_dev); | 766 | class_device_remove_attrs(class_dev); |
781 | class_device_remove_groups(class_dev); | 767 | class_device_remove_groups(class_dev); |
782 | 768 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index dd40d78a023d..0455aa78fa13 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -310,6 +310,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
310 | return count; | 310 | return count; |
311 | } | 311 | } |
312 | 312 | ||
313 | static struct device_attribute uevent_attr = | ||
314 | __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); | ||
315 | |||
313 | static int device_add_attributes(struct device *dev, | 316 | static int device_add_attributes(struct device *dev, |
314 | struct device_attribute *attrs) | 317 | struct device_attribute *attrs) |
315 | { | 318 | { |
@@ -423,6 +426,9 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | |||
423 | return print_dev_t(buf, dev->devt); | 426 | return print_dev_t(buf, dev->devt); |
424 | } | 427 | } |
425 | 428 | ||
429 | static struct device_attribute devt_attr = | ||
430 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
431 | |||
426 | /* | 432 | /* |
427 | * devices_subsys - structure to be registered with kobject core. | 433 | * devices_subsys - structure to be registered with kobject core. |
428 | */ | 434 | */ |
@@ -681,35 +687,14 @@ int device_add(struct device *dev) | |||
681 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 687 | blocking_notifier_call_chain(&dev->bus->bus_notifier, |
682 | BUS_NOTIFY_ADD_DEVICE, dev); | 688 | BUS_NOTIFY_ADD_DEVICE, dev); |
683 | 689 | ||
684 | dev->uevent_attr.attr.name = "uevent"; | 690 | error = device_create_file(dev, &uevent_attr); |
685 | dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
686 | if (dev->driver) | ||
687 | dev->uevent_attr.attr.owner = dev->driver->owner; | ||
688 | dev->uevent_attr.store = store_uevent; | ||
689 | dev->uevent_attr.show = show_uevent; | ||
690 | error = device_create_file(dev, &dev->uevent_attr); | ||
691 | if (error) | 691 | if (error) |
692 | goto attrError; | 692 | goto attrError; |
693 | 693 | ||
694 | if (MAJOR(dev->devt)) { | 694 | if (MAJOR(dev->devt)) { |
695 | struct device_attribute *attr; | 695 | error = device_create_file(dev, &devt_attr); |
696 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 696 | if (error) |
697 | if (!attr) { | ||
698 | error = -ENOMEM; | ||
699 | goto ueventattrError; | ||
700 | } | ||
701 | attr->attr.name = "dev"; | ||
702 | attr->attr.mode = S_IRUGO; | ||
703 | if (dev->driver) | ||
704 | attr->attr.owner = dev->driver->owner; | ||
705 | attr->show = show_dev; | ||
706 | error = device_create_file(dev, attr); | ||
707 | if (error) { | ||
708 | kfree(attr); | ||
709 | goto ueventattrError; | 697 | goto ueventattrError; |
710 | } | ||
711 | |||
712 | dev->devt_attr = attr; | ||
713 | } | 698 | } |
714 | 699 | ||
715 | if (dev->class) { | 700 | if (dev->class) { |
@@ -733,11 +718,14 @@ int device_add(struct device *dev) | |||
733 | } | 718 | } |
734 | } | 719 | } |
735 | 720 | ||
736 | if ((error = device_add_attrs(dev))) | 721 | error = device_add_attrs(dev); |
722 | if (error) | ||
737 | goto AttrsError; | 723 | goto AttrsError; |
738 | if ((error = device_pm_add(dev))) | 724 | error = device_pm_add(dev); |
725 | if (error) | ||
739 | goto PMError; | 726 | goto PMError; |
740 | if ((error = bus_add_device(dev))) | 727 | error = bus_add_device(dev); |
728 | if (error) | ||
741 | goto BusError; | 729 | goto BusError; |
742 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 730 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
743 | bus_attach_device(dev); | 731 | bus_attach_device(dev); |
@@ -767,10 +755,8 @@ int device_add(struct device *dev) | |||
767 | BUS_NOTIFY_DEL_DEVICE, dev); | 755 | BUS_NOTIFY_DEL_DEVICE, dev); |
768 | device_remove_attrs(dev); | 756 | device_remove_attrs(dev); |
769 | AttrsError: | 757 | AttrsError: |
770 | if (dev->devt_attr) { | 758 | if (MAJOR(dev->devt)) |
771 | device_remove_file(dev, dev->devt_attr); | 759 | device_remove_file(dev, &devt_attr); |
772 | kfree(dev->devt_attr); | ||
773 | } | ||
774 | 760 | ||
775 | if (dev->class) { | 761 | if (dev->class) { |
776 | sysfs_remove_link(&dev->kobj, "subsystem"); | 762 | sysfs_remove_link(&dev->kobj, "subsystem"); |
@@ -792,7 +778,7 @@ int device_add(struct device *dev) | |||
792 | } | 778 | } |
793 | } | 779 | } |
794 | ueventattrError: | 780 | ueventattrError: |
795 | device_remove_file(dev, &dev->uevent_attr); | 781 | device_remove_file(dev, &uevent_attr); |
796 | attrError: | 782 | attrError: |
797 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 783 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
798 | kobject_del(&dev->kobj); | 784 | kobject_del(&dev->kobj); |
@@ -869,10 +855,8 @@ void device_del(struct device * dev) | |||
869 | 855 | ||
870 | if (parent) | 856 | if (parent) |
871 | klist_del(&dev->knode_parent); | 857 | klist_del(&dev->knode_parent); |
872 | if (dev->devt_attr) { | 858 | if (MAJOR(dev->devt)) |
873 | device_remove_file(dev, dev->devt_attr); | 859 | device_remove_file(dev, &devt_attr); |
874 | kfree(dev->devt_attr); | ||
875 | } | ||
876 | if (dev->class) { | 860 | if (dev->class) { |
877 | sysfs_remove_link(&dev->kobj, "subsystem"); | 861 | sysfs_remove_link(&dev->kobj, "subsystem"); |
878 | /* If this is not a "fake" compatible device, remove the | 862 | /* If this is not a "fake" compatible device, remove the |
@@ -926,7 +910,7 @@ void device_del(struct device * dev) | |||
926 | up(&dev->class->sem); | 910 | up(&dev->class->sem); |
927 | } | 911 | } |
928 | } | 912 | } |
929 | device_remove_file(dev, &dev->uevent_attr); | 913 | device_remove_file(dev, &uevent_attr); |
930 | device_remove_attrs(dev); | 914 | device_remove_attrs(dev); |
931 | bus_remove_device(dev); | 915 | bus_remove_device(dev); |
932 | 916 | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index b0088b0efecd..7ac474db88c5 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -281,24 +281,16 @@ int driver_attach(struct device_driver * drv) | |||
281 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); | 281 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); |
282 | } | 282 | } |
283 | 283 | ||
284 | /** | 284 | /* |
285 | * device_release_driver - manually detach device from driver. | ||
286 | * @dev: device. | ||
287 | * | ||
288 | * Manually detach device from driver. | ||
289 | * | ||
290 | * __device_release_driver() must be called with @dev->sem held. | 285 | * __device_release_driver() must be called with @dev->sem held. |
291 | * When called for a USB interface, @dev->parent->sem must be held | 286 | * When called for a USB interface, @dev->parent->sem must be held as well. |
292 | * as well. | ||
293 | */ | 287 | */ |
294 | |||
295 | static void __device_release_driver(struct device * dev) | 288 | static void __device_release_driver(struct device * dev) |
296 | { | 289 | { |
297 | struct device_driver * drv; | 290 | struct device_driver * drv; |
298 | 291 | ||
299 | drv = dev->driver; | 292 | drv = get_driver(dev->driver); |
300 | if (drv) { | 293 | if (drv) { |
301 | get_driver(drv); | ||
302 | driver_sysfs_remove(dev); | 294 | driver_sysfs_remove(dev); |
303 | sysfs_remove_link(&dev->kobj, "driver"); | 295 | sysfs_remove_link(&dev->kobj, "driver"); |
304 | klist_remove(&dev->knode_driver); | 296 | klist_remove(&dev->knode_driver); |
@@ -318,6 +310,13 @@ static void __device_release_driver(struct device * dev) | |||
318 | } | 310 | } |
319 | } | 311 | } |
320 | 312 | ||
313 | /** | ||
314 | * device_release_driver - manually detach device from driver. | ||
315 | * @dev: device. | ||
316 | * | ||
317 | * Manually detach device from driver. | ||
318 | * When called for a USB interface, @dev->parent->sem must be held. | ||
319 | */ | ||
321 | void device_release_driver(struct device * dev) | 320 | void device_release_driver(struct device * dev) |
322 | { | 321 | { |
323 | /* | 322 | /* |
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index e1c0730a3b99..e8beb8e5b626 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | 12 | ||
13 | #include "base.h" | ||
14 | |||
13 | struct devres_node { | 15 | struct devres_node { |
14 | struct list_head entry; | 16 | struct list_head entry; |
15 | dr_release_t release; | 17 | dr_release_t release; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 89a5f4a54913..53f0ee6f3016 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -175,7 +175,7 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
175 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); | 175 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); |
176 | 176 | ||
177 | static ssize_t | 177 | static ssize_t |
178 | firmware_data_read(struct kobject *kobj, | 178 | firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, |
179 | char *buffer, loff_t offset, size_t count) | 179 | char *buffer, loff_t offset, size_t count) |
180 | { | 180 | { |
181 | struct device *dev = to_dev(kobj); | 181 | struct device *dev = to_dev(kobj); |
@@ -240,7 +240,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) | |||
240 | * the driver as a firmware image. | 240 | * the driver as a firmware image. |
241 | **/ | 241 | **/ |
242 | static ssize_t | 242 | static ssize_t |
243 | firmware_data_write(struct kobject *kobj, | 243 | firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr, |
244 | char *buffer, loff_t offset, size_t count) | 244 | char *buffer, loff_t offset, size_t count) |
245 | { | 245 | { |
246 | struct device *dev = to_dev(kobj); | 246 | struct device *dev = to_dev(kobj); |
@@ -271,7 +271,7 @@ out: | |||
271 | } | 271 | } |
272 | 272 | ||
273 | static struct bin_attribute firmware_attr_data_tmpl = { | 273 | static struct bin_attribute firmware_attr_data_tmpl = { |
274 | .attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE}, | 274 | .attr = {.name = "data", .mode = 0644}, |
275 | .size = 0, | 275 | .size = 0, |
276 | .read = firmware_data_read, | 276 | .read = firmware_data_read, |
277 | .write = firmware_data_write, | 277 | .write = firmware_data_write, |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 05dc8764e765..eb9f38d0aa58 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -20,64 +20,44 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/mutex.h> | ||
24 | |||
23 | #include "power.h" | 25 | #include "power.h" |
24 | 26 | ||
25 | LIST_HEAD(dpm_active); | 27 | LIST_HEAD(dpm_active); |
26 | LIST_HEAD(dpm_off); | 28 | LIST_HEAD(dpm_off); |
27 | LIST_HEAD(dpm_off_irq); | 29 | LIST_HEAD(dpm_off_irq); |
28 | 30 | ||
29 | DECLARE_MUTEX(dpm_sem); | 31 | DEFINE_MUTEX(dpm_mtx); |
30 | DECLARE_MUTEX(dpm_list_sem); | 32 | DEFINE_MUTEX(dpm_list_mtx); |
31 | 33 | ||
32 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | 34 | int (*platform_enable_wakeup)(struct device *dev, int is_on); |
33 | 35 | ||
34 | 36 | int device_pm_add(struct device *dev) | |
35 | /** | ||
36 | * device_pm_set_parent - Specify power dependency. | ||
37 | * @dev: Device who needs power. | ||
38 | * @parent: Device that supplies power. | ||
39 | * | ||
40 | * This function is used to manually describe a power-dependency | ||
41 | * relationship. It may be used to specify a transversal relationship | ||
42 | * (where the power supplier is not the physical (or electrical) | ||
43 | * ancestor of a specific device. | ||
44 | * The effect of this is that the supplier will not be powered down | ||
45 | * before the power dependent. | ||
46 | */ | ||
47 | |||
48 | void device_pm_set_parent(struct device * dev, struct device * parent) | ||
49 | { | ||
50 | put_device(dev->power.pm_parent); | ||
51 | dev->power.pm_parent = get_device(parent); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(device_pm_set_parent); | ||
54 | |||
55 | int device_pm_add(struct device * dev) | ||
56 | { | 37 | { |
57 | int error; | 38 | int error; |
58 | 39 | ||
59 | pr_debug("PM: Adding info for %s:%s\n", | 40 | pr_debug("PM: Adding info for %s:%s\n", |
60 | dev->bus ? dev->bus->name : "No Bus", | 41 | dev->bus ? dev->bus->name : "No Bus", |
61 | kobject_name(&dev->kobj)); | 42 | kobject_name(&dev->kobj)); |
62 | down(&dpm_list_sem); | 43 | mutex_lock(&dpm_list_mtx); |
63 | list_add_tail(&dev->power.entry, &dpm_active); | 44 | list_add_tail(&dev->power.entry, &dpm_active); |
64 | device_pm_set_parent(dev, dev->parent); | 45 | error = dpm_sysfs_add(dev); |
65 | if ((error = dpm_sysfs_add(dev))) | 46 | if (error) |
66 | list_del(&dev->power.entry); | 47 | list_del(&dev->power.entry); |
67 | up(&dpm_list_sem); | 48 | mutex_unlock(&dpm_list_mtx); |
68 | return error; | 49 | return error; |
69 | } | 50 | } |
70 | 51 | ||
71 | void device_pm_remove(struct device * dev) | 52 | void device_pm_remove(struct device *dev) |
72 | { | 53 | { |
73 | pr_debug("PM: Removing info for %s:%s\n", | 54 | pr_debug("PM: Removing info for %s:%s\n", |
74 | dev->bus ? dev->bus->name : "No Bus", | 55 | dev->bus ? dev->bus->name : "No Bus", |
75 | kobject_name(&dev->kobj)); | 56 | kobject_name(&dev->kobj)); |
76 | down(&dpm_list_sem); | 57 | mutex_lock(&dpm_list_mtx); |
77 | dpm_sysfs_remove(dev); | 58 | dpm_sysfs_remove(dev); |
78 | put_device(dev->power.pm_parent); | ||
79 | list_del_init(&dev->power.entry); | 59 | list_del_init(&dev->power.entry); |
80 | up(&dpm_list_sem); | 60 | mutex_unlock(&dpm_list_mtx); |
81 | } | 61 | } |
82 | 62 | ||
83 | 63 | ||
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index fb3d35a9e101..2760f25b3ac5 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -14,12 +14,12 @@ extern void device_shutdown(void); | |||
14 | /* | 14 | /* |
15 | * Used to synchronize global power management operations. | 15 | * Used to synchronize global power management operations. |
16 | */ | 16 | */ |
17 | extern struct semaphore dpm_sem; | 17 | extern struct mutex dpm_mtx; |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * Used to serialize changes to the dpm_* lists. | 20 | * Used to serialize changes to the dpm_* lists. |
21 | */ | 21 | */ |
22 | extern struct semaphore dpm_list_sem; | 22 | extern struct mutex dpm_list_mtx; |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * The PM lists. | 25 | * The PM lists. |
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index a2c64188d713..00fd84ae6e66 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
@@ -29,14 +29,6 @@ int resume_device(struct device * dev) | |||
29 | 29 | ||
30 | down(&dev->sem); | 30 | down(&dev->sem); |
31 | 31 | ||
32 | if (dev->power.pm_parent | ||
33 | && dev->power.pm_parent->power.power_state.event) { | ||
34 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", | ||
35 | dev->power.power_state.event, | ||
36 | dev->power.pm_parent->bus_id, | ||
37 | dev->power.pm_parent->power.power_state.event); | ||
38 | } | ||
39 | |||
40 | if (dev->bus && dev->bus->resume) { | 32 | if (dev->bus && dev->bus->resume) { |
41 | dev_dbg(dev,"resuming\n"); | 33 | dev_dbg(dev,"resuming\n"); |
42 | error = dev->bus->resume(dev); | 34 | error = dev->bus->resume(dev); |
@@ -80,7 +72,7 @@ static int resume_device_early(struct device * dev) | |||
80 | */ | 72 | */ |
81 | void dpm_resume(void) | 73 | void dpm_resume(void) |
82 | { | 74 | { |
83 | down(&dpm_list_sem); | 75 | mutex_lock(&dpm_list_mtx); |
84 | while(!list_empty(&dpm_off)) { | 76 | while(!list_empty(&dpm_off)) { |
85 | struct list_head * entry = dpm_off.next; | 77 | struct list_head * entry = dpm_off.next; |
86 | struct device * dev = to_device(entry); | 78 | struct device * dev = to_device(entry); |
@@ -88,13 +80,12 @@ void dpm_resume(void) | |||
88 | get_device(dev); | 80 | get_device(dev); |
89 | list_move_tail(entry, &dpm_active); | 81 | list_move_tail(entry, &dpm_active); |
90 | 82 | ||
91 | up(&dpm_list_sem); | 83 | mutex_unlock(&dpm_list_mtx); |
92 | if (!dev->power.prev_state.event) | 84 | resume_device(dev); |
93 | resume_device(dev); | 85 | mutex_lock(&dpm_list_mtx); |
94 | down(&dpm_list_sem); | ||
95 | put_device(dev); | 86 | put_device(dev); |
96 | } | 87 | } |
97 | up(&dpm_list_sem); | 88 | mutex_unlock(&dpm_list_mtx); |
98 | } | 89 | } |
99 | 90 | ||
100 | 91 | ||
@@ -108,9 +99,9 @@ void dpm_resume(void) | |||
108 | void device_resume(void) | 99 | void device_resume(void) |
109 | { | 100 | { |
110 | might_sleep(); | 101 | might_sleep(); |
111 | down(&dpm_sem); | 102 | mutex_lock(&dpm_mtx); |
112 | dpm_resume(); | 103 | dpm_resume(); |
113 | up(&dpm_sem); | 104 | mutex_unlock(&dpm_mtx); |
114 | } | 105 | } |
115 | 106 | ||
116 | EXPORT_SYMBOL_GPL(device_resume); | 107 | EXPORT_SYMBOL_GPL(device_resume); |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 96370ec1d673..df6174d85866 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -32,9 +32,9 @@ static void runtime_resume(struct device * dev) | |||
32 | 32 | ||
33 | void dpm_runtime_resume(struct device * dev) | 33 | void dpm_runtime_resume(struct device * dev) |
34 | { | 34 | { |
35 | down(&dpm_sem); | 35 | mutex_lock(&dpm_mtx); |
36 | runtime_resume(dev); | 36 | runtime_resume(dev); |
37 | up(&dpm_sem); | 37 | mutex_unlock(&dpm_mtx); |
38 | } | 38 | } |
39 | EXPORT_SYMBOL(dpm_runtime_resume); | 39 | EXPORT_SYMBOL(dpm_runtime_resume); |
40 | 40 | ||
@@ -49,7 +49,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state) | |||
49 | { | 49 | { |
50 | int error = 0; | 50 | int error = 0; |
51 | 51 | ||
52 | down(&dpm_sem); | 52 | mutex_lock(&dpm_mtx); |
53 | if (dev->power.power_state.event == state.event) | 53 | if (dev->power.power_state.event == state.event) |
54 | goto Done; | 54 | goto Done; |
55 | 55 | ||
@@ -59,7 +59,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state) | |||
59 | if (!(error = suspend_device(dev, state))) | 59 | if (!(error = suspend_device(dev, state))) |
60 | dev->power.power_state = state; | 60 | dev->power.power_state = state; |
61 | Done: | 61 | Done: |
62 | up(&dpm_sem); | 62 | mutex_unlock(&dpm_mtx); |
63 | return error; | 63 | return error; |
64 | } | 64 | } |
65 | EXPORT_SYMBOL(dpm_runtime_suspend); | 65 | EXPORT_SYMBOL(dpm_runtime_suspend); |
@@ -78,8 +78,8 @@ EXPORT_SYMBOL(dpm_runtime_suspend); | |||
78 | */ | 78 | */ |
79 | void dpm_set_power_state(struct device * dev, pm_message_t state) | 79 | void dpm_set_power_state(struct device * dev, pm_message_t state) |
80 | { | 80 | { |
81 | down(&dpm_sem); | 81 | mutex_lock(&dpm_mtx); |
82 | dev->power.power_state = state; | 82 | dev->power.power_state = state; |
83 | up(&dpm_sem); | 83 | mutex_unlock(&dpm_mtx); |
84 | } | 84 | } |
85 | #endif /* 0 */ | 85 | #endif /* 0 */ |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 42d2b86ba765..26df9b231737 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -40,6 +40,14 @@ static inline char *suspend_verb(u32 event) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | 42 | ||
43 | static void | ||
44 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | ||
45 | { | ||
46 | dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event), | ||
47 | ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ? | ||
48 | ", may wakeup" : ""); | ||
49 | } | ||
50 | |||
43 | /** | 51 | /** |
44 | * suspend_device - Save state of one device. | 52 | * suspend_device - Save state of one device. |
45 | * @dev: Device. | 53 | * @dev: Device. |
@@ -55,49 +63,21 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
55 | dev_dbg(dev, "PM: suspend %d-->%d\n", | 63 | dev_dbg(dev, "PM: suspend %d-->%d\n", |
56 | dev->power.power_state.event, state.event); | 64 | dev->power.power_state.event, state.event); |
57 | } | 65 | } |
58 | if (dev->power.pm_parent | ||
59 | && dev->power.pm_parent->power.power_state.event) { | ||
60 | dev_err(dev, | ||
61 | "PM: suspend %d->%d, parent %s already %d\n", | ||
62 | dev->power.power_state.event, state.event, | ||
63 | dev->power.pm_parent->bus_id, | ||
64 | dev->power.pm_parent->power.power_state.event); | ||
65 | } | ||
66 | |||
67 | dev->power.prev_state = dev->power.power_state; | ||
68 | 66 | ||
69 | if (dev->class && dev->class->suspend && !dev->power.power_state.event) { | 67 | if (dev->class && dev->class->suspend) { |
70 | dev_dbg(dev, "class %s%s\n", | 68 | suspend_device_dbg(dev, state, "class "); |
71 | suspend_verb(state.event), | ||
72 | ((state.event == PM_EVENT_SUSPEND) | ||
73 | && device_may_wakeup(dev)) | ||
74 | ? ", may wakeup" | ||
75 | : "" | ||
76 | ); | ||
77 | error = dev->class->suspend(dev, state); | 69 | error = dev->class->suspend(dev, state); |
78 | suspend_report_result(dev->class->suspend, error); | 70 | suspend_report_result(dev->class->suspend, error); |
79 | } | 71 | } |
80 | 72 | ||
81 | if (!error && dev->type && dev->type->suspend && !dev->power.power_state.event) { | 73 | if (!error && dev->type && dev->type->suspend) { |
82 | dev_dbg(dev, "%s%s\n", | 74 | suspend_device_dbg(dev, state, "type "); |
83 | suspend_verb(state.event), | ||
84 | ((state.event == PM_EVENT_SUSPEND) | ||
85 | && device_may_wakeup(dev)) | ||
86 | ? ", may wakeup" | ||
87 | : "" | ||
88 | ); | ||
89 | error = dev->type->suspend(dev, state); | 75 | error = dev->type->suspend(dev, state); |
90 | suspend_report_result(dev->type->suspend, error); | 76 | suspend_report_result(dev->type->suspend, error); |
91 | } | 77 | } |
92 | 78 | ||
93 | if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) { | 79 | if (!error && dev->bus && dev->bus->suspend) { |
94 | dev_dbg(dev, "%s%s\n", | 80 | suspend_device_dbg(dev, state, ""); |
95 | suspend_verb(state.event), | ||
96 | ((state.event == PM_EVENT_SUSPEND) | ||
97 | && device_may_wakeup(dev)) | ||
98 | ? ", may wakeup" | ||
99 | : "" | ||
100 | ); | ||
101 | error = dev->bus->suspend(dev, state); | 81 | error = dev->bus->suspend(dev, state); |
102 | suspend_report_result(dev->bus->suspend, error); | 82 | suspend_report_result(dev->bus->suspend, error); |
103 | } | 83 | } |
@@ -108,21 +88,15 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
108 | 88 | ||
109 | /* | 89 | /* |
110 | * This is called with interrupts off, only a single CPU | 90 | * This is called with interrupts off, only a single CPU |
111 | * running. We can't do down() on a semaphore (and we don't | 91 | * running. We can't acquire a mutex or semaphore (and we don't |
112 | * need the protection) | 92 | * need the protection) |
113 | */ | 93 | */ |
114 | static int suspend_device_late(struct device *dev, pm_message_t state) | 94 | static int suspend_device_late(struct device *dev, pm_message_t state) |
115 | { | 95 | { |
116 | int error = 0; | 96 | int error = 0; |
117 | 97 | ||
118 | if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) { | 98 | if (dev->bus && dev->bus->suspend_late) { |
119 | dev_dbg(dev, "LATE %s%s\n", | 99 | suspend_device_dbg(dev, state, "LATE "); |
120 | suspend_verb(state.event), | ||
121 | ((state.event == PM_EVENT_SUSPEND) | ||
122 | && device_may_wakeup(dev)) | ||
123 | ? ", may wakeup" | ||
124 | : "" | ||
125 | ); | ||
126 | error = dev->bus->suspend_late(dev, state); | 100 | error = dev->bus->suspend_late(dev, state); |
127 | suspend_report_result(dev->bus->suspend_late, error); | 101 | suspend_report_result(dev->bus->suspend_late, error); |
128 | } | 102 | } |
@@ -153,18 +127,18 @@ int device_suspend(pm_message_t state) | |||
153 | int error = 0; | 127 | int error = 0; |
154 | 128 | ||
155 | might_sleep(); | 129 | might_sleep(); |
156 | down(&dpm_sem); | 130 | mutex_lock(&dpm_mtx); |
157 | down(&dpm_list_sem); | 131 | mutex_lock(&dpm_list_mtx); |
158 | while (!list_empty(&dpm_active) && error == 0) { | 132 | while (!list_empty(&dpm_active) && error == 0) { |
159 | struct list_head * entry = dpm_active.prev; | 133 | struct list_head * entry = dpm_active.prev; |
160 | struct device * dev = to_device(entry); | 134 | struct device * dev = to_device(entry); |
161 | 135 | ||
162 | get_device(dev); | 136 | get_device(dev); |
163 | up(&dpm_list_sem); | 137 | mutex_unlock(&dpm_list_mtx); |
164 | 138 | ||
165 | error = suspend_device(dev, state); | 139 | error = suspend_device(dev, state); |
166 | 140 | ||
167 | down(&dpm_list_sem); | 141 | mutex_lock(&dpm_list_mtx); |
168 | 142 | ||
169 | /* Check if the device got removed */ | 143 | /* Check if the device got removed */ |
170 | if (!list_empty(&dev->power.entry)) { | 144 | if (!list_empty(&dev->power.entry)) { |
@@ -179,11 +153,11 @@ int device_suspend(pm_message_t state) | |||
179 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); | 153 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); |
180 | put_device(dev); | 154 | put_device(dev); |
181 | } | 155 | } |
182 | up(&dpm_list_sem); | 156 | mutex_unlock(&dpm_list_mtx); |
183 | if (error) | 157 | if (error) |
184 | dpm_resume(); | 158 | dpm_resume(); |
185 | 159 | ||
186 | up(&dpm_sem); | 160 | mutex_unlock(&dpm_mtx); |
187 | return error; | 161 | return error; |
188 | } | 162 | } |
189 | 163 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 29f1291966c1..18febe26caa1 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <asm/semaphore.h> | 24 | #include <linux/mutex.h> |
25 | 25 | ||
26 | #include "base.h" | 26 | #include "base.h" |
27 | 27 | ||
@@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_unregister); | |||
155 | 155 | ||
156 | 156 | ||
157 | static LIST_HEAD(sysdev_drivers); | 157 | static LIST_HEAD(sysdev_drivers); |
158 | static DECLARE_MUTEX(sysdev_drivers_lock); | 158 | static DEFINE_MUTEX(sysdev_drivers_lock); |
159 | 159 | ||
160 | /** | 160 | /** |
161 | * sysdev_driver_register - Register auxillary driver | 161 | * sysdev_driver_register - Register auxillary driver |
@@ -172,7 +172,7 @@ static DECLARE_MUTEX(sysdev_drivers_lock); | |||
172 | int sysdev_driver_register(struct sysdev_class * cls, | 172 | int sysdev_driver_register(struct sysdev_class * cls, |
173 | struct sysdev_driver * drv) | 173 | struct sysdev_driver * drv) |
174 | { | 174 | { |
175 | down(&sysdev_drivers_lock); | 175 | mutex_lock(&sysdev_drivers_lock); |
176 | if (cls && kset_get(&cls->kset)) { | 176 | if (cls && kset_get(&cls->kset)) { |
177 | list_add_tail(&drv->entry, &cls->drivers); | 177 | list_add_tail(&drv->entry, &cls->drivers); |
178 | 178 | ||
@@ -184,7 +184,7 @@ int sysdev_driver_register(struct sysdev_class * cls, | |||
184 | } | 184 | } |
185 | } else | 185 | } else |
186 | list_add_tail(&drv->entry, &sysdev_drivers); | 186 | list_add_tail(&drv->entry, &sysdev_drivers); |
187 | up(&sysdev_drivers_lock); | 187 | mutex_unlock(&sysdev_drivers_lock); |
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
190 | 190 | ||
@@ -197,7 +197,7 @@ int sysdev_driver_register(struct sysdev_class * cls, | |||
197 | void sysdev_driver_unregister(struct sysdev_class * cls, | 197 | void sysdev_driver_unregister(struct sysdev_class * cls, |
198 | struct sysdev_driver * drv) | 198 | struct sysdev_driver * drv) |
199 | { | 199 | { |
200 | down(&sysdev_drivers_lock); | 200 | mutex_lock(&sysdev_drivers_lock); |
201 | list_del_init(&drv->entry); | 201 | list_del_init(&drv->entry); |
202 | if (cls) { | 202 | if (cls) { |
203 | if (drv->remove) { | 203 | if (drv->remove) { |
@@ -207,7 +207,7 @@ void sysdev_driver_unregister(struct sysdev_class * cls, | |||
207 | } | 207 | } |
208 | kset_put(&cls->kset); | 208 | kset_put(&cls->kset); |
209 | } | 209 | } |
210 | up(&sysdev_drivers_lock); | 210 | mutex_unlock(&sysdev_drivers_lock); |
211 | } | 211 | } |
212 | 212 | ||
213 | EXPORT_SYMBOL_GPL(sysdev_driver_register); | 213 | EXPORT_SYMBOL_GPL(sysdev_driver_register); |
@@ -246,7 +246,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
246 | if (!error) { | 246 | if (!error) { |
247 | struct sysdev_driver * drv; | 247 | struct sysdev_driver * drv; |
248 | 248 | ||
249 | down(&sysdev_drivers_lock); | 249 | mutex_lock(&sysdev_drivers_lock); |
250 | /* Generic notification is implicit, because it's that | 250 | /* Generic notification is implicit, because it's that |
251 | * code that should have called us. | 251 | * code that should have called us. |
252 | */ | 252 | */ |
@@ -262,7 +262,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
262 | if (drv->add) | 262 | if (drv->add) |
263 | drv->add(sysdev); | 263 | drv->add(sysdev); |
264 | } | 264 | } |
265 | up(&sysdev_drivers_lock); | 265 | mutex_unlock(&sysdev_drivers_lock); |
266 | } | 266 | } |
267 | return error; | 267 | return error; |
268 | } | 268 | } |
@@ -271,7 +271,7 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
271 | { | 271 | { |
272 | struct sysdev_driver * drv; | 272 | struct sysdev_driver * drv; |
273 | 273 | ||
274 | down(&sysdev_drivers_lock); | 274 | mutex_lock(&sysdev_drivers_lock); |
275 | list_for_each_entry(drv, &sysdev_drivers, entry) { | 275 | list_for_each_entry(drv, &sysdev_drivers, entry) { |
276 | if (drv->remove) | 276 | if (drv->remove) |
277 | drv->remove(sysdev); | 277 | drv->remove(sysdev); |
@@ -281,7 +281,7 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
281 | if (drv->remove) | 281 | if (drv->remove) |
282 | drv->remove(sysdev); | 282 | drv->remove(sysdev); |
283 | } | 283 | } |
284 | up(&sysdev_drivers_lock); | 284 | mutex_unlock(&sysdev_drivers_lock); |
285 | 285 | ||
286 | kobject_unregister(&sysdev->kobj); | 286 | kobject_unregister(&sysdev->kobj); |
287 | } | 287 | } |
@@ -308,7 +308,7 @@ void sysdev_shutdown(void) | |||
308 | 308 | ||
309 | pr_debug("Shutting Down System Devices\n"); | 309 | pr_debug("Shutting Down System Devices\n"); |
310 | 310 | ||
311 | down(&sysdev_drivers_lock); | 311 | mutex_lock(&sysdev_drivers_lock); |
312 | list_for_each_entry_reverse(cls, &system_subsys.list, | 312 | list_for_each_entry_reverse(cls, &system_subsys.list, |
313 | kset.kobj.entry) { | 313 | kset.kobj.entry) { |
314 | struct sys_device * sysdev; | 314 | struct sys_device * sysdev; |
@@ -337,7 +337,7 @@ void sysdev_shutdown(void) | |||
337 | cls->shutdown(sysdev); | 337 | cls->shutdown(sysdev); |
338 | } | 338 | } |
339 | } | 339 | } |
340 | up(&sysdev_drivers_lock); | 340 | mutex_unlock(&sysdev_drivers_lock); |
341 | } | 341 | } |
342 | 342 | ||
343 | static void __sysdev_resume(struct sys_device *dev) | 343 | static void __sysdev_resume(struct sys_device *dev) |