diff options
| -rw-r--r-- | drivers/base/firmware_class.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index ae00a2fd280f..5401814c874d 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
| @@ -16,10 +16,11 @@ | |||
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
| 18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
| 19 | #include <linux/kthread.h> | 19 | #include <linux/workqueue.h> |
| 20 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
| 21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/sched.h> | ||
| 23 | 24 | ||
| 24 | #define to_dev(obj) container_of(obj, struct device, kobj) | 25 | #define to_dev(obj) container_of(obj, struct device, kobj) |
| 25 | 26 | ||
| @@ -630,19 +631,15 @@ struct firmware_work { | |||
| 630 | bool uevent; | 631 | bool uevent; |
| 631 | }; | 632 | }; |
| 632 | 633 | ||
| 633 | static int request_firmware_work_func(void *arg) | 634 | static void request_firmware_work_func(struct work_struct *work) |
| 634 | { | 635 | { |
| 635 | struct firmware_work *fw_work = arg; | 636 | struct firmware_work *fw_work; |
| 636 | const struct firmware *fw; | 637 | const struct firmware *fw; |
| 637 | struct firmware_priv *fw_priv; | 638 | struct firmware_priv *fw_priv; |
| 638 | long timeout; | 639 | long timeout; |
| 639 | int ret; | 640 | int ret; |
| 640 | 641 | ||
| 641 | if (!arg) { | 642 | fw_work = container_of(work, struct firmware_work, work); |
| 642 | WARN_ON(1); | ||
| 643 | return 0; | ||
| 644 | } | ||
| 645 | |||
| 646 | fw_priv = _request_firmware_prepare(&fw, fw_work->name, fw_work->device, | 643 | fw_priv = _request_firmware_prepare(&fw, fw_work->name, fw_work->device, |
| 647 | fw_work->uevent, true); | 644 | fw_work->uevent, true); |
| 648 | if (IS_ERR_OR_NULL(fw_priv)) { | 645 | if (IS_ERR_OR_NULL(fw_priv)) { |
| @@ -667,8 +664,6 @@ static int request_firmware_work_func(void *arg) | |||
| 667 | 664 | ||
| 668 | module_put(fw_work->module); | 665 | module_put(fw_work->module); |
| 669 | kfree(fw_work); | 666 | kfree(fw_work); |
| 670 | |||
| 671 | return ret; | ||
| 672 | } | 667 | } |
| 673 | 668 | ||
| 674 | /** | 669 | /** |
| @@ -694,7 +689,6 @@ request_firmware_nowait( | |||
| 694 | const char *name, struct device *device, gfp_t gfp, void *context, | 689 | const char *name, struct device *device, gfp_t gfp, void *context, |
| 695 | void (*cont)(const struct firmware *fw, void *context)) | 690 | void (*cont)(const struct firmware *fw, void *context)) |
| 696 | { | 691 | { |
| 697 | struct task_struct *task; | ||
| 698 | struct firmware_work *fw_work; | 692 | struct firmware_work *fw_work; |
| 699 | 693 | ||
| 700 | fw_work = kzalloc(sizeof (struct firmware_work), gfp); | 694 | fw_work = kzalloc(sizeof (struct firmware_work), gfp); |
| @@ -713,15 +707,8 @@ request_firmware_nowait( | |||
| 713 | return -EFAULT; | 707 | return -EFAULT; |
| 714 | } | 708 | } |
| 715 | 709 | ||
| 716 | task = kthread_run(request_firmware_work_func, fw_work, | 710 | INIT_WORK(&fw_work->work, request_firmware_work_func); |
| 717 | "firmware/%s", name); | 711 | schedule_work(&fw_work->work); |
| 718 | if (IS_ERR(task)) { | ||
| 719 | fw_work->cont(NULL, fw_work->context); | ||
| 720 | module_put(fw_work->module); | ||
| 721 | kfree(fw_work); | ||
| 722 | return PTR_ERR(task); | ||
| 723 | } | ||
| 724 | |||
| 725 | return 0; | 712 | return 0; |
| 726 | } | 713 | } |
| 727 | 714 | ||
