aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_loader/fallback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/firmware_loader/fallback.c')
-rw-r--r--drivers/base/firmware_loader/fallback.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 358354148dec..b676a99c469c 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -125,7 +125,7 @@ static ssize_t timeout_show(struct class *class, struct class_attribute *attr,
125} 125}
126 126
127/** 127/**
128 * firmware_timeout_store - set number of seconds to wait for firmware 128 * firmware_timeout_store() - set number of seconds to wait for firmware
129 * @class: device class pointer 129 * @class: device class pointer
130 * @attr: device attribute pointer 130 * @attr: device attribute pointer
131 * @buf: buffer to scan for timeout value 131 * @buf: buffer to scan for timeout value
@@ -239,7 +239,7 @@ static int map_fw_priv_pages(struct fw_priv *fw_priv)
239} 239}
240 240
241/** 241/**
242 * firmware_loading_store - set value in the 'loading' control file 242 * firmware_loading_store() - set value in the 'loading' control file
243 * @dev: device pointer 243 * @dev: device pointer
244 * @attr: device attribute pointer 244 * @attr: device attribute pointer
245 * @buf: buffer to scan for loading control value 245 * @buf: buffer to scan for loading control value
@@ -431,7 +431,7 @@ static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size)
431} 431}
432 432
433/** 433/**
434 * firmware_data_write - write method for firmware 434 * firmware_data_write() - write method for firmware
435 * @filp: open sysfs file 435 * @filp: open sysfs file
436 * @kobj: kobject for the device 436 * @kobj: kobject for the device
437 * @bin_attr: bin_attr structure 437 * @bin_attr: bin_attr structure
@@ -512,7 +512,7 @@ static const struct attribute_group *fw_dev_attr_groups[] = {
512 512
513static struct fw_sysfs * 513static struct fw_sysfs *
514fw_create_instance(struct firmware *firmware, const char *fw_name, 514fw_create_instance(struct firmware *firmware, const char *fw_name,
515 struct device *device, unsigned int opt_flags) 515 struct device *device, enum fw_opt opt_flags)
516{ 516{
517 struct fw_sysfs *fw_sysfs; 517 struct fw_sysfs *fw_sysfs;
518 struct device *f_dev; 518 struct device *f_dev;
@@ -537,7 +537,7 @@ exit:
537} 537}
538 538
539/** 539/**
540 * fw_load_sysfs_fallback - load a firmware via the sysfs fallback mechanism 540 * fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism
541 * @fw_sysfs: firmware sysfs information for the firmware to load 541 * @fw_sysfs: firmware sysfs information for the firmware to load
542 * @opt_flags: flags of options, FW_OPT_* 542 * @opt_flags: flags of options, FW_OPT_*
543 * @timeout: timeout to wait for the load 543 * @timeout: timeout to wait for the load
@@ -545,7 +545,7 @@ exit:
545 * In charge of constructing a sysfs fallback interface for firmware loading. 545 * In charge of constructing a sysfs fallback interface for firmware loading.
546 **/ 546 **/
547static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, 547static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
548 unsigned int opt_flags, long timeout) 548 enum fw_opt opt_flags, long timeout)
549{ 549{
550 int retval = 0; 550 int retval = 0;
551 struct device *f_dev = &fw_sysfs->dev; 551 struct device *f_dev = &fw_sysfs->dev;
@@ -599,7 +599,7 @@ err_put_dev:
599 599
600static int fw_load_from_user_helper(struct firmware *firmware, 600static int fw_load_from_user_helper(struct firmware *firmware,
601 const char *name, struct device *device, 601 const char *name, struct device *device,
602 unsigned int opt_flags) 602 enum fw_opt opt_flags)
603{ 603{
604 struct fw_sysfs *fw_sysfs; 604 struct fw_sysfs *fw_sysfs;
605 long timeout; 605 long timeout;
@@ -640,7 +640,7 @@ out_unlock:
640 return ret; 640 return ret;
641} 641}
642 642
643static bool fw_force_sysfs_fallback(unsigned int opt_flags) 643static bool fw_force_sysfs_fallback(enum fw_opt opt_flags)
644{ 644{
645 if (fw_fallback_config.force_sysfs_fallback) 645 if (fw_fallback_config.force_sysfs_fallback)
646 return true; 646 return true;
@@ -649,7 +649,7 @@ static bool fw_force_sysfs_fallback(unsigned int opt_flags)
649 return true; 649 return true;
650} 650}
651 651
652static bool fw_run_sysfs_fallback(unsigned int opt_flags) 652static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
653{ 653{
654 if (fw_fallback_config.ignore_sysfs_fallback) { 654 if (fw_fallback_config.ignore_sysfs_fallback) {
655 pr_info_once("Ignoring firmware sysfs fallback due to sysctl knob\n"); 655 pr_info_once("Ignoring firmware sysfs fallback due to sysctl knob\n");
@@ -662,14 +662,39 @@ static bool fw_run_sysfs_fallback(unsigned int opt_flags)
662 return fw_force_sysfs_fallback(opt_flags); 662 return fw_force_sysfs_fallback(opt_flags);
663} 663}
664 664
665int fw_sysfs_fallback(struct firmware *fw, const char *name, 665/**
666 struct device *device, 666 * firmware_fallback_sysfs() - use the fallback mechanism to find firmware
667 unsigned int opt_flags, 667 * @fw: pointer to firmware image
668 int ret) 668 * @name: name of firmware file to look for
669 * @device: device for which firmware is being loaded
670 * @opt_flags: options to control firmware loading behaviour
671 * @ret: return value from direct lookup which triggered the fallback mechanism
672 *
673 * This function is called if direct lookup for the firmware failed, it enables
674 * a fallback mechanism through userspace by exposing a sysfs loading
675 * interface. Userspace is in charge of loading the firmware through the syfs
676 * loading interface. This syfs fallback mechanism may be disabled completely
677 * on a system by setting the proc sysctl value ignore_sysfs_fallback to true.
678 * If this false we check if the internal API caller set the @FW_OPT_NOFALLBACK
679 * flag, if so it would also disable the fallback mechanism. A system may want
680 * to enfoce the sysfs fallback mechanism at all times, it can do this by
681 * setting ignore_sysfs_fallback to false and force_sysfs_fallback to true.
682 * Enabling force_sysfs_fallback is functionally equivalent to build a kernel
683 * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK.
684 **/
685int firmware_fallback_sysfs(struct firmware *fw, const char *name,
686 struct device *device,
687 enum fw_opt opt_flags,
688 int ret)
669{ 689{
670 if (!fw_run_sysfs_fallback(opt_flags)) 690 if (!fw_run_sysfs_fallback(opt_flags))
671 return ret; 691 return ret;
672 692
673 dev_warn(device, "Falling back to user helper\n"); 693 if (!(opt_flags & FW_OPT_NO_WARN))
694 dev_warn(device, "Falling back to syfs fallback for: %s\n",
695 name);
696 else
697 dev_dbg(device, "Falling back to sysfs fallback for: %s\n",
698 name);
674 return fw_load_from_user_helper(fw, name, device, opt_flags); 699 return fw_load_from_user_helper(fw, name, device, opt_flags);
675} 700}