Commit 0e742e92 authored by Vikram Mulukutla's avatar Vikram Mulukutla Committed by Linus Torvalds

firmware: provide infrastructure to make fw caching optional

Some low memory systems with complex peripherals cannot afford to have
the relatively large firmware images taking up valuable memory during
suspend and resume.  Change the internal implementation of
firmware_class to disallow caching based on a configurable option.  In
the near future, variants of request_firmware will take advantage of
this feature.

Link: http://lkml.kernel.org/r/20160607164741.31849-3-stephen.boyd@linaro.org
[stephen.boyd@linaro.org: Drop firmware_desc design and use flags]
Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
Signed-off-by: default avatarStephen Boyd <stephen.boyd@linaro.org>
Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9ccf9811
...@@ -112,6 +112,7 @@ static inline long firmware_loading_timeout(void) ...@@ -112,6 +112,7 @@ static inline long firmware_loading_timeout(void)
#define FW_OPT_FALLBACK 0 #define FW_OPT_FALLBACK 0
#endif #endif
#define FW_OPT_NO_WARN (1U << 3) #define FW_OPT_NO_WARN (1U << 3)
#define FW_OPT_NOCACHE (1U << 4)
struct firmware_cache { struct firmware_cache {
/* firmware_buf instance will be added into the below list */ /* firmware_buf instance will be added into the below list */
...@@ -1065,14 +1066,16 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, ...@@ -1065,14 +1066,16 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device,
* should be fixed in devres or driver core. * should be fixed in devres or driver core.
*/ */
/* don't cache firmware handled without uevent */ /* don't cache firmware handled without uevent */
if (device && (opt_flags & FW_OPT_UEVENT)) if (device && (opt_flags & FW_OPT_UEVENT) &&
!(opt_flags & FW_OPT_NOCACHE))
fw_add_devm_name(device, buf->fw_id); fw_add_devm_name(device, buf->fw_id);
/* /*
* After caching firmware image is started, let it piggyback * After caching firmware image is started, let it piggyback
* on request firmware. * on request firmware.
*/ */
if (buf->fwc->state == FW_LOADER_START_CACHE) { if (!(opt_flags & FW_OPT_NOCACHE) &&
buf->fwc->state == FW_LOADER_START_CACHE) {
if (fw_cache_piggyback_on_request(buf->fw_id)) if (fw_cache_piggyback_on_request(buf->fw_id))
kref_get(&buf->ref); kref_get(&buf->ref);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment