Re: [RFC PATCH 13/13] driver core: firmware loader: cache devicesfirmware during suspend/resume cycle
From: Borislav Petkov
Date: Thu Jul 26 2012 - 08:44:13 EST
On Wed, Jul 25, 2012 at 01:00:13AM +0800, Ming Lei wrote:
> This patch implements caching devices' firmware automatically
> during system syspend/resume cycle, so any device drivers can
> call request_firmware or request_firmware_nowait inside resume
> path to get the cached firmware if they have loaded firmwares
> successfully at least once before entering suspend.
>
> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
> ---
> drivers/base/firmware_class.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index 0918b26..59384e0 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -24,6 +24,7 @@
> #include <linux/list.h>
> #include <linux/async.h>
> #include <linux/pm.h>
> +#include <linux/suspend.h>
>
> #include "base.h"
>
> @@ -106,6 +107,8 @@ struct firmware_cache {
> wait_queue_head_t wait_queue;
> int cnt;
> struct delayed_work work;
> +
stray newline
> + struct notifier_block pm_notify;
variable names should be either all aligned or none at all but not
something in between.
> };
>
> struct firmware_buf {
> @@ -1202,6 +1205,31 @@ static void device_uncache_firmwares_delay(unsigned long delay)
> msecs_to_jiffies(delay));
> }
>
> +#ifdef CONFIG_PM
> +static int fw_pm_notify(struct notifier_block *notify_block,
> + unsigned long mode, void *unused)
> +{
> + switch (mode) {
> + case PM_HIBERNATION_PREPARE:
> + case PM_SUSPEND_PREPARE:
> + device_cache_firmwares();
> + break;
> +
> + case PM_POST_SUSPEND:
> + case PM_POST_HIBERNATION:
> + case PM_POST_RESTORE:
> + device_uncache_firmwares_delay(10 * MSEC_PER_SEC);
> + break;
> + }
> +
> + return 0;
> +}
> +#else
> +static int fw_pm_notify(struct notifier_block *notify_block,
> + unsigned long mode, void *unused)
> +{}
static inline int fw_pm...
> +#endif
> +
> static void __init fw_cache_init(void)
> {
> spin_lock_init(&fw_cache.lock);
> @@ -1214,6 +1242,9 @@ static void __init fw_cache_init(void)
> init_waitqueue_head(&fw_cache.wait_queue);
> INIT_DELAYED_WORK(&fw_cache.work,
> device_uncache_firmwares_work);
> + fw_cache.pm_notify.notifier_call = fw_pm_notify;
> +
> + register_pm_notifier(&fw_cache.pm_notify);
> }
>
> static int __init firmware_class_init(void)
> @@ -1224,6 +1255,7 @@ static int __init firmware_class_init(void)
>
> static void __exit firmware_class_exit(void)
> {
> + unregister_pm_notifier(&fw_cache.pm_notify);
> class_unregister(&firmware_class);
> }
Ok, that should be it.
Thanks.
--
Regards/Gruss,
Boris.
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
GM: Alberto Bozzo
Reg: Dornach, Landkreis Muenchen
HRB Nr. 43632 WEEE Registernr: 129 19551
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/