From 0e742e927571946e08e877d3629e6efd4891ed95 Mon Sep 17 00:00:00 2001 From: Vikram Mulukutla Date: Tue, 2 Aug 2016 14:04:25 -0700 Subject: [PATCH] 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: Vikram Mulukutla Signed-off-by: Stephen Boyd Cc: Mimi Zohar Cc: Mark Brown Cc: Ming Lei Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/firmware_class.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 01d55723d82c..45ed20cefa10 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -112,6 +112,7 @@ static inline long firmware_loading_timeout(void) #define FW_OPT_FALLBACK 0 #endif #define FW_OPT_NO_WARN (1U << 3) +#define FW_OPT_NOCACHE (1U << 4) struct firmware_cache { /* 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, * should be fixed in devres or driver core. */ /* 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); /* * After caching firmware image is started, let it piggyback * 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)) kref_get(&buf->ref); }