aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c21
-rw-r--r--drivers/base/dd.c8
-rw-r--r--drivers/base/firmware_class.c15
-rw-r--r--drivers/base/memory.c1
-rw-r--r--drivers/base/platform.c73
5 files changed, 96 insertions, 22 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 03204bfd17af..fa601b085eba 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -133,7 +133,7 @@ static struct kobj_type ktype_bus = {
133decl_subsys(bus, &ktype_bus, NULL); 133decl_subsys(bus, &ktype_bus, NULL);
134 134
135 135
136/* Manually detach a device from it's associated driver. */ 136/* Manually detach a device from its associated driver. */
137static int driver_helper(struct device *dev, void *data) 137static int driver_helper(struct device *dev, void *data)
138{ 138{
139 const char *name = data; 139 const char *name = data;
@@ -151,14 +151,13 @@ static ssize_t driver_unbind(struct device_driver *drv,
151 int err = -ENODEV; 151 int err = -ENODEV;
152 152
153 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); 153 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
154 if ((dev) && 154 if (dev && dev->driver == drv) {
155 (dev->driver == drv)) {
156 device_release_driver(dev); 155 device_release_driver(dev);
157 err = count; 156 err = count;
158 } 157 }
159 if (err) 158 put_device(dev);
160 return err; 159 put_bus(bus);
161 return count; 160 return err;
162} 161}
163static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 162static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
164 163
@@ -175,16 +174,14 @@ static ssize_t driver_bind(struct device_driver *drv,
175 int err = -ENODEV; 174 int err = -ENODEV;
176 175
177 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); 176 dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
178 if ((dev) && 177 if (dev && dev->driver == NULL) {
179 (dev->driver == NULL)) {
180 down(&dev->sem); 178 down(&dev->sem);
181 err = driver_probe_device(drv, dev); 179 err = driver_probe_device(drv, dev);
182 up(&dev->sem); 180 up(&dev->sem);
183 put_device(dev);
184 } 181 }
185 if (err) 182 put_device(dev);
186 return err; 183 put_bus(bus);
187 return count; 184 return err;
188} 185}
189static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); 186static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
190 187
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3565e9795301..3b419c9a1e7e 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -62,7 +62,6 @@ void device_bind_driver(struct device * dev)
62 * because we don't know the format of the ID structures, nor what 62 * because we don't know the format of the ID structures, nor what
63 * is to be considered a match and what is not. 63 * is to be considered a match and what is not.
64 * 64 *
65 *
66 * This function returns 1 if a match is found, an error if one 65 * This function returns 1 if a match is found, an error if one
67 * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise. 66 * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
68 * 67 *
@@ -158,7 +157,6 @@ static int __driver_attach(struct device * dev, void * data)
158 driver_probe_device(drv, dev); 157 driver_probe_device(drv, dev);
159 up(&dev->sem); 158 up(&dev->sem);
160 159
161
162 return 0; 160 return 0;
163} 161}
164 162
@@ -225,15 +223,15 @@ void driver_detach(struct device_driver * drv)
225 struct device * dev; 223 struct device * dev;
226 224
227 for (;;) { 225 for (;;) {
228 spin_lock_irq(&drv->klist_devices.k_lock); 226 spin_lock(&drv->klist_devices.k_lock);
229 if (list_empty(&drv->klist_devices.k_list)) { 227 if (list_empty(&drv->klist_devices.k_list)) {
230 spin_unlock_irq(&drv->klist_devices.k_lock); 228 spin_unlock(&drv->klist_devices.k_lock);
231 break; 229 break;
232 } 230 }
233 dev = list_entry(drv->klist_devices.k_list.prev, 231 dev = list_entry(drv->klist_devices.k_list.prev,
234 struct device, knode_driver.n_node); 232 struct device, knode_driver.n_node);
235 get_device(dev); 233 get_device(dev);
236 spin_unlock_irq(&drv->klist_devices.k_lock); 234 spin_unlock(&drv->klist_devices.k_lock);
237 235
238 down(&dev->sem); 236 down(&dev->sem);
239 if (dev->driver == drv) 237 if (dev->driver == drv)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 98f6c02d6790..59dacb6552c0 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -526,18 +526,23 @@ request_firmware_work_func(void *arg)
526{ 526{
527 struct firmware_work *fw_work = arg; 527 struct firmware_work *fw_work = arg;
528 const struct firmware *fw; 528 const struct firmware *fw;
529 int ret;
529 if (!arg) { 530 if (!arg) {
530 WARN_ON(1); 531 WARN_ON(1);
531 return 0; 532 return 0;
532 } 533 }
533 daemonize("%s/%s", "firmware", fw_work->name); 534 daemonize("%s/%s", "firmware", fw_work->name);
534 _request_firmware(&fw, fw_work->name, fw_work->device, 535 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
535 fw_work->hotplug); 536 fw_work->hotplug);
536 fw_work->cont(fw, fw_work->context); 537 if (ret < 0)
537 release_firmware(fw); 538 fw_work->cont(NULL, fw_work->context);
539 else {
540 fw_work->cont(fw, fw_work->context);
541 release_firmware(fw);
542 }
538 module_put(fw_work->module); 543 module_put(fw_work->module);
539 kfree(fw_work); 544 kfree(fw_work);
540 return 0; 545 return ret;
541} 546}
542 547
543/** 548/**
@@ -586,6 +591,8 @@ request_firmware_nowait(
586 591
587 if (ret < 0) { 592 if (ret < 0) {
588 fw_work->cont(NULL, fw_work->context); 593 fw_work->cont(NULL, fw_work->context);
594 module_put(fw_work->module);
595 kfree(fw_work);
589 return ret; 596 return ret;
590 } 597 }
591 return 0; 598 return 0;
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index b7ddd651d664..bc3ca6a656b2 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -28,7 +28,6 @@
28static struct sysdev_class memory_sysdev_class = { 28static struct sysdev_class memory_sysdev_class = {
29 set_kset_name(MEMORY_CLASS_NAME), 29 set_kset_name(MEMORY_CLASS_NAME),
30}; 30};
31EXPORT_SYMBOL(memory_sysdev_class);
32 31
33static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj) 32static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
34{ 33{
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6d4736e89f1a..8827dafba945 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -20,6 +20,8 @@
20 20
21#include "base.h" 21#include "base.h"
22 22
23#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver))
24
23struct device platform_bus = { 25struct device platform_bus = {
24 .bus_id = "platform", 26 .bus_id = "platform",
25}; 27};
@@ -354,6 +356,77 @@ error:
354 return ERR_PTR(retval); 356 return ERR_PTR(retval);
355} 357}
356 358
359static int platform_drv_probe(struct device *_dev)
360{
361 struct platform_driver *drv = to_platform_driver(_dev->driver);
362 struct platform_device *dev = to_platform_device(_dev);
363
364 return drv->probe(dev);
365}
366
367static int platform_drv_remove(struct device *_dev)
368{
369 struct platform_driver *drv = to_platform_driver(_dev->driver);
370 struct platform_device *dev = to_platform_device(_dev);
371
372 return drv->remove(dev);
373}
374
375static void platform_drv_shutdown(struct device *_dev)
376{
377 struct platform_driver *drv = to_platform_driver(_dev->driver);
378 struct platform_device *dev = to_platform_device(_dev);
379
380 drv->shutdown(dev);
381}
382
383static int platform_drv_suspend(struct device *_dev, pm_message_t state)
384{
385 struct platform_driver *drv = to_platform_driver(_dev->driver);
386 struct platform_device *dev = to_platform_device(_dev);
387
388 return drv->suspend(dev, state);
389}
390
391static int platform_drv_resume(struct device *_dev)
392{
393 struct platform_driver *drv = to_platform_driver(_dev->driver);
394 struct platform_device *dev = to_platform_device(_dev);
395
396 return drv->resume(dev);
397}
398
399/**
400 * platform_driver_register
401 * @drv: platform driver structure
402 */
403int platform_driver_register(struct platform_driver *drv)
404{
405 drv->driver.bus = &platform_bus_type;
406 if (drv->probe)
407 drv->driver.probe = platform_drv_probe;
408 if (drv->remove)
409 drv->driver.remove = platform_drv_remove;
410 if (drv->shutdown)
411 drv->driver.shutdown = platform_drv_shutdown;
412 if (drv->suspend)
413 drv->driver.suspend = platform_drv_suspend;
414 if (drv->resume)
415 drv->driver.resume = platform_drv_resume;
416 return driver_register(&drv->driver);
417}
418EXPORT_SYMBOL_GPL(platform_driver_register);
419
420/**
421 * platform_driver_unregister
422 * @drv: platform driver structure
423 */
424void platform_driver_unregister(struct platform_driver *drv)
425{
426 driver_unregister(&drv->driver);
427}
428EXPORT_SYMBOL_GPL(platform_driver_unregister);
429
357 430
358/** 431/**
359 * platform_match - bind platform device to platform driver. 432 * platform_match - bind platform device to platform driver.