diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/bus.c | 5 | ||||
-rw-r--r-- | drivers/base/class.c | 45 | ||||
-rw-r--r-- | drivers/base/dd.c | 2 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 39 | ||||
-rw-r--r-- | drivers/base/power/suspend.c | 17 | ||||
-rw-r--r-- | drivers/base/topology.c | 2 |
6 files changed, 66 insertions, 44 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 48718b7f4fa0..76656acd00d4 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
188 | up(&dev->sem); | 188 | up(&dev->sem); |
189 | if (dev->parent) | 189 | if (dev->parent) |
190 | up(&dev->parent->sem); | 190 | up(&dev->parent->sem); |
191 | |||
192 | if (err > 0) /* success */ | ||
193 | err = count; | ||
194 | else if (err == 0) /* driver didn't accept device */ | ||
195 | err = -ENODEV; | ||
191 | } | 196 | } |
192 | put_device(dev); | 197 | put_device(dev); |
193 | put_bus(bus); | 198 | put_bus(bus); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index df7fdabd0730..b1ea4df85c7d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd) | |||
456 | } | 456 | } |
457 | } | 457 | } |
458 | 458 | ||
459 | static int class_device_add_groups(struct class_device * cd) | ||
460 | { | ||
461 | int i; | ||
462 | int error = 0; | ||
463 | |||
464 | if (cd->groups) { | ||
465 | for (i = 0; cd->groups[i]; i++) { | ||
466 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); | ||
467 | if (error) { | ||
468 | while (--i >= 0) | ||
469 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
470 | goto out; | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | out: | ||
475 | return error; | ||
476 | } | ||
477 | |||
478 | static void class_device_remove_groups(struct class_device * cd) | ||
479 | { | ||
480 | int i; | ||
481 | if (cd->groups) { | ||
482 | for (i = 0; cd->groups[i]; i++) { | ||
483 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
484 | } | ||
485 | } | ||
486 | } | ||
487 | |||
459 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | 488 | static ssize_t show_dev(struct class_device *class_dev, char *buf) |
460 | { | 489 | { |
461 | return print_dev_t(buf, class_dev->devt); | 490 | return print_dev_t(buf, class_dev->devt); |
@@ -559,17 +588,18 @@ int class_device_add(struct class_device *class_dev) | |||
559 | class_name); | 588 | class_name); |
560 | } | 589 | } |
561 | 590 | ||
591 | class_device_add_groups(class_dev); | ||
592 | |||
562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 593 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
563 | 594 | ||
564 | /* notify any interfaces this device is now here */ | 595 | /* notify any interfaces this device is now here */ |
565 | if (parent_class) { | 596 | down(&parent_class->sem); |
566 | down(&parent_class->sem); | 597 | list_add_tail(&class_dev->node, &parent_class->children); |
567 | list_add_tail(&class_dev->node, &parent_class->children); | 598 | list_for_each_entry(class_intf, &parent_class->interfaces, node) { |
568 | list_for_each_entry(class_intf, &parent_class->interfaces, node) | 599 | if (class_intf->add) |
569 | if (class_intf->add) | 600 | class_intf->add(class_dev, class_intf); |
570 | class_intf->add(class_dev, class_intf); | ||
571 | up(&parent_class->sem); | ||
572 | } | 601 | } |
602 | up(&parent_class->sem); | ||
573 | 603 | ||
574 | register_done: | 604 | register_done: |
575 | if (error) { | 605 | if (error) { |
@@ -673,6 +703,7 @@ void class_device_del(struct class_device *class_dev) | |||
673 | if (class_dev->devt_attr) | 703 | if (class_dev->devt_attr) |
674 | class_device_remove_file(class_dev, class_dev->devt_attr); | 704 | class_device_remove_file(class_dev, class_dev->devt_attr); |
675 | class_device_remove_attrs(class_dev); | 705 | class_device_remove_attrs(class_dev); |
706 | class_device_remove_groups(class_dev); | ||
676 | 707 | ||
677 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); | 708 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); |
678 | kobject_del(&class_dev->kobj); | 709 | kobject_del(&class_dev->kobj); |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 730a9ce0a14a..889c71111239 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -209,7 +209,7 @@ static void __device_release_driver(struct device * dev) | |||
209 | sysfs_remove_link(&dev->kobj, "driver"); | 209 | sysfs_remove_link(&dev->kobj, "driver"); |
210 | klist_remove(&dev->knode_driver); | 210 | klist_remove(&dev->knode_driver); |
211 | 211 | ||
212 | if (dev->bus->remove) | 212 | if (dev->bus && dev->bus->remove) |
213 | dev->bus->remove(dev); | 213 | dev->bus->remove(dev); |
214 | else if (drv->remove) | 214 | else if (drv->remove) |
215 | drv->remove(dev); | 215 | drv->remove(dev); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 472318205236..0c99ae6a3407 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -86,18 +86,9 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) | |||
86 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); | 86 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); |
87 | 87 | ||
88 | static void fw_class_dev_release(struct class_device *class_dev); | 88 | static void fw_class_dev_release(struct class_device *class_dev); |
89 | int firmware_class_uevent(struct class_device *dev, char **envp, | ||
90 | int num_envp, char *buffer, int buffer_size); | ||
91 | 89 | ||
92 | static struct class firmware_class = { | 90 | static int firmware_class_uevent(struct class_device *class_dev, char **envp, |
93 | .name = "firmware", | 91 | int num_envp, char *buffer, int buffer_size) |
94 | .uevent = firmware_class_uevent, | ||
95 | .release = fw_class_dev_release, | ||
96 | }; | ||
97 | |||
98 | int | ||
99 | firmware_class_uevent(struct class_device *class_dev, char **envp, | ||
100 | int num_envp, char *buffer, int buffer_size) | ||
101 | { | 92 | { |
102 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 93 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); |
103 | int i = 0, len = 0; | 94 | int i = 0, len = 0; |
@@ -116,6 +107,12 @@ firmware_class_uevent(struct class_device *class_dev, char **envp, | |||
116 | return 0; | 107 | return 0; |
117 | } | 108 | } |
118 | 109 | ||
110 | static struct class firmware_class = { | ||
111 | .name = "firmware", | ||
112 | .uevent = firmware_class_uevent, | ||
113 | .release = fw_class_dev_release, | ||
114 | }; | ||
115 | |||
119 | static ssize_t | 116 | static ssize_t |
120 | firmware_loading_show(struct class_device *class_dev, char *buf) | 117 | firmware_loading_show(struct class_device *class_dev, char *buf) |
121 | { | 118 | { |
@@ -493,25 +490,6 @@ release_firmware(const struct firmware *fw) | |||
493 | } | 490 | } |
494 | } | 491 | } |
495 | 492 | ||
496 | /** | ||
497 | * register_firmware: - provide a firmware image for later usage | ||
498 | * @name: name of firmware image file | ||
499 | * @data: buffer pointer for the firmware image | ||
500 | * @size: size of the data buffer area | ||
501 | * | ||
502 | * Make sure that @data will be available by requesting firmware @name. | ||
503 | * | ||
504 | * Note: This will not be possible until some kind of persistence | ||
505 | * is available. | ||
506 | **/ | ||
507 | void | ||
508 | register_firmware(const char *name, const u8 *data, size_t size) | ||
509 | { | ||
510 | /* This is meaningless without firmware caching, so until we | ||
511 | * decide if firmware caching is reasonable just leave it as a | ||
512 | * noop */ | ||
513 | } | ||
514 | |||
515 | /* Async support */ | 493 | /* Async support */ |
516 | struct firmware_work { | 494 | struct firmware_work { |
517 | struct work_struct work; | 495 | struct work_struct work; |
@@ -630,4 +608,3 @@ module_exit(firmware_class_exit); | |||
630 | EXPORT_SYMBOL(release_firmware); | 608 | EXPORT_SYMBOL(release_firmware); |
631 | EXPORT_SYMBOL(request_firmware); | 609 | EXPORT_SYMBOL(request_firmware); |
632 | EXPORT_SYMBOL(request_firmware_nowait); | 610 | EXPORT_SYMBOL(request_firmware_nowait); |
633 | EXPORT_SYMBOL(register_firmware); | ||
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index bdb60663f2ef..2a769cc6f5f9 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -8,8 +8,9 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/vt_kern.h> | ||
12 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/kallsyms.h> | ||
13 | #include <linux/pm.h> | ||
13 | #include "../base.h" | 14 | #include "../base.h" |
14 | #include "power.h" | 15 | #include "power.h" |
15 | 16 | ||
@@ -58,11 +59,13 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
58 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { | 59 | if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { |
59 | dev_dbg(dev, "suspending\n"); | 60 | dev_dbg(dev, "suspending\n"); |
60 | error = dev->bus->suspend(dev, state); | 61 | error = dev->bus->suspend(dev, state); |
62 | suspend_report_result(dev->bus->suspend, error); | ||
61 | } | 63 | } |
62 | up(&dev->sem); | 64 | up(&dev->sem); |
63 | return error; | 65 | return error; |
64 | } | 66 | } |
65 | 67 | ||
68 | |||
66 | /** | 69 | /** |
67 | * device_suspend - Save state and stop all devices in system. | 70 | * device_suspend - Save state and stop all devices in system. |
68 | * @state: Power state to put each device in. | 71 | * @state: Power state to put each device in. |
@@ -82,9 +85,6 @@ int device_suspend(pm_message_t state) | |||
82 | { | 85 | { |
83 | int error = 0; | 86 | int error = 0; |
84 | 87 | ||
85 | if (!is_console_suspend_safe()) | ||
86 | return -EINVAL; | ||
87 | |||
88 | down(&dpm_sem); | 88 | down(&dpm_sem); |
89 | down(&dpm_list_sem); | 89 | down(&dpm_list_sem); |
90 | while (!list_empty(&dpm_active) && error == 0) { | 90 | while (!list_empty(&dpm_active) && error == 0) { |
@@ -169,3 +169,12 @@ int device_power_down(pm_message_t state) | |||
169 | 169 | ||
170 | EXPORT_SYMBOL_GPL(device_power_down); | 170 | EXPORT_SYMBOL_GPL(device_power_down); |
171 | 171 | ||
172 | void __suspend_report_result(const char *function, void *fn, int ret) | ||
173 | { | ||
174 | if (ret) { | ||
175 | printk(KERN_ERR "%s(): ", function); | ||
176 | print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn); | ||
177 | printk("%d\n", ret); | ||
178 | } | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(__suspend_report_result); | ||
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 915810f6237e..8c52421cbc54 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -107,7 +107,7 @@ static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | 110 | static int topology_cpu_callback(struct notifier_block *nfb, |
111 | unsigned long action, void *hcpu) | 111 | unsigned long action, void *hcpu) |
112 | { | 112 | { |
113 | unsigned int cpu = (unsigned long)hcpu; | 113 | unsigned int cpu = (unsigned long)hcpu; |