From a67e503b67a8b0d99c3fa96ae6c254ca5d8bb2ba Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 09:45:31 -0800 Subject: firmware: add helper to unregister pm ops This will be used later to unfold on error on init. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4b57cf5bc81d..149413a376cf 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -1767,11 +1767,20 @@ static int fw_suspend(void) static struct syscore_ops fw_syscore_ops = { .suspend = fw_suspend, }; + +static inline void unregister_fw_pm_ops(void) +{ + unregister_syscore_ops(&fw_syscore_ops); + unregister_pm_notifier(&fw_cache.pm_notify); +} #else static int fw_cache_piggyback_on_request(const char *name) { return 0; } +static inline void unregister_fw_pm_ops(void) +{ +} #endif static void __init fw_cache_init(void) @@ -1823,10 +1832,7 @@ static int __init firmware_class_init(void) static void __exit firmware_class_exit(void) { -#ifdef CONFIG_PM_SLEEP - unregister_syscore_ops(&fw_syscore_ops); - unregister_pm_notifier(&fw_cache.pm_notify); -#endif + unregister_fw_pm_ops(); unregister_reboot_notifier(&fw_shutdown_nb); #ifdef CONFIG_FW_LOADER_USER_HELPER class_unregister(&firmware_class); -- cgit v1.2.3 From 59b6d859ff0e36872396afdd3d853036408a87dc Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 09:45:32 -0800 Subject: firmware: fix capturing errors on fw_cache_init() on early init register_pm_notifier() can technically fail, caputure this. Note that register_syscore_ops() cannot fail given it just adds an element to a linked list. This has been broken since v3.7. Chances of this failing however are slim. To improve code readability move the code folded under CONFIG_PM_SLEEP into a helper. Fixes: 07646d9c0938d ("firmware loader: cache devices firmware during suspend/resume cycle") Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 45 ++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 149413a376cf..c8033c5488f9 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -1768,6 +1768,26 @@ static struct syscore_ops fw_syscore_ops = { .suspend = fw_suspend, }; +static int __init register_fw_pm_ops(void) +{ + int ret; + + spin_lock_init(&fw_cache.name_lock); + INIT_LIST_HEAD(&fw_cache.fw_names); + + INIT_DELAYED_WORK(&fw_cache.work, + device_uncache_fw_images_work); + + fw_cache.pm_notify.notifier_call = fw_pm_notify; + ret = register_pm_notifier(&fw_cache.pm_notify); + if (ret) + return ret; + + register_syscore_ops(&fw_syscore_ops); + + return ret; +} + static inline void unregister_fw_pm_ops(void) { unregister_syscore_ops(&fw_syscore_ops); @@ -1778,6 +1798,10 @@ static int fw_cache_piggyback_on_request(const char *name) { return 0; } +static inline int register_fw_pm_ops(void) +{ + return 0; +} static inline void unregister_fw_pm_ops(void) { } @@ -1788,19 +1812,6 @@ static void __init fw_cache_init(void) spin_lock_init(&fw_cache.lock); INIT_LIST_HEAD(&fw_cache.head); fw_cache.state = FW_LOADER_NO_CACHE; - -#ifdef CONFIG_PM_SLEEP - spin_lock_init(&fw_cache.name_lock); - INIT_LIST_HEAD(&fw_cache.fw_names); - - INIT_DELAYED_WORK(&fw_cache.work, - device_uncache_fw_images_work); - - fw_cache.pm_notify.notifier_call = fw_pm_notify; - register_pm_notifier(&fw_cache.pm_notify); - - register_syscore_ops(&fw_syscore_ops); -#endif } static int fw_shutdown_notify(struct notifier_block *unused1, @@ -1821,7 +1832,15 @@ static struct notifier_block fw_shutdown_nb = { static int __init firmware_class_init(void) { + int ret; + + /* No need to unfold these on exit */ fw_cache_init(); + + ret = register_fw_pm_ops(); + if (ret) + return ret; + register_reboot_notifier(&fw_shutdown_nb); #ifdef CONFIG_FW_LOADER_USER_HELPER return class_register(&firmware_class); -- cgit v1.2.3 From 6bb9cf3aa3edf5968877d3f7863e232d4b9394a4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 09:45:33 -0800 Subject: firmware: provide helpers for registering the syfs loader This makes init / exit much easier to read, and we can later reuse this code on other errors not captured yet. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index c8033c5488f9..3340a17e0499 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -687,6 +687,16 @@ static struct class firmware_class = { .dev_release = fw_dev_release, }; +static inline int register_sysfs_loader(void) +{ + return class_register(&firmware_class); +} + +static inline void unregister_sysfs_loader(void) +{ + class_unregister(&firmware_class); +} + static ssize_t firmware_loading_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1124,6 +1134,15 @@ fw_load_from_user_helper(struct firmware *firmware, const char *name, static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { } +static inline int register_sysfs_loader(void) +{ + return 0; +} + +static inline void unregister_sysfs_loader(void) +{ +} + #endif /* CONFIG_FW_LOADER_USER_HELPER */ /* prepare firmware and firmware_buf structs; @@ -1842,20 +1861,14 @@ static int __init firmware_class_init(void) return ret; register_reboot_notifier(&fw_shutdown_nb); -#ifdef CONFIG_FW_LOADER_USER_HELPER - return class_register(&firmware_class); -#else - return 0; -#endif + return register_sysfs_loader(); } static void __exit firmware_class_exit(void) { unregister_fw_pm_ops(); unregister_reboot_notifier(&fw_shutdown_nb); -#ifdef CONFIG_FW_LOADER_USER_HELPER - class_unregister(&firmware_class); -#endif + unregister_sysfs_loader(); } fs_initcall(firmware_class_init); -- cgit v1.2.3 From 561a10b6a15b531de359ccfc489488c733bb2821 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 09:45:34 -0800 Subject: firmware: fix detecting error on register_reboot_notifier() register_reboot_notifier() can fail, detect this and address this failure. This has been broken since v3.11, however the chances of this failing here is really low. Fixes: fe304143b0c3d ("firmware: Avoid deadlock of usermodehelper lock at shutdown") Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3340a17e0499..7ab54f2b032f 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -1860,8 +1860,15 @@ static int __init firmware_class_init(void) if (ret) return ret; - register_reboot_notifier(&fw_shutdown_nb); + ret = register_reboot_notifier(&fw_shutdown_nb); + if (ret) + goto out; + return register_sysfs_loader(); + +out: + unregister_fw_pm_ops(); + return ret; } static void __exit firmware_class_exit(void) -- cgit v1.2.3 From aa6969c903a59ff509e2354a5ab338ac9189c5e4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:47 -0800 Subject: firmware: rename struct firmware_priv to struct fw_sysfs The struct firmware_priv is only used for the sysfs fallback mechanism, rename it to make emphasis of this. This will also enable us to use the name later for something much more meaninful. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 98 +++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 49 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 7ab54f2b032f..82bc70f66996 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -254,7 +254,7 @@ struct fw_name_devm { static int fw_cache_piggyback_on_request(const char *name); -/* fw_lock could be moved to 'struct firmware_priv' but since it is just +/* fw_lock could be moved to 'struct fw_sysfs' but since it is just * guarding for corner cases a global lock should be OK */ static DEFINE_MUTEX(fw_lock); @@ -566,16 +566,16 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, * user-mode helper code */ #ifdef CONFIG_FW_LOADER_USER_HELPER -struct firmware_priv { +struct fw_sysfs { bool nowait; struct device dev; struct firmware_buf *buf; struct firmware *fw; }; -static struct firmware_priv *to_firmware_priv(struct device *dev) +static struct fw_sysfs *to_fw_sysfs(struct device *dev) { - return container_of(dev, struct firmware_priv, dev); + return container_of(dev, struct fw_sysfs, dev); } static void __fw_load_abort(struct firmware_buf *buf) @@ -591,9 +591,9 @@ static void __fw_load_abort(struct firmware_buf *buf) fw_state_aborted(&buf->fw_st); } -static void fw_load_abort(struct firmware_priv *fw_priv) +static void fw_load_abort(struct fw_sysfs *fw_sysfs) { - struct firmware_buf *buf = fw_priv->buf; + struct firmware_buf *buf = fw_sysfs->buf; __fw_load_abort(buf); } @@ -651,18 +651,18 @@ ATTRIBUTE_GROUPS(firmware_class); static void fw_dev_release(struct device *dev) { - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); - kfree(fw_priv); + kfree(fw_sysfs); } -static int do_firmware_uevent(struct firmware_priv *fw_priv, struct kobj_uevent_env *env) +static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) { - if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->buf->fw_id)) + if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->buf->fw_id)) return -ENOMEM; if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) return -ENOMEM; - if (add_uevent_var(env, "ASYNC=%d", fw_priv->nowait)) + if (add_uevent_var(env, "ASYNC=%d", fw_sysfs->nowait)) return -ENOMEM; return 0; @@ -670,12 +670,12 @@ static int do_firmware_uevent(struct firmware_priv *fw_priv, struct kobj_uevent_ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); int err = 0; mutex_lock(&fw_lock); - if (fw_priv->buf) - err = do_firmware_uevent(fw_priv, env); + if (fw_sysfs->buf) + err = do_firmware_uevent(fw_sysfs, env); mutex_unlock(&fw_lock); return err; } @@ -700,12 +700,12 @@ static inline void unregister_sysfs_loader(void) static ssize_t firmware_loading_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); int loading = 0; mutex_lock(&fw_lock); - if (fw_priv->buf) - loading = fw_state_is_loading(&fw_priv->buf->fw_st); + if (fw_sysfs->buf) + loading = fw_state_is_loading(&fw_sysfs->buf->fw_st); mutex_unlock(&fw_lock); return sprintf(buf, "%d\n", loading); @@ -746,14 +746,14 @@ static ssize_t firmware_loading_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct firmware_buf *fw_buf; ssize_t written = count; int loading = simple_strtol(buf, NULL, 10); int i; mutex_lock(&fw_lock); - fw_buf = fw_priv->buf; + fw_buf = fw_sysfs->buf; if (fw_state_is_aborted(&fw_buf->fw_st)) goto out; @@ -807,7 +807,7 @@ static ssize_t firmware_loading_store(struct device *dev, dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); /* fallthrough */ case -1: - fw_load_abort(fw_priv); + fw_load_abort(fw_sysfs); break; } out: @@ -854,12 +854,12 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, char *buffer, loff_t offset, size_t count) { struct device *dev = kobj_to_dev(kobj); - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct firmware_buf *buf; ssize_t ret_count; mutex_lock(&fw_lock); - buf = fw_priv->buf; + buf = fw_sysfs->buf; if (!buf || fw_state_is_done(&buf->fw_st)) { ret_count = -ENODEV; goto out; @@ -883,9 +883,9 @@ out: return ret_count; } -static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) +static int fw_realloc_buffer(struct fw_sysfs *fw_sysfs, int min_size) { - struct firmware_buf *buf = fw_priv->buf; + struct firmware_buf *buf = fw_sysfs->buf; int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; /* If the array of pages is too small, grow it... */ @@ -896,7 +896,7 @@ static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) new_pages = vmalloc(new_array_size * sizeof(void *)); if (!new_pages) { - fw_load_abort(fw_priv); + fw_load_abort(fw_sysfs); return -ENOMEM; } memcpy(new_pages, buf->pages, @@ -913,7 +913,7 @@ static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) alloc_page(GFP_KERNEL | __GFP_HIGHMEM); if (!buf->pages[buf->nr_pages]) { - fw_load_abort(fw_priv); + fw_load_abort(fw_sysfs); return -ENOMEM; } buf->nr_pages++; @@ -938,7 +938,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, char *buffer, loff_t offset, size_t count) { struct device *dev = kobj_to_dev(kobj); - struct firmware_priv *fw_priv = to_firmware_priv(dev); + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct firmware_buf *buf; ssize_t retval; @@ -946,7 +946,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, return -EPERM; mutex_lock(&fw_lock); - buf = fw_priv->buf; + buf = fw_sysfs->buf; if (!buf || fw_state_is_done(&buf->fw_st)) { retval = -ENODEV; goto out; @@ -960,7 +960,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, firmware_rw_buf(buf, buffer, offset, count, false); retval = count; } else { - retval = fw_realloc_buffer(fw_priv, offset + count); + retval = fw_realloc_buffer(fw_sysfs, offset + count); if (retval) goto out; @@ -1001,22 +1001,22 @@ static const struct attribute_group *fw_dev_attr_groups[] = { NULL }; -static struct firmware_priv * +static struct fw_sysfs * fw_create_instance(struct firmware *firmware, const char *fw_name, struct device *device, unsigned int opt_flags) { - struct firmware_priv *fw_priv; + struct fw_sysfs *fw_sysfs; struct device *f_dev; - fw_priv = kzalloc(sizeof(*fw_priv), GFP_KERNEL); - if (!fw_priv) { - fw_priv = ERR_PTR(-ENOMEM); + fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL); + if (!fw_sysfs) { + fw_sysfs = ERR_PTR(-ENOMEM); goto exit; } - fw_priv->nowait = !!(opt_flags & FW_OPT_NOWAIT); - fw_priv->fw = firmware; - f_dev = &fw_priv->dev; + fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT); + fw_sysfs->fw = firmware; + f_dev = &fw_sysfs->dev; device_initialize(f_dev); dev_set_name(f_dev, "%s", fw_name); @@ -1024,16 +1024,16 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, f_dev->class = &firmware_class; f_dev->groups = fw_dev_attr_groups; exit: - return fw_priv; + return fw_sysfs; } /* load a firmware via user helper */ -static int _request_firmware_load(struct firmware_priv *fw_priv, +static int _request_firmware_load(struct fw_sysfs *fw_sysfs, unsigned int opt_flags, long timeout) { int retval = 0; - struct device *f_dev = &fw_priv->dev; - struct firmware_buf *buf = fw_priv->buf; + struct device *f_dev = &fw_sysfs->dev; + struct firmware_buf *buf = fw_sysfs->buf; /* fall back on userspace loading */ if (!buf->data) @@ -1055,7 +1055,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, buf->need_uevent = true; dev_set_uevent_suppress(f_dev, false); dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); - kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); + kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); } else { timeout = MAX_JIFFY_OFFSET; } @@ -1063,7 +1063,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, retval = fw_state_wait_timeout(&buf->fw_st, timeout); if (retval < 0) { mutex_lock(&fw_lock); - fw_load_abort(fw_priv); + fw_load_abort(fw_sysfs); mutex_unlock(&fw_lock); } @@ -1085,7 +1085,7 @@ static int fw_load_from_user_helper(struct firmware *firmware, const char *name, struct device *device, unsigned int opt_flags) { - struct firmware_priv *fw_priv; + struct fw_sysfs *fw_sysfs; long timeout; int ret; @@ -1106,14 +1106,14 @@ static int fw_load_from_user_helper(struct firmware *firmware, } } - fw_priv = fw_create_instance(firmware, name, device, opt_flags); - if (IS_ERR(fw_priv)) { - ret = PTR_ERR(fw_priv); + fw_sysfs = fw_create_instance(firmware, name, device, opt_flags); + if (IS_ERR(fw_sysfs)) { + ret = PTR_ERR(fw_sysfs); goto out_unlock; } - fw_priv->buf = firmware->priv; - ret = _request_firmware_load(fw_priv, opt_flags, timeout); + fw_sysfs->buf = firmware->priv; + ret = _request_firmware_load(fw_sysfs, opt_flags, timeout); if (!ret) ret = assign_firmware_buf(firmware, device, opt_flags); -- cgit v1.2.3 From cd5322b7a6b463f0fcf3ef6d9ae2134a49e51b7c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:48 -0800 Subject: firmware: rename struct firmware_buf to struct fw_priv This reflects much better what this is used for. It also puts emphasis on the fact we can and should be able to extend this data structure as we see fit internally as its the opaque private pointer on struct firmware. As we rename the data structure, also rename a few functions that use it to reflect better what they are for. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 372 +++++++++++++++++++++--------------------- 1 file changed, 187 insertions(+), 185 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 82bc70f66996..3f95a9e55b4b 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -218,7 +218,7 @@ struct firmware_cache { #endif }; -struct firmware_buf { +struct fw_priv { struct kref ref; struct list_head list; struct firmware_cache *fwc; @@ -247,7 +247,7 @@ struct fw_name_devm { const char *name; }; -#define to_fwbuf(d) container_of(d, struct firmware_buf, ref) +#define to_fw_priv(d) container_of(d, struct fw_priv, ref) #define FW_LOADER_NO_CACHE 0 #define FW_LOADER_START_CACHE 1 @@ -260,39 +260,39 @@ static DEFINE_MUTEX(fw_lock); static struct firmware_cache fw_cache; -static struct firmware_buf *__allocate_fw_buf(const char *fw_name, - struct firmware_cache *fwc, - void *dbuf, size_t size) +static struct fw_priv *__allocate_fw_priv(const char *fw_name, + struct firmware_cache *fwc, + void *dbuf, size_t size) { - struct firmware_buf *buf; + struct fw_priv *fw_priv; - buf = kzalloc(sizeof(*buf), GFP_ATOMIC); - if (!buf) + fw_priv = kzalloc(sizeof(*fw_priv), GFP_ATOMIC); + if (!fw_priv) return NULL; - buf->fw_id = kstrdup_const(fw_name, GFP_ATOMIC); - if (!buf->fw_id) { - kfree(buf); + fw_priv->fw_id = kstrdup_const(fw_name, GFP_ATOMIC); + if (!fw_priv->fw_id) { + kfree(fw_priv); return NULL; } - kref_init(&buf->ref); - buf->fwc = fwc; - buf->data = dbuf; - buf->allocated_size = size; - fw_state_init(&buf->fw_st); + kref_init(&fw_priv->ref); + fw_priv->fwc = fwc; + fw_priv->data = dbuf; + fw_priv->allocated_size = size; + fw_state_init(&fw_priv->fw_st); #ifdef CONFIG_FW_LOADER_USER_HELPER - INIT_LIST_HEAD(&buf->pending_list); + INIT_LIST_HEAD(&fw_priv->pending_list); #endif - pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); + pr_debug("%s: fw-%s fw_priv=%p\n", __func__, fw_name, fw_priv); - return buf; + return fw_priv; } -static struct firmware_buf *__fw_lookup_buf(const char *fw_name) +static struct fw_priv *__lookup_fw_priv(const char *fw_name) { - struct firmware_buf *tmp; + struct fw_priv *tmp; struct firmware_cache *fwc = &fw_cache; list_for_each_entry(tmp, &fwc->head, list) @@ -302,65 +302,65 @@ static struct firmware_buf *__fw_lookup_buf(const char *fw_name) } /* Returns 1 for batching firmware requests with the same name */ -static int fw_lookup_and_allocate_buf(const char *fw_name, - struct firmware_cache *fwc, - struct firmware_buf **buf, void *dbuf, - size_t size) +static int alloc_lookup_fw_priv(const char *fw_name, + struct firmware_cache *fwc, + struct fw_priv **fw_priv, void *dbuf, + size_t size) { - struct firmware_buf *tmp; + struct fw_priv *tmp; spin_lock(&fwc->lock); - tmp = __fw_lookup_buf(fw_name); + tmp = __lookup_fw_priv(fw_name); if (tmp) { kref_get(&tmp->ref); spin_unlock(&fwc->lock); - *buf = tmp; - pr_debug("batched request - sharing the same struct firmware_buf and lookup for multiple requests\n"); + *fw_priv = tmp; + pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n"); return 1; } - tmp = __allocate_fw_buf(fw_name, fwc, dbuf, size); + tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size); if (tmp) list_add(&tmp->list, &fwc->head); spin_unlock(&fwc->lock); - *buf = tmp; + *fw_priv = tmp; return tmp ? 0 : -ENOMEM; } -static void __fw_free_buf(struct kref *ref) +static void __free_fw_priv(struct kref *ref) __releases(&fwc->lock) { - struct firmware_buf *buf = to_fwbuf(ref); - struct firmware_cache *fwc = buf->fwc; + struct fw_priv *fw_priv = to_fw_priv(ref); + struct firmware_cache *fwc = fw_priv->fwc; - pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", - __func__, buf->fw_id, buf, buf->data, - (unsigned int)buf->size); + pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n", + __func__, fw_priv->fw_id, fw_priv, fw_priv->data, + (unsigned int)fw_priv->size); - list_del(&buf->list); + list_del(&fw_priv->list); spin_unlock(&fwc->lock); #ifdef CONFIG_FW_LOADER_USER_HELPER - if (buf->is_paged_buf) { + if (fw_priv->is_paged_buf) { int i; - vunmap(buf->data); - for (i = 0; i < buf->nr_pages; i++) - __free_page(buf->pages[i]); - vfree(buf->pages); + vunmap(fw_priv->data); + for (i = 0; i < fw_priv->nr_pages; i++) + __free_page(fw_priv->pages[i]); + vfree(fw_priv->pages); } else #endif - if (!buf->allocated_size) - vfree(buf->data); - kfree_const(buf->fw_id); - kfree(buf); + if (!fw_priv->allocated_size) + vfree(fw_priv->data); + kfree_const(fw_priv->fw_id); + kfree(fw_priv); } -static void fw_free_buf(struct firmware_buf *buf) +static void free_fw_priv(struct fw_priv *fw_priv) { - struct firmware_cache *fwc = buf->fwc; + struct firmware_cache *fwc = fw_priv->fwc; spin_lock(&fwc->lock); - if (!kref_put(&buf->ref, __fw_free_buf)) + if (!kref_put(&fw_priv->ref, __free_fw_priv)) spin_unlock(&fwc->lock); } @@ -383,7 +383,7 @@ module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); static int -fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) +fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) { loff_t size; int i, len; @@ -393,9 +393,9 @@ fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) size_t msize = INT_MAX; /* Already populated data member means we're loading into a buffer */ - if (buf->data) { + if (fw_priv->data) { id = READING_FIRMWARE_PREALLOC_BUFFER; - msize = buf->allocated_size; + msize = fw_priv->allocated_size; } path = __getname(); @@ -408,15 +408,15 @@ fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) continue; len = snprintf(path, PATH_MAX, "%s/%s", - fw_path[i], buf->fw_id); + fw_path[i], fw_priv->fw_id); if (len >= PATH_MAX) { rc = -ENAMETOOLONG; break; } - buf->size = 0; - rc = kernel_read_file_from_path(path, &buf->data, &size, msize, - id); + fw_priv->size = 0; + rc = kernel_read_file_from_path(path, &fw_priv->data, &size, + msize, id); if (rc) { if (rc == -ENOENT) dev_dbg(device, "loading %s failed with error %d\n", @@ -426,9 +426,9 @@ fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) path, rc); continue; } - dev_dbg(device, "direct-loading %s\n", buf->fw_id); - buf->size = size; - fw_state_done(&buf->fw_st); + dev_dbg(device, "direct-loading %s\n", fw_priv->fw_id); + fw_priv->size = size; + fw_state_done(&fw_priv->fw_st); break; } __putname(path); @@ -444,22 +444,22 @@ static void firmware_free_data(const struct firmware *fw) vfree(fw->data); return; } - fw_free_buf(fw->priv); + free_fw_priv(fw->priv); } /* store the pages buffer info firmware from buf */ -static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) +static void fw_set_page_data(struct fw_priv *fw_priv, struct firmware *fw) { - fw->priv = buf; + fw->priv = fw_priv; #ifdef CONFIG_FW_LOADER_USER_HELPER - fw->pages = buf->pages; + fw->pages = fw_priv->pages; #endif - fw->size = buf->size; - fw->data = buf->data; + fw->size = fw_priv->size; + fw->data = fw_priv->data; - pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", - __func__, buf->fw_id, buf, buf->data, - (unsigned int)buf->size); + pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n", + __func__, fw_priv->fw_id, fw_priv, fw_priv->data, + (unsigned int)fw_priv->size); } #ifdef CONFIG_PM_SLEEP @@ -523,13 +523,13 @@ static int fw_add_devm_name(struct device *dev, const char *name) } #endif -static int assign_firmware_buf(struct firmware *fw, struct device *device, - unsigned int opt_flags) +static int assign_fw(struct firmware *fw, struct device *device, + unsigned int opt_flags) { - struct firmware_buf *buf = fw->priv; + struct fw_priv *fw_priv = fw->priv; mutex_lock(&fw_lock); - if (!buf->size || fw_state_is_aborted(&buf->fw_st)) { + if (!fw_priv->size || fw_state_is_aborted(&fw_priv->fw_st)) { mutex_unlock(&fw_lock); return -ENOENT; } @@ -544,20 +544,20 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, /* don't cache firmware handled without 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, fw_priv->fw_id); /* * After caching firmware image is started, let it piggyback * on request firmware. */ 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); + fw_priv->fwc->state == FW_LOADER_START_CACHE) { + if (fw_cache_piggyback_on_request(fw_priv->fw_id)) + kref_get(&fw_priv->ref); } /* pass the pages buffer to driver at the last minute */ - fw_set_page_data(buf, fw); + fw_set_page_data(fw_priv, fw); mutex_unlock(&fw_lock); return 0; } @@ -569,7 +569,7 @@ static int assign_firmware_buf(struct firmware *fw, struct device *device, struct fw_sysfs { bool nowait; struct device dev; - struct firmware_buf *buf; + struct fw_priv *fw_priv; struct firmware *fw; }; @@ -578,37 +578,38 @@ static struct fw_sysfs *to_fw_sysfs(struct device *dev) return container_of(dev, struct fw_sysfs, dev); } -static void __fw_load_abort(struct firmware_buf *buf) +static void __fw_load_abort(struct fw_priv *fw_priv) { /* * There is a small window in which user can write to 'loading' * between loading done and disappearance of 'loading' */ - if (fw_state_is_done(&buf->fw_st)) + if (fw_state_is_done(&fw_priv->fw_st)) return; - list_del_init(&buf->pending_list); - fw_state_aborted(&buf->fw_st); + list_del_init(&fw_priv->pending_list); + fw_state_aborted(&fw_priv->fw_st); } static void fw_load_abort(struct fw_sysfs *fw_sysfs) { - struct firmware_buf *buf = fw_sysfs->buf; + struct fw_priv *fw_priv = fw_sysfs->fw_priv; - __fw_load_abort(buf); + __fw_load_abort(fw_priv); } static LIST_HEAD(pending_fw_head); static void kill_pending_fw_fallback_reqs(bool only_kill_custom) { - struct firmware_buf *buf; - struct firmware_buf *next; + struct fw_priv *fw_priv; + struct fw_priv *next; mutex_lock(&fw_lock); - list_for_each_entry_safe(buf, next, &pending_fw_head, pending_list) { - if (!buf->need_uevent || !only_kill_custom) - __fw_load_abort(buf); + list_for_each_entry_safe(fw_priv, next, &pending_fw_head, + pending_list) { + if (!fw_priv->need_uevent || !only_kill_custom) + __fw_load_abort(fw_priv); } mutex_unlock(&fw_lock); } @@ -658,7 +659,7 @@ static void fw_dev_release(struct device *dev) static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) { - if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->buf->fw_id)) + if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_id)) return -ENOMEM; if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) return -ENOMEM; @@ -674,7 +675,7 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) int err = 0; mutex_lock(&fw_lock); - if (fw_sysfs->buf) + if (fw_sysfs->fw_priv) err = do_firmware_uevent(fw_sysfs, env); mutex_unlock(&fw_lock); return err; @@ -704,8 +705,8 @@ static ssize_t firmware_loading_show(struct device *dev, int loading = 0; mutex_lock(&fw_lock); - if (fw_sysfs->buf) - loading = fw_state_is_loading(&fw_sysfs->buf->fw_st); + if (fw_sysfs->fw_priv) + loading = fw_state_is_loading(&fw_sysfs->fw_priv->fw_st); mutex_unlock(&fw_lock); return sprintf(buf, "%d\n", loading); @@ -717,14 +718,15 @@ static ssize_t firmware_loading_show(struct device *dev, #endif /* one pages buffer should be mapped/unmapped only once */ -static int fw_map_pages_buf(struct firmware_buf *buf) +static int map_fw_priv_pages(struct fw_priv *fw_priv) { - if (!buf->is_paged_buf) + if (!fw_priv->is_paged_buf) return 0; - vunmap(buf->data); - buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); - if (!buf->data) + vunmap(fw_priv->data); + fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, + PAGE_KERNEL_RO); + if (!fw_priv->data) return -ENOMEM; return 0; } @@ -747,31 +749,31 @@ static ssize_t firmware_loading_store(struct device *dev, const char *buf, size_t count) { struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); - struct firmware_buf *fw_buf; + struct fw_priv *fw_priv; ssize_t written = count; int loading = simple_strtol(buf, NULL, 10); int i; mutex_lock(&fw_lock); - fw_buf = fw_sysfs->buf; - if (fw_state_is_aborted(&fw_buf->fw_st)) + fw_priv = fw_sysfs->fw_priv; + if (fw_state_is_aborted(&fw_priv->fw_st)) goto out; switch (loading) { case 1: /* discarding any previous partial load */ - if (!fw_state_is_done(&fw_buf->fw_st)) { - for (i = 0; i < fw_buf->nr_pages; i++) - __free_page(fw_buf->pages[i]); - vfree(fw_buf->pages); - fw_buf->pages = NULL; - fw_buf->page_array_size = 0; - fw_buf->nr_pages = 0; - fw_state_start(&fw_buf->fw_st); + if (!fw_state_is_done(&fw_priv->fw_st)) { + for (i = 0; i < fw_priv->nr_pages; i++) + __free_page(fw_priv->pages[i]); + vfree(fw_priv->pages); + fw_priv->pages = NULL; + fw_priv->page_array_size = 0; + fw_priv->nr_pages = 0; + fw_state_start(&fw_priv->fw_st); } break; case 0: - if (fw_state_is_loading(&fw_buf->fw_st)) { + if (fw_state_is_loading(&fw_priv->fw_st)) { int rc; /* @@ -780,25 +782,25 @@ static ssize_t firmware_loading_store(struct device *dev, * see the mapped 'buf->data' once the loading * is completed. * */ - rc = fw_map_pages_buf(fw_buf); + rc = map_fw_priv_pages(fw_priv); if (rc) dev_err(dev, "%s: map pages failed\n", __func__); else rc = security_kernel_post_read_file(NULL, - fw_buf->data, fw_buf->size, + fw_priv->data, fw_priv->size, READING_FIRMWARE); /* * Same logic as fw_load_abort, only the DONE bit * is ignored and we set ABORT only on failure. */ - list_del_init(&fw_buf->pending_list); + list_del_init(&fw_priv->pending_list); if (rc) { - fw_state_aborted(&fw_buf->fw_st); + fw_state_aborted(&fw_priv->fw_st); written = rc; } else { - fw_state_done(&fw_buf->fw_st); + fw_state_done(&fw_priv->fw_st); } break; } @@ -817,16 +819,16 @@ out: static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); -static void firmware_rw_buf(struct firmware_buf *buf, char *buffer, +static void firmware_rw_data(struct fw_priv *fw_priv, char *buffer, loff_t offset, size_t count, bool read) { if (read) - memcpy(buffer, buf->data + offset, count); + memcpy(buffer, fw_priv->data + offset, count); else - memcpy(buf->data + offset, buffer, count); + memcpy(fw_priv->data + offset, buffer, count); } -static void firmware_rw(struct firmware_buf *buf, char *buffer, +static void firmware_rw(struct fw_priv *fw_priv, char *buffer, loff_t offset, size_t count, bool read) { while (count) { @@ -835,14 +837,14 @@ static void firmware_rw(struct firmware_buf *buf, char *buffer, int page_ofs = offset & (PAGE_SIZE-1); int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); - page_data = kmap(buf->pages[page_nr]); + page_data = kmap(fw_priv->pages[page_nr]); if (read) memcpy(buffer, page_data + page_ofs, page_cnt); else memcpy(page_data + page_ofs, buffer, page_cnt); - kunmap(buf->pages[page_nr]); + kunmap(fw_priv->pages[page_nr]); buffer += page_cnt; offset += page_cnt; count -= page_cnt; @@ -855,43 +857,43 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); - struct firmware_buf *buf; + struct fw_priv *fw_priv; ssize_t ret_count; mutex_lock(&fw_lock); - buf = fw_sysfs->buf; - if (!buf || fw_state_is_done(&buf->fw_st)) { + fw_priv = fw_sysfs->fw_priv; + if (!fw_priv || fw_state_is_done(&fw_priv->fw_st)) { ret_count = -ENODEV; goto out; } - if (offset > buf->size) { + if (offset > fw_priv->size) { ret_count = 0; goto out; } - if (count > buf->size - offset) - count = buf->size - offset; + if (count > fw_priv->size - offset) + count = fw_priv->size - offset; ret_count = count; - if (buf->data) - firmware_rw_buf(buf, buffer, offset, count, true); + if (fw_priv->data) + firmware_rw_data(fw_priv, buffer, offset, count, true); else - firmware_rw(buf, buffer, offset, count, true); + firmware_rw(fw_priv, buffer, offset, count, true); out: mutex_unlock(&fw_lock); return ret_count; } -static int fw_realloc_buffer(struct fw_sysfs *fw_sysfs, int min_size) +static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) { - struct firmware_buf *buf = fw_sysfs->buf; + struct fw_priv *fw_priv= fw_sysfs->fw_priv; int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; /* If the array of pages is too small, grow it... */ - if (buf->page_array_size < pages_needed) { + if (fw_priv->page_array_size < pages_needed) { int new_array_size = max(pages_needed, - buf->page_array_size * 2); + fw_priv->page_array_size * 2); struct page **new_pages; new_pages = vmalloc(new_array_size * sizeof(void *)); @@ -899,24 +901,24 @@ static int fw_realloc_buffer(struct fw_sysfs *fw_sysfs, int min_size) fw_load_abort(fw_sysfs); return -ENOMEM; } - memcpy(new_pages, buf->pages, - buf->page_array_size * sizeof(void *)); - memset(&new_pages[buf->page_array_size], 0, sizeof(void *) * - (new_array_size - buf->page_array_size)); - vfree(buf->pages); - buf->pages = new_pages; - buf->page_array_size = new_array_size; + memcpy(new_pages, fw_priv->pages, + fw_priv->page_array_size * sizeof(void *)); + memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * + (new_array_size - fw_priv->page_array_size)); + vfree(fw_priv->pages); + fw_priv->pages = new_pages; + fw_priv->page_array_size = new_array_size; } - while (buf->nr_pages < pages_needed) { - buf->pages[buf->nr_pages] = + while (fw_priv->nr_pages < pages_needed) { + fw_priv->pages[fw_priv->nr_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); - if (!buf->pages[buf->nr_pages]) { + if (!fw_priv->pages[fw_priv->nr_pages]) { fw_load_abort(fw_sysfs); return -ENOMEM; } - buf->nr_pages++; + fw_priv->nr_pages++; } return 0; } @@ -939,36 +941,36 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); - struct firmware_buf *buf; + struct fw_priv *fw_priv; ssize_t retval; if (!capable(CAP_SYS_RAWIO)) return -EPERM; mutex_lock(&fw_lock); - buf = fw_sysfs->buf; - if (!buf || fw_state_is_done(&buf->fw_st)) { + fw_priv = fw_sysfs->fw_priv; + if (!fw_priv || fw_state_is_done(&fw_priv->fw_st)) { retval = -ENODEV; goto out; } - if (buf->data) { - if (offset + count > buf->allocated_size) { + if (fw_priv->data) { + if (offset + count > fw_priv->allocated_size) { retval = -ENOMEM; goto out; } - firmware_rw_buf(buf, buffer, offset, count, false); + firmware_rw_data(fw_priv, buffer, offset, count, false); retval = count; } else { - retval = fw_realloc_buffer(fw_sysfs, offset + count); + retval = fw_realloc_pages(fw_sysfs, offset + count); if (retval) goto out; retval = count; - firmware_rw(buf, buffer, offset, count, false); + firmware_rw(fw_priv, buffer, offset, count, false); } - buf->size = max_t(size_t, offset + count, buf->size); + fw_priv->size = max_t(size_t, offset + count, fw_priv->size); out: mutex_unlock(&fw_lock); return retval; @@ -1033,11 +1035,11 @@ static int _request_firmware_load(struct fw_sysfs *fw_sysfs, { int retval = 0; struct device *f_dev = &fw_sysfs->dev; - struct firmware_buf *buf = fw_sysfs->buf; + struct fw_priv *fw_priv = fw_sysfs->fw_priv; /* fall back on userspace loading */ - if (!buf->data) - buf->is_paged_buf = true; + if (!fw_priv->data) + fw_priv->is_paged_buf = true; dev_set_uevent_suppress(f_dev, true); @@ -1048,31 +1050,31 @@ static int _request_firmware_load(struct fw_sysfs *fw_sysfs, } mutex_lock(&fw_lock); - list_add(&buf->pending_list, &pending_fw_head); + list_add(&fw_priv->pending_list, &pending_fw_head); mutex_unlock(&fw_lock); if (opt_flags & FW_OPT_UEVENT) { - buf->need_uevent = true; + fw_priv->need_uevent = true; dev_set_uevent_suppress(f_dev, false); - dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); + dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_id); kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); } else { timeout = MAX_JIFFY_OFFSET; } - retval = fw_state_wait_timeout(&buf->fw_st, timeout); + retval = fw_state_wait_timeout(&fw_priv->fw_st, timeout); if (retval < 0) { mutex_lock(&fw_lock); fw_load_abort(fw_sysfs); mutex_unlock(&fw_lock); } - if (fw_state_is_aborted(&buf->fw_st)) { + if (fw_state_is_aborted(&fw_priv->fw_st)) { if (retval == -ERESTARTSYS) retval = -EINTR; else retval = -EAGAIN; - } else if (buf->is_paged_buf && !buf->data) + } else if (fw_priv->is_paged_buf && !fw_priv->data) retval = -ENOMEM; device_del(f_dev); @@ -1112,11 +1114,11 @@ static int fw_load_from_user_helper(struct firmware *firmware, goto out_unlock; } - fw_sysfs->buf = firmware->priv; + fw_sysfs->fw_priv = firmware->priv; ret = _request_firmware_load(fw_sysfs, opt_flags, timeout); if (!ret) - ret = assign_firmware_buf(firmware, device, opt_flags); + ret = assign_fw(firmware, device, opt_flags); out_unlock: usermodehelper_read_unlock(); @@ -1154,7 +1156,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, struct device *device, void *dbuf, size_t size) { struct firmware *firmware; - struct firmware_buf *buf; + struct fw_priv *fw_priv; int ret; *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); @@ -1169,18 +1171,18 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, return 0; /* assigned */ } - ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf, dbuf, size); + ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size); /* - * bind with 'buf' now to avoid warning in failure path + * bind with 'priv' now to avoid warning in failure path * of requesting firmware. */ - firmware->priv = buf; + firmware->priv = fw_priv; if (ret > 0) { - ret = fw_state_wait(&buf->fw_st); + ret = fw_state_wait(&fw_priv->fw_st); if (!ret) { - fw_set_page_data(buf, firmware); + fw_set_page_data(fw_priv, firmware); return 0; /* assigned */ } } @@ -1196,20 +1198,20 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, * released until the last user calls release_firmware(). * * Failed batched requests are possible as well, in such cases we just share - * the struct firmware_buf and won't release it until all requests are woken + * the struct fw_priv and won't release it until all requests are woken * and have gone through this same path. */ static void fw_abort_batch_reqs(struct firmware *fw) { - struct firmware_buf *buf; + struct fw_priv *fw_priv; /* Loaded directly? */ if (!fw || !fw->priv) return; - buf = fw->priv; - if (!fw_state_is_aborted(&buf->fw_st)) - fw_state_aborted(&buf->fw_st); + fw_priv = fw->priv; + if (!fw_state_is_aborted(&fw_priv->fw_st)) + fw_state_aborted(&fw_priv->fw_st); } /* called from request_firmware() and request_firmware_work_func() */ @@ -1245,7 +1247,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, opt_flags); } } else - ret = assign_firmware_buf(fw, device, opt_flags); + ret = assign_fw(fw, device, opt_flags); out: if (ret < 0) { @@ -1482,13 +1484,13 @@ static int cache_firmware(const char *fw_name) return ret; } -static struct firmware_buf *fw_lookup_buf(const char *fw_name) +static struct fw_priv *lookup_fw_priv(const char *fw_name) { - struct firmware_buf *tmp; + struct fw_priv *tmp; struct firmware_cache *fwc = &fw_cache; spin_lock(&fwc->lock); - tmp = __fw_lookup_buf(fw_name); + tmp = __lookup_fw_priv(fw_name); spin_unlock(&fwc->lock); return tmp; @@ -1507,7 +1509,7 @@ static struct firmware_buf *fw_lookup_buf(const char *fw_name) */ static int uncache_firmware(const char *fw_name) { - struct firmware_buf *buf; + struct fw_priv *fw_priv; struct firmware fw; pr_debug("%s: %s\n", __func__, fw_name); @@ -1515,9 +1517,9 @@ static int uncache_firmware(const char *fw_name) if (fw_get_builtin_firmware(&fw, fw_name, NULL, 0)) return 0; - buf = fw_lookup_buf(fw_name); - if (buf) { - fw_free_buf(buf); + fw_priv = lookup_fw_priv(fw_name); + if (fw_priv) { + free_fw_priv(fw_priv); return 0; } -- cgit v1.2.3 From 31034f22fcee763b9a76d5fc1b51f3fc2bd28565 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:49 -0800 Subject: firmware: rename struct fw_priv->fw_id to fw_name This makes it clear exactly what the field is for. With fw_id it was not clear to a reader if this was some sort of private concoction of some sort. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3f95a9e55b4b..3a79231c2cf5 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -234,7 +234,7 @@ struct fw_priv { int page_array_size; struct list_head pending_list; #endif - const char *fw_id; + const char *fw_name; }; struct fw_cache_entry { @@ -270,8 +270,8 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name, if (!fw_priv) return NULL; - fw_priv->fw_id = kstrdup_const(fw_name, GFP_ATOMIC); - if (!fw_priv->fw_id) { + fw_priv->fw_name = kstrdup_const(fw_name, GFP_ATOMIC); + if (!fw_priv->fw_name) { kfree(fw_priv); return NULL; } @@ -296,7 +296,7 @@ static struct fw_priv *__lookup_fw_priv(const char *fw_name) struct firmware_cache *fwc = &fw_cache; list_for_each_entry(tmp, &fwc->head, list) - if (!strcmp(tmp->fw_id, fw_name)) + if (!strcmp(tmp->fw_name, fw_name)) return tmp; return NULL; } @@ -335,7 +335,7 @@ static void __free_fw_priv(struct kref *ref) struct firmware_cache *fwc = fw_priv->fwc; pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n", - __func__, fw_priv->fw_id, fw_priv, fw_priv->data, + __func__, fw_priv->fw_name, fw_priv, fw_priv->data, (unsigned int)fw_priv->size); list_del(&fw_priv->list); @@ -352,7 +352,7 @@ static void __free_fw_priv(struct kref *ref) #endif if (!fw_priv->allocated_size) vfree(fw_priv->data); - kfree_const(fw_priv->fw_id); + kfree_const(fw_priv->fw_name); kfree(fw_priv); } @@ -408,7 +408,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) continue; len = snprintf(path, PATH_MAX, "%s/%s", - fw_path[i], fw_priv->fw_id); + fw_path[i], fw_priv->fw_name); if (len >= PATH_MAX) { rc = -ENAMETOOLONG; break; @@ -426,7 +426,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) path, rc); continue; } - dev_dbg(device, "direct-loading %s\n", fw_priv->fw_id); + dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name); fw_priv->size = size; fw_state_done(&fw_priv->fw_st); break; @@ -458,7 +458,7 @@ static void fw_set_page_data(struct fw_priv *fw_priv, struct firmware *fw) fw->data = fw_priv->data; pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n", - __func__, fw_priv->fw_id, fw_priv, fw_priv->data, + __func__, fw_priv->fw_name, fw_priv, fw_priv->data, (unsigned int)fw_priv->size); } @@ -544,7 +544,7 @@ static int assign_fw(struct firmware *fw, struct device *device, /* don't cache firmware handled without uevent */ if (device && (opt_flags & FW_OPT_UEVENT) && !(opt_flags & FW_OPT_NOCACHE)) - fw_add_devm_name(device, fw_priv->fw_id); + fw_add_devm_name(device, fw_priv->fw_name); /* * After caching firmware image is started, let it piggyback @@ -552,7 +552,7 @@ static int assign_fw(struct firmware *fw, struct device *device, */ if (!(opt_flags & FW_OPT_NOCACHE) && fw_priv->fwc->state == FW_LOADER_START_CACHE) { - if (fw_cache_piggyback_on_request(fw_priv->fw_id)) + if (fw_cache_piggyback_on_request(fw_priv->fw_name)) kref_get(&fw_priv->ref); } @@ -659,7 +659,7 @@ static void fw_dev_release(struct device *dev) static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) { - if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_id)) + if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name)) return -ENOMEM; if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) return -ENOMEM; @@ -1056,7 +1056,7 @@ static int _request_firmware_load(struct fw_sysfs *fw_sysfs, if (opt_flags & FW_OPT_UEVENT) { fw_priv->need_uevent = true; dev_set_uevent_suppress(f_dev, false); - dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_id); + dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name); kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); } else { timeout = MAX_JIFFY_OFFSET; -- cgit v1.2.3 From be8d462f3e5713801a1f1bf3cccef30ff2a40423 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:50 -0800 Subject: firmware: move core data structures to the top of file Move main core data structures used internally for firmware to the top of the file. This will allow us to use them earlier later in helpers as we extend their use. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 190 +++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 95 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3a79231c2cf5..4041548d1a81 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -41,6 +41,101 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_LICENSE("GPL"); +enum fw_status { + FW_STATUS_UNKNOWN, + FW_STATUS_LOADING, + FW_STATUS_DONE, + FW_STATUS_ABORTED, +}; + +/* + * Concurrent request_firmware() for the same firmware need to be + * serialized. struct fw_state is simple state machine which hold the + * state of the firmware loading. + */ +struct fw_state { + struct completion completion; + enum fw_status status; +}; + +/* firmware behavior options */ +#define FW_OPT_UEVENT (1U << 0) +#define FW_OPT_NOWAIT (1U << 1) +#ifdef CONFIG_FW_LOADER_USER_HELPER +#define FW_OPT_USERHELPER (1U << 2) +#else +#define FW_OPT_USERHELPER 0 +#endif +#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK +#define FW_OPT_FALLBACK FW_OPT_USERHELPER +#else +#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 */ + spinlock_t lock; + struct list_head head; + int state; + +#ifdef CONFIG_PM_SLEEP + /* + * Names of firmware images which have been cached successfully + * will be added into the below list so that device uncache + * helper can trace which firmware images have been cached + * before. + */ + spinlock_t name_lock; + struct list_head fw_names; + + struct delayed_work work; + + struct notifier_block pm_notify; +#endif +}; + +struct fw_priv { + struct kref ref; + struct list_head list; + struct firmware_cache *fwc; + struct fw_state fw_st; + void *data; + size_t size; + size_t allocated_size; +#ifdef CONFIG_FW_LOADER_USER_HELPER + bool is_paged_buf; + bool need_uevent; + struct page **pages; + int nr_pages; + int page_array_size; + struct list_head pending_list; +#endif + const char *fw_name; +}; + +struct fw_cache_entry { + struct list_head list; + const char *name; +}; + +struct fw_name_devm { + unsigned long magic; + const char *name; +}; + +#define to_fw_priv(d) container_of(d, struct fw_priv, ref) + +#define FW_LOADER_NO_CACHE 0 +#define FW_LOADER_START_CACHE 1 + +/* fw_lock could be moved to 'struct fw_sysfs' but since it is just + * guarding for corner cases a global lock should be OK */ +static DEFINE_MUTEX(fw_lock); + +static struct firmware_cache fw_cache; + /* Builtin firmware support */ #ifdef CONFIG_FW_LOADER @@ -93,13 +188,6 @@ static inline bool fw_is_builtin_firmware(const struct firmware *fw) } #endif -enum fw_status { - FW_STATUS_UNKNOWN, - FW_STATUS_LOADING, - FW_STATUS_DONE, - FW_STATUS_ABORTED, -}; - static int loading_timeout = 60; /* In seconds */ static inline long firmware_loading_timeout(void) @@ -107,16 +195,6 @@ static inline long firmware_loading_timeout(void) return loading_timeout > 0 ? loading_timeout * HZ : MAX_JIFFY_OFFSET; } -/* - * Concurrent request_firmware() for the same firmware need to be - * serialized. struct fw_state is simple state machine which hold the - * state of the firmware loading. - */ -struct fw_state { - struct completion completion; - enum fw_status status; -}; - static void fw_state_init(struct fw_state *fw_st) { init_completion(&fw_st->completion); @@ -180,86 +258,8 @@ static int __fw_state_check(struct fw_state *fw_st, enum fw_status status) #endif /* CONFIG_FW_LOADER_USER_HELPER */ -/* firmware behavior options */ -#define FW_OPT_UEVENT (1U << 0) -#define FW_OPT_NOWAIT (1U << 1) -#ifdef CONFIG_FW_LOADER_USER_HELPER -#define FW_OPT_USERHELPER (1U << 2) -#else -#define FW_OPT_USERHELPER 0 -#endif -#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK -#define FW_OPT_FALLBACK FW_OPT_USERHELPER -#else -#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 */ - spinlock_t lock; - struct list_head head; - int state; - -#ifdef CONFIG_PM_SLEEP - /* - * Names of firmware images which have been cached successfully - * will be added into the below list so that device uncache - * helper can trace which firmware images have been cached - * before. - */ - spinlock_t name_lock; - struct list_head fw_names; - - struct delayed_work work; - - struct notifier_block pm_notify; -#endif -}; - -struct fw_priv { - struct kref ref; - struct list_head list; - struct firmware_cache *fwc; - struct fw_state fw_st; - void *data; - size_t size; - size_t allocated_size; -#ifdef CONFIG_FW_LOADER_USER_HELPER - bool is_paged_buf; - bool need_uevent; - struct page **pages; - int nr_pages; - int page_array_size; - struct list_head pending_list; -#endif - const char *fw_name; -}; - -struct fw_cache_entry { - struct list_head list; - const char *name; -}; - -struct fw_name_devm { - unsigned long magic; - const char *name; -}; - -#define to_fw_priv(d) container_of(d, struct fw_priv, ref) - -#define FW_LOADER_NO_CACHE 0 -#define FW_LOADER_START_CACHE 1 - static int fw_cache_piggyback_on_request(const char *name); -/* fw_lock could be moved to 'struct fw_sysfs' but since it is just - * guarding for corner cases a global lock should be OK */ -static DEFINE_MUTEX(fw_lock); - -static struct firmware_cache fw_cache; - static struct fw_priv *__allocate_fw_priv(const char *fw_name, struct firmware_cache *fwc, void *dbuf, size_t size) -- cgit v1.2.3 From 2465032435f3e32b5843f7b4704405d9a6e4d699 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:51 -0800 Subject: firmware: remove duplicate fw_state_aborted() The macro is defined twice without need. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4041548d1a81..485bb18cee1d 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -247,8 +247,6 @@ static int __fw_state_check(struct fw_state *fw_st, enum fw_status status) #ifdef CONFIG_FW_LOADER_USER_HELPER -#define fw_state_aborted(fw_st) \ - __fw_state_set(fw_st, FW_STATUS_ABORTED) #define fw_state_is_done(fw_st) \ __fw_state_check(fw_st, FW_STATUS_DONE) #define fw_state_is_loading(fw_st) \ -- cgit v1.2.3 From c73bf7f487983087238f086a15780c1227adce3b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:52 -0800 Subject: firmware: remove unused __fw_state_is_done() After commit e44565f62a ("firmware: fix batched requests - wake all waiters") where we moved away from swait to old wait with a completion we also stopped using __fw_state_is_done(). Since this is longer used kill it. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 485bb18cee1d..0d35ed72c6c6 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -201,11 +201,6 @@ static void fw_state_init(struct fw_state *fw_st) fw_st->status = FW_STATUS_UNKNOWN; } -static inline bool __fw_state_is_done(enum fw_status status) -{ - return status == FW_STATUS_DONE || status == FW_STATUS_ABORTED; -} - static int __fw_state_wait_common(struct fw_state *fw_st, long timeout) { long ret; -- cgit v1.2.3 From f1b9cf39af2e56da6e432d1fec3acb6c974c2f8e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:53 -0800 Subject: firmware: use static inlines for state machine checking This will allow us to do proper typechecking on users both of values passed and return types expected. While at it, change the parameter passed to be the struct fw_priv, so we can move around the state machine variable as we see fit with these helpers. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 107 +++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 39 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 0d35ed72c6c6..3b506d375897 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -195,14 +195,17 @@ static inline long firmware_loading_timeout(void) return loading_timeout > 0 ? loading_timeout * HZ : MAX_JIFFY_OFFSET; } -static void fw_state_init(struct fw_state *fw_st) +static void fw_state_init(struct fw_priv *fw_priv) { + struct fw_state *fw_st = &fw_priv->fw_st; + init_completion(&fw_st->completion); fw_st->status = FW_STATUS_UNKNOWN; } -static int __fw_state_wait_common(struct fw_state *fw_st, long timeout) +static int __fw_state_wait_common(struct fw_priv *fw_priv, long timeout) { + struct fw_state *fw_st = &fw_priv->fw_st; long ret; ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout); @@ -214,40 +217,66 @@ static int __fw_state_wait_common(struct fw_state *fw_st, long timeout) return ret < 0 ? ret : 0; } -static void __fw_state_set(struct fw_state *fw_st, +static void __fw_state_set(struct fw_priv *fw_priv, enum fw_status status) { + struct fw_state *fw_st = &fw_priv->fw_st; + WRITE_ONCE(fw_st->status, status); if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) complete_all(&fw_st->completion); } -#define fw_state_start(fw_st) \ - __fw_state_set(fw_st, FW_STATUS_LOADING) -#define fw_state_done(fw_st) \ - __fw_state_set(fw_st, FW_STATUS_DONE) -#define fw_state_aborted(fw_st) \ - __fw_state_set(fw_st, FW_STATUS_ABORTED) -#define fw_state_wait(fw_st) \ - __fw_state_wait_common(fw_st, MAX_SCHEDULE_TIMEOUT) +static inline void fw_state_start(struct fw_priv *fw_priv) +{ + __fw_state_set(fw_priv, FW_STATUS_LOADING); +} + +static inline void fw_state_done(struct fw_priv *fw_priv) +{ + __fw_state_set(fw_priv, FW_STATUS_DONE); +} + +static inline void fw_state_aborted(struct fw_priv *fw_priv) +{ + __fw_state_set(fw_priv, FW_STATUS_ABORTED); +} + +static inline int fw_state_wait(struct fw_priv *fw_priv) +{ + return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT); +} -static int __fw_state_check(struct fw_state *fw_st, enum fw_status status) +static bool __fw_state_check(struct fw_priv *fw_priv, + enum fw_status status) { + struct fw_state *fw_st = &fw_priv->fw_st; + return fw_st->status == status; } -#define fw_state_is_aborted(fw_st) \ - __fw_state_check(fw_st, FW_STATUS_ABORTED) +static inline bool fw_state_is_aborted(struct fw_priv *fw_priv) +{ + return __fw_state_check(fw_priv, FW_STATUS_ABORTED); +} #ifdef CONFIG_FW_LOADER_USER_HELPER -#define fw_state_is_done(fw_st) \ - __fw_state_check(fw_st, FW_STATUS_DONE) -#define fw_state_is_loading(fw_st) \ - __fw_state_check(fw_st, FW_STATUS_LOADING) -#define fw_state_wait_timeout(fw_st, timeout) \ - __fw_state_wait_common(fw_st, timeout) +static inline bool fw_state_is_done(struct fw_priv *fw_priv) +{ + return __fw_state_check(fw_priv, FW_STATUS_DONE); +} + +static inline bool fw_state_is_loading(struct fw_priv *fw_priv) +{ + return __fw_state_check(fw_priv, FW_STATUS_LOADING); +} + +static inline int fw_state_wait_timeout(struct fw_priv *fw_priv, long timeout) +{ + return __fw_state_wait_common(fw_priv, timeout); +} #endif /* CONFIG_FW_LOADER_USER_HELPER */ @@ -273,7 +302,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name, fw_priv->fwc = fwc; fw_priv->data = dbuf; fw_priv->allocated_size = size; - fw_state_init(&fw_priv->fw_st); + fw_state_init(fw_priv); #ifdef CONFIG_FW_LOADER_USER_HELPER INIT_LIST_HEAD(&fw_priv->pending_list); #endif @@ -421,7 +450,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv) } dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name); fw_priv->size = size; - fw_state_done(&fw_priv->fw_st); + fw_state_done(fw_priv); break; } __putname(path); @@ -522,7 +551,7 @@ static int assign_fw(struct firmware *fw, struct device *device, struct fw_priv *fw_priv = fw->priv; mutex_lock(&fw_lock); - if (!fw_priv->size || fw_state_is_aborted(&fw_priv->fw_st)) { + if (!fw_priv->size || fw_state_is_aborted(fw_priv)) { mutex_unlock(&fw_lock); return -ENOENT; } @@ -577,11 +606,11 @@ static void __fw_load_abort(struct fw_priv *fw_priv) * There is a small window in which user can write to 'loading' * between loading done and disappearance of 'loading' */ - if (fw_state_is_done(&fw_priv->fw_st)) + if (fw_state_is_done(fw_priv)) return; list_del_init(&fw_priv->pending_list); - fw_state_aborted(&fw_priv->fw_st); + fw_state_aborted(fw_priv); } static void fw_load_abort(struct fw_sysfs *fw_sysfs) @@ -699,7 +728,7 @@ static ssize_t firmware_loading_show(struct device *dev, mutex_lock(&fw_lock); if (fw_sysfs->fw_priv) - loading = fw_state_is_loading(&fw_sysfs->fw_priv->fw_st); + loading = fw_state_is_loading(fw_sysfs->fw_priv); mutex_unlock(&fw_lock); return sprintf(buf, "%d\n", loading); @@ -749,24 +778,24 @@ static ssize_t firmware_loading_store(struct device *dev, mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; - if (fw_state_is_aborted(&fw_priv->fw_st)) + if (fw_state_is_aborted(fw_priv)) goto out; switch (loading) { case 1: /* discarding any previous partial load */ - if (!fw_state_is_done(&fw_priv->fw_st)) { + if (!fw_state_is_done(fw_priv)) { for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); vfree(fw_priv->pages); fw_priv->pages = NULL; fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; - fw_state_start(&fw_priv->fw_st); + fw_state_start(fw_priv); } break; case 0: - if (fw_state_is_loading(&fw_priv->fw_st)) { + if (fw_state_is_loading(fw_priv)) { int rc; /* @@ -790,10 +819,10 @@ static ssize_t firmware_loading_store(struct device *dev, */ list_del_init(&fw_priv->pending_list); if (rc) { - fw_state_aborted(&fw_priv->fw_st); + fw_state_aborted(fw_priv); written = rc; } else { - fw_state_done(&fw_priv->fw_st); + fw_state_done(fw_priv); } break; } @@ -855,7 +884,7 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; - if (!fw_priv || fw_state_is_done(&fw_priv->fw_st)) { + if (!fw_priv || fw_state_is_done(fw_priv)) { ret_count = -ENODEV; goto out; } @@ -942,7 +971,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; - if (!fw_priv || fw_state_is_done(&fw_priv->fw_st)) { + if (!fw_priv || fw_state_is_done(fw_priv)) { retval = -ENODEV; goto out; } @@ -1055,14 +1084,14 @@ static int _request_firmware_load(struct fw_sysfs *fw_sysfs, timeout = MAX_JIFFY_OFFSET; } - retval = fw_state_wait_timeout(&fw_priv->fw_st, timeout); + retval = fw_state_wait_timeout(fw_priv, timeout); if (retval < 0) { mutex_lock(&fw_lock); fw_load_abort(fw_sysfs); mutex_unlock(&fw_lock); } - if (fw_state_is_aborted(&fw_priv->fw_st)) { + if (fw_state_is_aborted(fw_priv)) { if (retval == -ERESTARTSYS) retval = -EINTR; else @@ -1173,7 +1202,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, firmware->priv = fw_priv; if (ret > 0) { - ret = fw_state_wait(&fw_priv->fw_st); + ret = fw_state_wait(fw_priv); if (!ret) { fw_set_page_data(fw_priv, firmware); return 0; /* assigned */ @@ -1203,8 +1232,8 @@ static void fw_abort_batch_reqs(struct firmware *fw) return; fw_priv = fw->priv; - if (!fw_state_is_aborted(&fw_priv->fw_st)) - fw_state_aborted(&fw_priv->fw_st); + if (!fw_state_is_aborted(fw_priv)) + fw_state_aborted(fw_priv); } /* called from request_firmware() and request_firmware_work_func() */ -- cgit v1.2.3 From 33a5b18de2f5cac6de9b86e137cce2bbf02560d5 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:54 -0800 Subject: firmware: rename sysfs state checks with sysfs prefix Doing this makes it clearer the states are only to be used in the context of the sysfs fallback loading interface. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 3b506d375897..dcc1281789e4 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -263,17 +263,17 @@ static inline bool fw_state_is_aborted(struct fw_priv *fw_priv) #ifdef CONFIG_FW_LOADER_USER_HELPER -static inline bool fw_state_is_done(struct fw_priv *fw_priv) +static inline bool fw_sysfs_done(struct fw_priv *fw_priv) { return __fw_state_check(fw_priv, FW_STATUS_DONE); } -static inline bool fw_state_is_loading(struct fw_priv *fw_priv) +static inline bool fw_sysfs_loading(struct fw_priv *fw_priv) { return __fw_state_check(fw_priv, FW_STATUS_LOADING); } -static inline int fw_state_wait_timeout(struct fw_priv *fw_priv, long timeout) +static inline int fw_sysfs_wait_timeout(struct fw_priv *fw_priv, long timeout) { return __fw_state_wait_common(fw_priv, timeout); } @@ -606,7 +606,7 @@ static void __fw_load_abort(struct fw_priv *fw_priv) * There is a small window in which user can write to 'loading' * between loading done and disappearance of 'loading' */ - if (fw_state_is_done(fw_priv)) + if (fw_sysfs_done(fw_priv)) return; list_del_init(&fw_priv->pending_list); @@ -728,7 +728,7 @@ static ssize_t firmware_loading_show(struct device *dev, mutex_lock(&fw_lock); if (fw_sysfs->fw_priv) - loading = fw_state_is_loading(fw_sysfs->fw_priv); + loading = fw_sysfs_loading(fw_sysfs->fw_priv); mutex_unlock(&fw_lock); return sprintf(buf, "%d\n", loading); @@ -784,7 +784,7 @@ static ssize_t firmware_loading_store(struct device *dev, switch (loading) { case 1: /* discarding any previous partial load */ - if (!fw_state_is_done(fw_priv)) { + if (!fw_sysfs_done(fw_priv)) { for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); vfree(fw_priv->pages); @@ -795,7 +795,7 @@ static ssize_t firmware_loading_store(struct device *dev, } break; case 0: - if (fw_state_is_loading(fw_priv)) { + if (fw_sysfs_loading(fw_priv)) { int rc; /* @@ -884,7 +884,7 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; - if (!fw_priv || fw_state_is_done(fw_priv)) { + if (!fw_priv || fw_sysfs_done(fw_priv)) { ret_count = -ENODEV; goto out; } @@ -971,7 +971,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, mutex_lock(&fw_lock); fw_priv = fw_sysfs->fw_priv; - if (!fw_priv || fw_state_is_done(fw_priv)) { + if (!fw_priv || fw_sysfs_done(fw_priv)) { retval = -ENODEV; goto out; } @@ -1084,7 +1084,7 @@ static int _request_firmware_load(struct fw_sysfs *fw_sysfs, timeout = MAX_JIFFY_OFFSET; } - retval = fw_state_wait_timeout(fw_priv, timeout); + retval = fw_sysfs_wait_timeout(fw_priv, timeout); if (retval < 0) { mutex_lock(&fw_lock); fw_load_abort(fw_sysfs); -- cgit v1.2.3 From 942e743b73d0effc65895e4361b04534e24106cb Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:55 -0800 Subject: firmware: use static inline for to_fw_priv() This lets us type check the callers. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index dcc1281789e4..4f64410fe7e6 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -125,7 +125,10 @@ struct fw_name_devm { const char *name; }; -#define to_fw_priv(d) container_of(d, struct fw_priv, ref) +static inline struct fw_priv *to_fw_priv(struct kref *ref) +{ + return container_of(ref, struct fw_priv, ref); +} #define FW_LOADER_NO_CACHE 0 #define FW_LOADER_START_CACHE 1 -- cgit v1.2.3 From 5711ae6d3054e13a95858da6df6d142bec90d832 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:56 -0800 Subject: firmware: add helper to copy built-in data to pre-alloc buffer This makes it clearer that the parameters passed are only used for the preallocated buffer option, ie, when a caller uses: request_firmware_into_buf() Otherwise this code won't run. We flip the logic just so the actual prellocated buf code is not indented. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4f64410fe7e6..aba3f2cbe2f4 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -146,6 +146,14 @@ static struct firmware_cache fw_cache; extern struct builtin_fw __start_builtin_fw[]; extern struct builtin_fw __end_builtin_fw[]; +static void fw_copy_to_prealloc_buf(struct firmware *fw, + void *buf, size_t size) +{ + if (!buf || size < fw->size) + return; + memcpy(buf, fw->data, fw->size); +} + static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, void *buf, size_t size) { @@ -155,9 +163,8 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, if (strcmp(name, b_fw->name) == 0) { fw->size = b_fw->size; fw->data = b_fw->data; + fw_copy_to_prealloc_buf(fw, buf, size); - if (buf && fw->size <= size) - memcpy(buf, fw->data, fw->size); return true; } } -- cgit v1.2.3 From 25d3913181b3e397549cb6584d7ab1a37709d104 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:57 -0800 Subject: firmware: provide helper for FW_OPT_USERHELPER The macro FW_OPT_USERHELPER is only currently defined when CONFIG_FW_LOADER_USER_HELPER is set. This is handled via an ifdef around CONFIG_FW_LOADER_USER_HELPER. This makes reading and understanding use FW_OPT_USERHELPER a bit convoluted. Instead wrap the functionality implemented behind CONFIG_FW_LOADER_USER_HELPER as we typically do in the kernel. Now when CONFIG_FW_LOADER_USER_HELPER is *not set*, then simply the helper fw_sysfs_fallback() will not do anything. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index aba3f2cbe2f4..316991429032 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -61,11 +61,7 @@ struct fw_state { /* firmware behavior options */ #define FW_OPT_UEVENT (1U << 0) #define FW_OPT_NOWAIT (1U << 1) -#ifdef CONFIG_FW_LOADER_USER_HELPER #define FW_OPT_USERHELPER (1U << 2) -#else -#define FW_OPT_USERHELPER 0 -#endif #ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK #define FW_OPT_FALLBACK FW_OPT_USERHELPER #else @@ -1158,12 +1154,25 @@ out_unlock: return ret; } +static int fw_sysfs_fallback(struct firmware *fw, const char *name, + struct device *device, + unsigned int opt_flags, + int ret) +{ + if (!(opt_flags & FW_OPT_USERHELPER)) + return ret; + + dev_warn(device, "Falling back to user helper\n"); + return fw_load_from_user_helper(fw, name, device, opt_flags); +} #else /* CONFIG_FW_LOADER_USER_HELPER */ -static inline int -fw_load_from_user_helper(struct firmware *firmware, const char *name, - struct device *device, unsigned int opt_flags) +static int fw_sysfs_fallback(struct firmware *fw, const char *name, + struct device *device, + unsigned int opt_flags, + int ret) { - return -ENOENT; + /* Keep carrying over the same error */ + return ret; } static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { } @@ -1273,11 +1282,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, dev_warn(device, "Direct firmware load for %s failed with error %d\n", name, ret); - if (opt_flags & FW_OPT_USERHELPER) { - dev_warn(device, "Falling back to user helper\n"); - ret = fw_load_from_user_helper(fw, name, device, - opt_flags); - } + ret = fw_sysfs_fallback(fw, name, device, opt_flags, ret); } else ret = assign_fw(fw, device, opt_flags); -- cgit v1.2.3 From 3f72271233943c76a1686b3de4c5509e23993770 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 20 Nov 2017 10:23:58 -0800 Subject: firmware: replace #ifdef over FW_OPT_FALLBACK with function checks Its not easy to follow the logic behind making FW_OPT_FALLBACK map to an existing flag only if a kernel configuration option was set. Its much easier to retpresent what was intended with function helpers which make it clear that if CONFIG_FW_LOADER_USER_HELPER_FALLBACK is set we force running the fallback mechanism unless a caller specifically never wants to run it, such as request_firmware_direct(). Prior and after this change we upkeep the tradition: CONFIG_FW_LOADER_USER_HELPER_FALLBACK request_firmware() force fallback request_firmware_into_buf() force fallback request_firmware_nowait() force fallback request_firmware_direct() always ignore fallback !CONFIG_FW_LOADER_USER_HELPER_FALLBACK request_firmware() ignore fallback request_firmware_into_buf() ignore fallback request_firmware_nowait() depends on uevent flag request_firmware_direct() always ignore fallback Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 316991429032..43b97a8137f7 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -62,13 +62,9 @@ struct fw_state { #define FW_OPT_UEVENT (1U << 0) #define FW_OPT_NOWAIT (1U << 1) #define FW_OPT_USERHELPER (1U << 2) -#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK -#define FW_OPT_FALLBACK FW_OPT_USERHELPER -#else -#define FW_OPT_FALLBACK 0 -#endif #define FW_OPT_NO_WARN (1U << 3) #define FW_OPT_NOCACHE (1U << 4) +#define FW_OPT_NOFALLBACK (1U << 5) struct firmware_cache { /* firmware_buf instance will be added into the below list */ @@ -1154,12 +1150,34 @@ out_unlock: return ret; } +#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK +static bool fw_force_sysfs_fallback(unsigned int opt_flags) +{ + return true; +} +#else +static bool fw_force_sysfs_fallback(unsigned int opt_flags) +{ + if (!(opt_flags & FW_OPT_USERHELPER)) + return false; + return true; +} +#endif + +static bool fw_run_sysfs_fallback(unsigned int opt_flags) +{ + if ((opt_flags & FW_OPT_NOFALLBACK)) + return false; + + return fw_force_sysfs_fallback(opt_flags); +} + static int fw_sysfs_fallback(struct firmware *fw, const char *name, struct device *device, unsigned int opt_flags, int ret) { - if (!(opt_flags & FW_OPT_USERHELPER)) + if (!fw_run_sysfs_fallback(opt_flags)) return ret; dev_warn(device, "Falling back to user helper\n"); @@ -1326,7 +1344,7 @@ request_firmware(const struct firmware **firmware_p, const char *name, /* Need to pin this module until return */ __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, NULL, 0, - FW_OPT_UEVENT | FW_OPT_FALLBACK); + FW_OPT_UEVENT); module_put(THIS_MODULE); return ret; } @@ -1350,7 +1368,8 @@ int request_firmware_direct(const struct firmware **firmware_p, __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, NULL, 0, - FW_OPT_UEVENT | FW_OPT_NO_WARN); + FW_OPT_UEVENT | FW_OPT_NO_WARN | + FW_OPT_NOFALLBACK); module_put(THIS_MODULE); return ret; } @@ -1379,8 +1398,7 @@ request_firmware_into_buf(const struct firmware **firmware_p, const char *name, __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, buf, size, - FW_OPT_UEVENT | FW_OPT_FALLBACK | - FW_OPT_NOCACHE); + FW_OPT_UEVENT | FW_OPT_NOCACHE); module_put(THIS_MODULE); return ret; } @@ -1472,7 +1490,7 @@ request_firmware_nowait( fw_work->device = device; fw_work->context = context; fw_work->cont = cont; - fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK | + fw_work->opt_flags = FW_OPT_NOWAIT | (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); if (!try_module_get(module)) { -- cgit v1.2.3 From 989d42e85dc2f6823f39b8e9d080fd04bae0645d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 7 Nov 2017 17:30:07 +0100 Subject: driver core: add SPDX identifiers to all driver core files It's good to have SPDX identifiers in all files to make it easier to audit the kernel tree for correct licenses. Update the driver core files files with the correct SPDX license identifier based on the license text in the file itself. The SPDX identifier is a legally binding shorthand, which can be used instead of the full boiler plate text. This work is based on a script and data from Thomas Gleixner, Philippe Ombredanne, and Kate Stewart. Cc: Johannes Berg Cc: "Luis R. Rodriguez" Cc: William Breathitt Gray Cc: Thomas Gleixner Cc: Kate Stewart Cc: Philippe Ombredanne Signed-off-by: Greg Kroah-Hartman --- drivers/base/attribute_container.c | 1 + drivers/base/bus.c | 1 + drivers/base/cacheinfo.c | 1 + drivers/base/class.c | 1 + drivers/base/component.c | 1 + drivers/base/container.c | 1 + drivers/base/core.c | 1 + drivers/base/cpu.c | 1 + drivers/base/dd.c | 1 + drivers/base/devcoredump.c | 1 + drivers/base/devres.c | 1 + drivers/base/dma-contiguous.c | 1 + drivers/base/dma-mapping.c | 1 + drivers/base/driver.c | 1 + drivers/base/firmware.c | 1 + drivers/base/firmware_class.c | 1 + drivers/base/hypervisor.c | 1 + drivers/base/init.c | 1 + drivers/base/isa.c | 1 + drivers/base/map.c | 1 + drivers/base/module.c | 1 + drivers/base/pinctrl.c | 1 + drivers/base/platform-msi.c | 1 + drivers/base/platform.c | 1 + drivers/base/property.c | 1 + drivers/base/soc.c | 1 + drivers/base/syscore.c | 1 + drivers/base/test/test_async_driver_probe.c | 1 + drivers/base/topology.c | 1 + drivers/base/transport_class.c | 1 + include/linux/device.h | 1 + 31 files changed, 31 insertions(+) (limited to 'drivers/base/firmware_class.c') diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 95e3ef82f3b7..218b9deb4f0b 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * attribute_container.c - implementation of a simple container for classes * diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 22a64fd3309b..46ddb96b9179 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bus.c - bus driver management * diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index eb3af2739537..e321a7e66a1d 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * cacheinfo support - processor cache information via sysfs * diff --git a/drivers/base/class.c b/drivers/base/class.c index 52eb8e644acd..61220ea83f8e 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * class.c - basic device class management * diff --git a/drivers/base/component.c b/drivers/base/component.c index 89b032f2ffd2..c96ed8068719 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Componentized device handling. * diff --git a/drivers/base/container.c b/drivers/base/container.c index ecbfbe2e908f..ddc68a1e10af 100644 --- a/drivers/base/container.c +++ b/drivers/base/container.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * System bus type for containers. * diff --git a/drivers/base/core.c b/drivers/base/core.c index 110230d86527..aa0593f1c2b6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/base/core.c - core driver model code (device registration, etc) * diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 58a9b608d821..31d0ee53613b 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * CPU subsystem support */ diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2c964f56dafe..47ac37838399 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/base/dd.c - The core device/driver interactions. * diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 7be310f7db73..3133684a8754 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is provided under the GPLv2 license. * diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 71d577025285..1b7a9a8cbd6a 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/base/devres.c - device resource management * diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index ea9726e71468..7c954100d503 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Contiguous Memory Allocator for DMA mapping framework * Copyright (c) 2010-2011 by Samsung Electronics. diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index e584eddef0a7..c7e7806a657f 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/base/dma-mapping.c - arch-independent dma-mapping routines * diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 4eabfe28d2b3..6a93c7522dbe 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * driver.c - centralized device driver management * diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c index 113815556809..0ef2a36de65e 100644 --- a/drivers/base/firmware.c +++ b/drivers/base/firmware.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * firmware.c - firmware subsystem hoohaw. * diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 43b97a8137f7..7dd36ace6152 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * firmware_class.c - Multi purpose firmware loading support * diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c index 4f8b741f4615..8dbd98c7ed55 100644 --- a/drivers/base/hypervisor.c +++ b/drivers/base/hypervisor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * hypervisor.c - /sys/hypervisor subsystem. * diff --git a/drivers/base/init.c b/drivers/base/init.c index 48c0e220acc0..0bf84b9e09b2 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs diff --git a/drivers/base/isa.c b/drivers/base/isa.c index cd6ccdcf9df0..61ab202aae43 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ISA bus. */ diff --git a/drivers/base/map.c b/drivers/base/map.c index c1d38234d725..07daaf6c2cd6 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/drivers/base/map.c * diff --git a/drivers/base/module.c b/drivers/base/module.c index 2a215780eda2..9e50e55c547a 100644 --- a/drivers/base/module.c +++ b/drivers/base/module.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * module.c - module sysfs fun for drivers * diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index eb929dd6ef1e..fec06a1a0e15 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver core interface to the pinctrl subsystem. * diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index e5473525e7b2..d7c56d5b06e0 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MSI framework for platform devices * diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c203fb90c1a0..be287c7f5a6a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * platform.c - platform 'pseudo' bus for legacy devices * diff --git a/drivers/base/property.c b/drivers/base/property.c index 851b1b6596a4..f64bf6bebf58 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * property.c - Unified device property interface. * diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 909dedae4c4e..b1e6e7ca46f0 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) ST-Ericsson SA 2011 * diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index 8d98a329f6ea..34f71a46b51c 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * syscore.c - Execution of system core operations. * diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c index a3355d66bc12..58b445ed8d8b 100644 --- a/drivers/base/test/test_async_driver_probe.c +++ b/drivers/base/test/test_async_driver_probe.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2014 Google, Inc. * diff --git a/drivers/base/topology.c b/drivers/base/topology.c index d936fcf9f1fb..5abc176a2966 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * driver/base/topology.c - Populate sysfs with cpu topology information * diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c index f6c453c3816e..750378341a43 100644 --- a/drivers/base/transport_class.c +++ b/drivers/base/transport_class.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * transport_class.c - implementation of generic transport classes * using attribute_containers diff --git a/include/linux/device.h b/include/linux/device.h index 9d32000725da..70d352f9083a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * device.h - generic, centralized driver model * -- cgit v1.2.3