aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 60290671f04a..72c644b191a4 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -81,6 +81,11 @@ enum {
81 81
82static int loading_timeout = 60; /* In seconds */ 82static int loading_timeout = 60; /* In seconds */
83 83
84static inline long firmware_loading_timeout(void)
85{
86 return loading_timeout > 0 ? loading_timeout * HZ : MAX_SCHEDULE_TIMEOUT;
87}
88
84/* fw_lock could be moved to 'struct firmware_priv' but since it is just 89/* fw_lock could be moved to 'struct firmware_priv' but since it is just
85 * guarding for corner cases a global lock should be OK */ 90 * guarding for corner cases a global lock should be OK */
86static DEFINE_MUTEX(fw_lock); 91static DEFINE_MUTEX(fw_lock);
@@ -541,31 +546,22 @@ static void _request_firmware_cleanup(const struct firmware **firmware_p)
541 546
542static int _request_firmware(const struct firmware *firmware, 547static int _request_firmware(const struct firmware *firmware,
543 const char *name, struct device *device, 548 const char *name, struct device *device,
544 bool uevent, bool nowait) 549 bool uevent, bool nowait, long timeout)
545{ 550{
546 struct firmware_priv *fw_priv; 551 struct firmware_priv *fw_priv;
547 int retval; 552 int retval = 0;
548
549 retval = usermodehelper_read_trylock();
550 if (WARN_ON(retval)) {
551 dev_err(device, "firmware: %s will not be loaded\n", name);
552 return retval;
553 }
554 553
555 if (uevent) 554 if (uevent)
556 dev_dbg(device, "firmware: requesting %s\n", name); 555 dev_dbg(device, "firmware: requesting %s\n", name);
557 556
558 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); 557 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
559 if (IS_ERR(fw_priv)) { 558 if (IS_ERR(fw_priv))
560 retval = PTR_ERR(fw_priv); 559 return PTR_ERR(fw_priv);
561 goto out;
562 }
563 560
564 if (uevent) { 561 if (uevent) {
565 if (loading_timeout > 0) 562 if (timeout != MAX_SCHEDULE_TIMEOUT)
566 mod_timer(&fw_priv->timeout, 563 mod_timer(&fw_priv->timeout,
567 round_jiffies_up(jiffies + 564 round_jiffies_up(jiffies + timeout));
568 loading_timeout * HZ));
569 565
570 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); 566 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
571 } 567 }
@@ -582,9 +578,6 @@ static int _request_firmware(const struct firmware *firmware,
582 mutex_unlock(&fw_lock); 578 mutex_unlock(&fw_lock);
583 579
584 fw_destroy_instance(fw_priv); 580 fw_destroy_instance(fw_priv);
585
586out:
587 usermodehelper_read_unlock();
588 return retval; 581 return retval;
589} 582}
590 583
@@ -613,7 +606,14 @@ request_firmware(const struct firmware **firmware_p, const char *name,
613 if (ret <= 0) 606 if (ret <= 0)
614 return ret; 607 return ret;
615 608
616 ret = _request_firmware(*firmware_p, name, device, true, false); 609 ret = usermodehelper_read_trylock();
610 if (WARN_ON(ret)) {
611 dev_err(device, "firmware: %s will not be loaded\n", name);
612 } else {
613 ret = _request_firmware(*firmware_p, name, device, true, false,
614 firmware_loading_timeout());
615 usermodehelper_read_unlock();
616 }
617 if (ret) 617 if (ret)
618 _request_firmware_cleanup(firmware_p); 618 _request_firmware_cleanup(firmware_p);
619 619
@@ -648,6 +648,7 @@ static int request_firmware_work_func(void *arg)
648{ 648{
649 struct firmware_work *fw_work = arg; 649 struct firmware_work *fw_work = arg;
650 const struct firmware *fw; 650 const struct firmware *fw;
651 long timeout;
651 int ret; 652 int ret;
652 653
653 if (!arg) { 654 if (!arg) {
@@ -659,8 +660,16 @@ static int request_firmware_work_func(void *arg)
659 if (ret <= 0) 660 if (ret <= 0)
660 goto out; 661 goto out;
661 662
662 ret = _request_firmware(fw, fw_work->name, fw_work->device, 663 timeout = usermodehelper_read_lock_wait(firmware_loading_timeout());
663 fw_work->uevent, true); 664 if (timeout) {
665 ret = _request_firmware(fw, fw_work->name, fw_work->device,
666 fw_work->uevent, true, timeout);
667 usermodehelper_read_unlock();
668 } else {
669 dev_dbg(fw_work->device, "firmware: %s loading timed out\n",
670 fw_work->name);
671 ret = -EAGAIN;
672 }
664 if (ret) 673 if (ret)
665 _request_firmware_cleanup(&fw); 674 _request_firmware_cleanup(&fw);
666 675