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: 07646d9c09
("firmware loader: cache devices firmware during suspend/resume cycle")
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
a67e503b67
Коммит
59b6d859ff
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче