aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 14:36:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-06 14:36:30 -0400
commitab69bcd66fb4be64edfc767365cb9eb084961246 (patch)
treef7623585aee58978fc7814460fff517ec39138f2 /drivers/base
parentc513b67e68787eceafeede32bcd0edbee45c0006 (diff)
parent6937e8f8c0135f2325194c372ada6dc655499992 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (28 commits) driver core: device_rename's new_name can be const sysfs: Remove owner field from sysfs struct attribute powerpc/pci: Remove owner field from attribute initialization in PCI bridge init regulator: Remove owner field from attribute initialization in regulator core driver leds: Remove owner field from attribute initialization in bd2802 driver scsi: Remove owner field from attribute initialization in ARCMSR driver scsi: Remove owner field from attribute initialization in LPFC driver cgroupfs: create /sys/fs/cgroup to mount cgroupfs on Driver core: Add BUS_NOTIFY_BIND_DRIVER driver core: fix memory leak on one error path in bus_register() debugfs: no longer needs to depend on SYSFS sysfs: Fix one more signature discrepancy between sysfs implementation and docs. sysfs: fix discrepancies between implementation and documentation dcdbas: remove a redundant smi_data_buf_free in dcdbas_exit dmi-id: fix a memory leak in dmi_id_init error path sysfs: sysfs_chmod_file's attr can be const firmware: Update hotplug script Driver core: move platform device creation helpers to .init.text (if MODULE=n) Driver core: reduce duplicated code for platform_device creation Driver core: use kmemdup in platform_device_add_resources ...
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c2
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/dd.c4
-rw-r--r--drivers/base/dma-coherent.c2
-rw-r--r--drivers/base/firmware_class.c262
-rw-r--r--drivers/base/platform.c110
6 files changed, 160 insertions, 222 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 12eec3f633b1..eb1b7fa20dce 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -945,8 +945,8 @@ bus_devices_fail:
945 bus_remove_file(bus, &bus_attr_uevent); 945 bus_remove_file(bus, &bus_attr_uevent);
946bus_uevent_fail: 946bus_uevent_fail:
947 kset_unregister(&bus->p->subsys); 947 kset_unregister(&bus->p->subsys);
948 kfree(bus->p);
949out: 948out:
949 kfree(bus->p);
950 bus->p = NULL; 950 bus->p = NULL;
951 return retval; 951 return retval;
952} 952}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index f8e72724dd4b..d1b2c9adc271 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1599,7 +1599,7 @@ EXPORT_SYMBOL_GPL(device_destroy);
1599 * on the same device to ensure that new_name is valid and 1599 * on the same device to ensure that new_name is valid and
1600 * won't conflict with other devices. 1600 * won't conflict with other devices.
1601 */ 1601 */
1602int device_rename(struct device *dev, char *new_name) 1602int device_rename(struct device *dev, const char *new_name)
1603{ 1603{
1604 char *old_class_name = NULL; 1604 char *old_class_name = NULL;
1605 char *new_class_name = NULL; 1605 char *new_class_name = NULL;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 503c2620bbcc..da57ee9d63fe 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -51,6 +51,10 @@ static int driver_sysfs_add(struct device *dev)
51{ 51{
52 int ret; 52 int ret;
53 53
54 if (dev->bus)
55 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
56 BUS_NOTIFY_BIND_DRIVER, dev);
57
54 ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, 58 ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
55 kobject_name(&dev->kobj)); 59 kobject_name(&dev->kobj));
56 if (ret == 0) { 60 if (ret == 0) {
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index d4d8ce53886a..f369e2795985 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -8,7 +8,7 @@
8 8
9struct dma_coherent_mem { 9struct dma_coherent_mem {
10 void *virt_base; 10 void *virt_base;
11 u32 device_base; 11 dma_addr_t device_base;
12 int size; 12 int size;
13 int flags; 13 int flags;
14 unsigned long *bitmap; 14 unsigned long *bitmap;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 3f093b0dd217..c8a44f5e0584 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -87,29 +87,32 @@ static DEFINE_MUTEX(fw_lock);
87 87
88struct firmware_priv { 88struct firmware_priv {
89 struct completion completion; 89 struct completion completion;
90 struct bin_attribute attr_data;
91 struct firmware *fw; 90 struct firmware *fw;
92 unsigned long status; 91 unsigned long status;
93 struct page **pages; 92 struct page **pages;
94 int nr_pages; 93 int nr_pages;
95 int page_array_size; 94 int page_array_size;
96 struct timer_list timeout; 95 struct timer_list timeout;
96 struct device dev;
97 bool nowait; 97 bool nowait;
98 char fw_id[]; 98 char fw_id[];
99}; 99};
100 100
101static void 101static struct firmware_priv *to_firmware_priv(struct device *dev)
102fw_load_abort(struct firmware_priv *fw_priv) 102{
103 return container_of(dev, struct firmware_priv, dev);
104}
105
106static void fw_load_abort(struct firmware_priv *fw_priv)
103{ 107{
104 set_bit(FW_STATUS_ABORT, &fw_priv->status); 108 set_bit(FW_STATUS_ABORT, &fw_priv->status);
105 wmb(); 109 wmb();
106 complete(&fw_priv->completion); 110 complete(&fw_priv->completion);
107} 111}
108 112
109static ssize_t 113static ssize_t firmware_timeout_show(struct class *class,
110firmware_timeout_show(struct class *class, 114 struct class_attribute *attr,
111 struct class_attribute *attr, 115 char *buf)
112 char *buf)
113{ 116{
114 return sprintf(buf, "%d\n", loading_timeout); 117 return sprintf(buf, "%d\n", loading_timeout);
115} 118}
@@ -127,14 +130,14 @@ firmware_timeout_show(struct class *class,
127 * 130 *
128 * Note: zero means 'wait forever'. 131 * Note: zero means 'wait forever'.
129 **/ 132 **/
130static ssize_t 133static ssize_t firmware_timeout_store(struct class *class,
131firmware_timeout_store(struct class *class, 134 struct class_attribute *attr,
132 struct class_attribute *attr, 135 const char *buf, size_t count)
133 const char *buf, size_t count)
134{ 136{
135 loading_timeout = simple_strtol(buf, NULL, 10); 137 loading_timeout = simple_strtol(buf, NULL, 10);
136 if (loading_timeout < 0) 138 if (loading_timeout < 0)
137 loading_timeout = 0; 139 loading_timeout = 0;
140
138 return count; 141 return count;
139} 142}
140 143
@@ -146,21 +149,20 @@ static struct class_attribute firmware_class_attrs[] = {
146 149
147static void fw_dev_release(struct device *dev) 150static void fw_dev_release(struct device *dev)
148{ 151{
149 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 152 struct firmware_priv *fw_priv = to_firmware_priv(dev);
150 int i; 153 int i;
151 154
152 for (i = 0; i < fw_priv->nr_pages; i++) 155 for (i = 0; i < fw_priv->nr_pages; i++)
153 __free_page(fw_priv->pages[i]); 156 __free_page(fw_priv->pages[i]);
154 kfree(fw_priv->pages); 157 kfree(fw_priv->pages);
155 kfree(fw_priv); 158 kfree(fw_priv);
156 kfree(dev);
157 159
158 module_put(THIS_MODULE); 160 module_put(THIS_MODULE);
159} 161}
160 162
161static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) 163static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
162{ 164{
163 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 165 struct firmware_priv *fw_priv = to_firmware_priv(dev);
164 166
165 if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id)) 167 if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
166 return -ENOMEM; 168 return -ENOMEM;
@@ -182,8 +184,9 @@ static struct class firmware_class = {
182static ssize_t firmware_loading_show(struct device *dev, 184static ssize_t firmware_loading_show(struct device *dev,
183 struct device_attribute *attr, char *buf) 185 struct device_attribute *attr, char *buf)
184{ 186{
185 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 187 struct firmware_priv *fw_priv = to_firmware_priv(dev);
186 int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); 188 int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
189
187 return sprintf(buf, "%d\n", loading); 190 return sprintf(buf, "%d\n", loading);
188} 191}
189 192
@@ -219,7 +222,7 @@ static ssize_t firmware_loading_store(struct device *dev,
219 struct device_attribute *attr, 222 struct device_attribute *attr,
220 const char *buf, size_t count) 223 const char *buf, size_t count)
221{ 224{
222 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 225 struct firmware_priv *fw_priv = to_firmware_priv(dev);
223 int loading = simple_strtol(buf, NULL, 10); 226 int loading = simple_strtol(buf, NULL, 10);
224 int i; 227 int i;
225 228
@@ -277,13 +280,12 @@ static ssize_t firmware_loading_store(struct device *dev,
277 280
278static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); 281static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
279 282
280static ssize_t 283static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
281firmware_data_read(struct file *filp, struct kobject *kobj, 284 struct bin_attribute *bin_attr,
282 struct bin_attribute *bin_attr, char *buffer, loff_t offset, 285 char *buffer, loff_t offset, size_t count)
283 size_t count)
284{ 286{
285 struct device *dev = to_dev(kobj); 287 struct device *dev = to_dev(kobj);
286 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 288 struct firmware_priv *fw_priv = to_firmware_priv(dev);
287 struct firmware *fw; 289 struct firmware *fw;
288 ssize_t ret_count; 290 ssize_t ret_count;
289 291
@@ -322,8 +324,7 @@ out:
322 return ret_count; 324 return ret_count;
323} 325}
324 326
325static int 327static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
326fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
327{ 328{
328 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; 329 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
329 330
@@ -373,13 +374,12 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
373 * Data written to the 'data' attribute will be later handed to 374 * Data written to the 'data' attribute will be later handed to
374 * the driver as a firmware image. 375 * the driver as a firmware image.
375 **/ 376 **/
376static ssize_t 377static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
377firmware_data_write(struct file* filp, struct kobject *kobj, 378 struct bin_attribute *bin_attr,
378 struct bin_attribute *bin_attr, char *buffer, 379 char *buffer, loff_t offset, size_t count)
379 loff_t offset, size_t count)
380{ 380{
381 struct device *dev = to_dev(kobj); 381 struct device *dev = to_dev(kobj);
382 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 382 struct firmware_priv *fw_priv = to_firmware_priv(dev);
383 struct firmware *fw; 383 struct firmware *fw;
384 ssize_t retval; 384 ssize_t retval;
385 385
@@ -420,116 +420,103 @@ out:
420 return retval; 420 return retval;
421} 421}
422 422
423static struct bin_attribute firmware_attr_data_tmpl = { 423static struct bin_attribute firmware_attr_data = {
424 .attr = {.name = "data", .mode = 0644}, 424 .attr = { .name = "data", .mode = 0644 },
425 .size = 0, 425 .size = 0,
426 .read = firmware_data_read, 426 .read = firmware_data_read,
427 .write = firmware_data_write, 427 .write = firmware_data_write,
428}; 428};
429 429
430static void 430static void firmware_class_timeout(u_long data)
431firmware_class_timeout(u_long data)
432{ 431{
433 struct firmware_priv *fw_priv = (struct firmware_priv *) data; 432 struct firmware_priv *fw_priv = (struct firmware_priv *) data;
433
434 fw_load_abort(fw_priv); 434 fw_load_abort(fw_priv);
435} 435}
436 436
437static int fw_register_device(struct device **dev_p, const char *fw_name, 437static struct firmware_priv *
438 struct device *device) 438fw_create_instance(struct firmware *firmware, const char *fw_name,
439 struct device *device, bool uevent, bool nowait)
439{ 440{
440 int retval; 441 struct firmware_priv *fw_priv;
441 struct firmware_priv *fw_priv = 442 struct device *f_dev;
442 kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL); 443 int error;
443 struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL);
444
445 *dev_p = NULL;
446 444
447 if (!fw_priv || !f_dev) { 445 fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
446 if (!fw_priv) {
448 dev_err(device, "%s: kmalloc failed\n", __func__); 447 dev_err(device, "%s: kmalloc failed\n", __func__);
449 retval = -ENOMEM; 448 error = -ENOMEM;
450 goto error_kfree; 449 goto err_out;
451 } 450 }
452 451
452 fw_priv->fw = firmware;
453 fw_priv->nowait = nowait;
453 strcpy(fw_priv->fw_id, fw_name); 454 strcpy(fw_priv->fw_id, fw_name);
454 init_completion(&fw_priv->completion); 455 init_completion(&fw_priv->completion);
455 fw_priv->attr_data = firmware_attr_data_tmpl; 456 setup_timer(&fw_priv->timeout,
456 fw_priv->timeout.function = firmware_class_timeout; 457 firmware_class_timeout, (u_long) fw_priv);
457 fw_priv->timeout.data = (u_long) fw_priv;
458 init_timer(&fw_priv->timeout);
459 458
459 f_dev = &fw_priv->dev;
460
461 device_initialize(f_dev);
460 dev_set_name(f_dev, "%s", dev_name(device)); 462 dev_set_name(f_dev, "%s", dev_name(device));
461 f_dev->parent = device; 463 f_dev->parent = device;
462 f_dev->class = &firmware_class; 464 f_dev->class = &firmware_class;
463 dev_set_drvdata(f_dev, fw_priv);
464 dev_set_uevent_suppress(f_dev, 1);
465 retval = device_register(f_dev);
466 if (retval) {
467 dev_err(device, "%s: device_register failed\n", __func__);
468 put_device(f_dev);
469 return retval;
470 }
471 *dev_p = f_dev;
472 return 0;
473
474error_kfree:
475 kfree(f_dev);
476 kfree(fw_priv);
477 return retval;
478}
479 465
480static int fw_setup_device(struct firmware *fw, struct device **dev_p, 466 dev_set_uevent_suppress(f_dev, true);
481 const char *fw_name, struct device *device,
482 int uevent, bool nowait)
483{
484 struct device *f_dev;
485 struct firmware_priv *fw_priv;
486 int retval;
487
488 *dev_p = NULL;
489 retval = fw_register_device(&f_dev, fw_name, device);
490 if (retval)
491 goto out;
492 467
493 /* Need to pin this module until class device is destroyed */ 468 /* Need to pin this module until class device is destroyed */
494 __module_get(THIS_MODULE); 469 __module_get(THIS_MODULE);
495 470
496 fw_priv = dev_get_drvdata(f_dev); 471 error = device_add(f_dev);
497 472 if (error) {
498 fw_priv->nowait = nowait; 473 dev_err(device, "%s: device_register failed\n", __func__);
474 goto err_put_dev;
475 }
499 476
500 fw_priv->fw = fw; 477 error = device_create_bin_file(f_dev, &firmware_attr_data);
501 sysfs_bin_attr_init(&fw_priv->attr_data); 478 if (error) {
502 retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
503 if (retval) {
504 dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); 479 dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
505 goto error_unreg; 480 goto err_del_dev;
506 } 481 }
507 482
508 retval = device_create_file(f_dev, &dev_attr_loading); 483 error = device_create_file(f_dev, &dev_attr_loading);
509 if (retval) { 484 if (error) {
510 dev_err(device, "%s: device_create_file failed\n", __func__); 485 dev_err(device, "%s: device_create_file failed\n", __func__);
511 goto error_unreg; 486 goto err_del_bin_attr;
512 } 487 }
513 488
514 if (uevent) 489 if (uevent)
515 dev_set_uevent_suppress(f_dev, 0); 490 dev_set_uevent_suppress(f_dev, false);
516 *dev_p = f_dev; 491
517 goto out; 492 return fw_priv;
493
494err_del_bin_attr:
495 device_remove_bin_file(f_dev, &firmware_attr_data);
496err_del_dev:
497 device_del(f_dev);
498err_put_dev:
499 put_device(f_dev);
500err_out:
501 return ERR_PTR(error);
502}
503
504static void fw_destroy_instance(struct firmware_priv *fw_priv)
505{
506 struct device *f_dev = &fw_priv->dev;
518 507
519error_unreg: 508 device_remove_file(f_dev, &dev_attr_loading);
509 device_remove_bin_file(f_dev, &firmware_attr_data);
520 device_unregister(f_dev); 510 device_unregister(f_dev);
521out:
522 return retval;
523} 511}
524 512
525static int 513static int _request_firmware(const struct firmware **firmware_p,
526_request_firmware(const struct firmware **firmware_p, const char *name, 514 const char *name, struct device *device,
527 struct device *device, int uevent, bool nowait) 515 bool uevent, bool nowait)
528{ 516{
529 struct device *f_dev;
530 struct firmware_priv *fw_priv; 517 struct firmware_priv *fw_priv;
531 struct firmware *firmware; 518 struct firmware *firmware;
532 int retval; 519 int retval = 0;
533 520
534 if (!firmware_p) 521 if (!firmware_p)
535 return -EINVAL; 522 return -EINVAL;
@@ -550,41 +537,40 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
550 if (uevent) 537 if (uevent)
551 dev_dbg(device, "firmware: requesting %s\n", name); 538 dev_dbg(device, "firmware: requesting %s\n", name);
552 539
553 retval = fw_setup_device(firmware, &f_dev, name, device, 540 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
554 uevent, nowait); 541 if (IS_ERR(fw_priv)) {
555 if (retval) 542 retval = PTR_ERR(fw_priv);
556 goto error_kfree_fw; 543 goto out;
557 544 }
558 fw_priv = dev_get_drvdata(f_dev);
559 545
560 if (uevent) { 546 if (uevent) {
561 if (loading_timeout > 0) { 547 if (loading_timeout > 0)
562 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 548 mod_timer(&fw_priv->timeout,
563 add_timer(&fw_priv->timeout); 549 round_jiffies_up(jiffies +
564 } 550 loading_timeout * HZ));
551
552 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
553 }
554
555 wait_for_completion(&fw_priv->completion);
565 556
566 kobject_uevent(&f_dev->kobj, KOBJ_ADD); 557 set_bit(FW_STATUS_DONE, &fw_priv->status);
567 wait_for_completion(&fw_priv->completion); 558 del_timer_sync(&fw_priv->timeout);
568 set_bit(FW_STATUS_DONE, &fw_priv->status);
569 del_timer_sync(&fw_priv->timeout);
570 } else
571 wait_for_completion(&fw_priv->completion);
572 559
573 mutex_lock(&fw_lock); 560 mutex_lock(&fw_lock);
574 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 561 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status))
575 retval = -ENOENT; 562 retval = -ENOENT;
576 release_firmware(fw_priv->fw);
577 *firmware_p = NULL;
578 }
579 fw_priv->fw = NULL; 563 fw_priv->fw = NULL;
580 mutex_unlock(&fw_lock); 564 mutex_unlock(&fw_lock);
581 device_unregister(f_dev);
582 goto out;
583 565
584error_kfree_fw: 566 fw_destroy_instance(fw_priv);
585 kfree(firmware); 567
586 *firmware_p = NULL;
587out: 568out:
569 if (retval) {
570 release_firmware(firmware);
571 firmware_p = NULL;
572 }
573
588 return retval; 574 return retval;
589} 575}
590 576
@@ -635,23 +621,24 @@ struct firmware_work {
635 int uevent; 621 int uevent;
636}; 622};
637 623
638static int 624static int request_firmware_work_func(void *arg)
639request_firmware_work_func(void *arg)
640{ 625{
641 struct firmware_work *fw_work = arg; 626 struct firmware_work *fw_work = arg;
642 const struct firmware *fw; 627 const struct firmware *fw;
643 int ret; 628 int ret;
629
644 if (!arg) { 630 if (!arg) {
645 WARN_ON(1); 631 WARN_ON(1);
646 return 0; 632 return 0;
647 } 633 }
648 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
649 fw_work->uevent, true);
650 634
635 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
636 fw_work->uevent, true);
651 fw_work->cont(fw, fw_work->context); 637 fw_work->cont(fw, fw_work->context);
652 638
653 module_put(fw_work->module); 639 module_put(fw_work->module);
654 kfree(fw_work); 640 kfree(fw_work);
641
655 return ret; 642 return ret;
656} 643}
657 644
@@ -679,34 +666,33 @@ request_firmware_nowait(
679 void (*cont)(const struct firmware *fw, void *context)) 666 void (*cont)(const struct firmware *fw, void *context))
680{ 667{
681 struct task_struct *task; 668 struct task_struct *task;
682 struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), 669 struct firmware_work *fw_work;
683 gfp);
684 670
671 fw_work = kzalloc(sizeof (struct firmware_work), gfp);
685 if (!fw_work) 672 if (!fw_work)
686 return -ENOMEM; 673 return -ENOMEM;
674
675 fw_work->module = module;
676 fw_work->name = name;
677 fw_work->device = device;
678 fw_work->context = context;
679 fw_work->cont = cont;
680 fw_work->uevent = uevent;
681
687 if (!try_module_get(module)) { 682 if (!try_module_get(module)) {
688 kfree(fw_work); 683 kfree(fw_work);
689 return -EFAULT; 684 return -EFAULT;
690 } 685 }
691 686
692 *fw_work = (struct firmware_work) {
693 .module = module,
694 .name = name,
695 .device = device,
696 .context = context,
697 .cont = cont,
698 .uevent = uevent,
699 };
700
701 task = kthread_run(request_firmware_work_func, fw_work, 687 task = kthread_run(request_firmware_work_func, fw_work,
702 "firmware/%s", name); 688 "firmware/%s", name);
703
704 if (IS_ERR(task)) { 689 if (IS_ERR(task)) {
705 fw_work->cont(NULL, fw_work->context); 690 fw_work->cont(NULL, fw_work->context);
706 module_put(fw_work->module); 691 module_put(fw_work->module);
707 kfree(fw_work); 692 kfree(fw_work);
708 return PTR_ERR(task); 693 return PTR_ERR(task);
709 } 694 }
695
710 return 0; 696 return 0;
711} 697}
712 698
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f699fabf403b..c6c933f58102 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -192,13 +192,13 @@ int platform_device_add_resources(struct platform_device *pdev,
192{ 192{
193 struct resource *r; 193 struct resource *r;
194 194
195 r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL); 195 r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
196 if (r) { 196 if (r) {
197 memcpy(r, res, sizeof(struct resource) * num);
198 pdev->resource = r; 197 pdev->resource = r;
199 pdev->num_resources = num; 198 pdev->num_resources = num;
199 return 0;
200 } 200 }
201 return r ? 0 : -ENOMEM; 201 return -ENOMEM;
202} 202}
203EXPORT_SYMBOL_GPL(platform_device_add_resources); 203EXPORT_SYMBOL_GPL(platform_device_add_resources);
204 204
@@ -345,108 +345,56 @@ void platform_device_unregister(struct platform_device *pdev)
345EXPORT_SYMBOL_GPL(platform_device_unregister); 345EXPORT_SYMBOL_GPL(platform_device_unregister);
346 346
347/** 347/**
348 * platform_device_register_simple - add a platform-level device and its resources 348 * platform_device_register_resndata - add a platform-level device with
349 * @name: base name of the device we're adding 349 * resources and platform-specific data
350 * @id: instance id
351 * @res: set of resources that needs to be allocated for the device
352 * @num: number of resources
353 *
354 * This function creates a simple platform device that requires minimal
355 * resource and memory management. Canned release function freeing memory
356 * allocated for the device allows drivers using such devices to be
357 * unloaded without waiting for the last reference to the device to be
358 * dropped.
359 *
360 * This interface is primarily intended for use with legacy drivers which
361 * probe hardware directly. Because such drivers create sysfs device nodes
362 * themselves, rather than letting system infrastructure handle such device
363 * enumeration tasks, they don't fully conform to the Linux driver model.
364 * In particular, when such drivers are built as modules, they can't be
365 * "hotplugged".
366 * 350 *
367 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
368 */
369struct platform_device *platform_device_register_simple(const char *name,
370 int id,
371 const struct resource *res,
372 unsigned int num)
373{
374 struct platform_device *pdev;
375 int retval;
376
377 pdev = platform_device_alloc(name, id);
378 if (!pdev) {
379 retval = -ENOMEM;
380 goto error;
381 }
382
383 if (num) {
384 retval = platform_device_add_resources(pdev, res, num);
385 if (retval)
386 goto error;
387 }
388
389 retval = platform_device_add(pdev);
390 if (retval)
391 goto error;
392
393 return pdev;
394
395error:
396 platform_device_put(pdev);
397 return ERR_PTR(retval);
398}
399EXPORT_SYMBOL_GPL(platform_device_register_simple);
400
401/**
402 * platform_device_register_data - add a platform-level device with platform-specific data
403 * @parent: parent device for the device we're adding 351 * @parent: parent device for the device we're adding
404 * @name: base name of the device we're adding 352 * @name: base name of the device we're adding
405 * @id: instance id 353 * @id: instance id
354 * @res: set of resources that needs to be allocated for the device
355 * @num: number of resources
406 * @data: platform specific data for this platform device 356 * @data: platform specific data for this platform device
407 * @size: size of platform specific data 357 * @size: size of platform specific data
408 * 358 *
409 * This function creates a simple platform device that requires minimal
410 * resource and memory management. Canned release function freeing memory
411 * allocated for the device allows drivers using such devices to be
412 * unloaded without waiting for the last reference to the device to be
413 * dropped.
414 *
415 * Returns &struct platform_device pointer on success, or ERR_PTR() on error. 359 * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
416 */ 360 */
417struct platform_device *platform_device_register_data( 361struct platform_device *__init_or_module platform_device_register_resndata(
418 struct device *parent, 362 struct device *parent,
419 const char *name, int id, 363 const char *name, int id,
364 const struct resource *res, unsigned int num,
420 const void *data, size_t size) 365 const void *data, size_t size)
421{ 366{
367 int ret = -ENOMEM;
422 struct platform_device *pdev; 368 struct platform_device *pdev;
423 int retval;
424 369
425 pdev = platform_device_alloc(name, id); 370 pdev = platform_device_alloc(name, id);
426 if (!pdev) { 371 if (!pdev)
427 retval = -ENOMEM; 372 goto err;
428 goto error;
429 }
430 373
431 pdev->dev.parent = parent; 374 pdev->dev.parent = parent;
432 375
433 if (size) { 376 if (res) {
434 retval = platform_device_add_data(pdev, data, size); 377 ret = platform_device_add_resources(pdev, res, num);
435 if (retval) 378 if (ret)
436 goto error; 379 goto err;
437 } 380 }
438 381
439 retval = platform_device_add(pdev); 382 if (data) {
440 if (retval) 383 ret = platform_device_add_data(pdev, data, size);
441 goto error; 384 if (ret)
385 goto err;
386 }
442 387
443 return pdev; 388 ret = platform_device_add(pdev);
389 if (ret) {
390err:
391 platform_device_put(pdev);
392 return ERR_PTR(ret);
393 }
444 394
445error: 395 return pdev;
446 platform_device_put(pdev);
447 return ERR_PTR(retval);
448} 396}
449EXPORT_SYMBOL_GPL(platform_device_register_data); 397EXPORT_SYMBOL_GPL(platform_device_register_resndata);
450 398
451static int platform_drv_probe(struct device *_dev) 399static int platform_drv_probe(struct device *_dev)
452{ 400{