mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
PM, libnvdimm: Add runtime firmware activation support
Abstract platform specific mechanics for nvdimm firmware activation behind a handful of generic ops. At the bus level ->activate_state() indicates the unified state (idle, busy, armed) of all DIMMs on the bus, and ->capability() indicates the system state expectations for activate. At the DIMM level ->activate_state() indicates the per-DIMM state, ->activate_result() indicates the outcome of the last activation attempt, and ->arm() attempts to transition the DIMM from 'idle' to 'armed'. A new hibernate_quiet_exec() facility is added to support firmware activation in an OS defined system quiesce state. It leverages the fact that the hibernate-freeze state wants to assert that a memory hibernation snapshot can be taken. This is in contrast to a platform firmware defined quiesce state that may forcefully quiet the memory controller independent of whether an individual device-driver properly supports hibernate-freeze. The libnvdimm sysfs interface is extended to support detection of a firmware activate capability. The mechanism supports enumeration and triggering of firmware activate, optionally in the hibernate_quiet_exec() context. [rafael: hibernate_quiet_exec() proposal] [vishal: fix up sparse warning, grammar in Documentation/] Cc: Pavel Machek <pavel@ucw.cz> Cc: Ira Weiny <ira.weiny@intel.com> Cc: Len Brown <len.brown@intel.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Dave Jiang <dave.jiang@intel.com> Cc: Vishal Verma <vishal.l.verma@intel.com> Reported-by: kernel test robot <lkp@intel.com> Co-developed-by: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Signed-off-by: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
This commit is contained in:
committed by
Vishal Verma
parent
5cf81ce189
commit
48001ea50d
@@ -795,6 +795,103 @@ int hibernate(void)
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* hibernate_quiet_exec - Execute a function with all devices frozen.
|
||||
* @func: Function to execute.
|
||||
* @data: Data pointer to pass to @func.
|
||||
*
|
||||
* Return the @func return value or an error code if it cannot be executed.
|
||||
*/
|
||||
int hibernate_quiet_exec(int (*func)(void *data), void *data)
|
||||
{
|
||||
int error, nr_calls = 0;
|
||||
|
||||
lock_system_sleep();
|
||||
|
||||
if (!hibernate_acquire()) {
|
||||
error = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
pm_prepare_console();
|
||||
|
||||
error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
|
||||
if (error) {
|
||||
nr_calls--;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
error = freeze_processes();
|
||||
if (error)
|
||||
goto exit;
|
||||
|
||||
lock_device_hotplug();
|
||||
|
||||
pm_suspend_clear_flags();
|
||||
|
||||
error = platform_begin(true);
|
||||
if (error)
|
||||
goto thaw;
|
||||
|
||||
error = freeze_kernel_threads();
|
||||
if (error)
|
||||
goto thaw;
|
||||
|
||||
error = dpm_prepare(PMSG_FREEZE);
|
||||
if (error)
|
||||
goto dpm_complete;
|
||||
|
||||
suspend_console();
|
||||
|
||||
error = dpm_suspend(PMSG_FREEZE);
|
||||
if (error)
|
||||
goto dpm_resume;
|
||||
|
||||
error = dpm_suspend_end(PMSG_FREEZE);
|
||||
if (error)
|
||||
goto dpm_resume;
|
||||
|
||||
error = platform_pre_snapshot(true);
|
||||
if (error)
|
||||
goto skip;
|
||||
|
||||
error = func(data);
|
||||
|
||||
skip:
|
||||
platform_finish(true);
|
||||
|
||||
dpm_resume_start(PMSG_THAW);
|
||||
|
||||
dpm_resume:
|
||||
dpm_resume(PMSG_THAW);
|
||||
|
||||
resume_console();
|
||||
|
||||
dpm_complete:
|
||||
dpm_complete(PMSG_THAW);
|
||||
|
||||
thaw_kernel_threads();
|
||||
|
||||
thaw:
|
||||
platform_end(true);
|
||||
|
||||
unlock_device_hotplug();
|
||||
|
||||
thaw_processes();
|
||||
|
||||
exit:
|
||||
__pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
|
||||
|
||||
pm_restore_console();
|
||||
|
||||
hibernate_release();
|
||||
|
||||
unlock:
|
||||
unlock_system_sleep();
|
||||
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hibernate_quiet_exec);
|
||||
|
||||
/**
|
||||
* software_resume - Resume from a saved hibernation image.
|
||||
|
Reference in New Issue
Block a user