From: Dave Gerlach <d-gerlach@xxxxxx> Introduce a ti_sci_prepare_system_suspend call to be used in the driver suspend handler to allow the system to identify the low power mode being entered and if necessary, send TISCI_MSG_PREPARE_SLEEP with information about the mode is being entered and the address for allocated memory for storing the context during Deep Sleep. We're using "pm_suspend_target_state" to map the kernel's target suspend state to SysFW low power mode. Make sure this is available only when CONFIG_SUSPEND is enabled. Signed-off-by: Dave Gerlach <d-gerlach@xxxxxx> Signed-off-by: Vibhore Vardhan <vibhore@xxxxxx> Signed-off-by: Georgi Vlaev <g-vlaev@xxxxxx> Tested-by: Roger Quadros <rogerq@xxxxxxxxxx> --- drivers/firmware/ti_sci.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 09bca1a15d74..681f2ebb3fe4 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -3568,9 +3568,46 @@ static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspendin info->is_suspending = is_suspending; } +static int ti_sci_prepare_system_suspend(struct ti_sci_info *info) +{ +#if IS_ENABLED(CONFIG_SUSPEND) + u8 mode; + + /* Map and validate the target Linux suspend state to TISCI LPM. */ + switch (pm_suspend_target_state) { + case PM_SUSPEND_MEM: + /* S2MEM is not supported by the firmware. */ + if (!(info->fw_caps & MSG_FLAG_CAPS_LPM_DEEP_SLEEP)) + return 0; + /* S2MEM can't continue if the LPM firmware is not loaded. */ + if (!info->lpm_firmware_loaded) + return -EINVAL; + mode = TISCI_MSG_VALUE_SLEEP_MODE_DEEP_SLEEP; + break; + default: + /* + * Do not fail if we don't have action to take for a + * specific suspend mode. + */ + return 0; + } + + return ti_sci_cmd_prepare_sleep(&info->handle, mode, + (u32)(info->ctx_mem_addr & 0xffffffff), + (u32)((u64)info->ctx_mem_addr >> 32), 0); +#else + return 0; +#endif +} + static int ti_sci_suspend(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); + int ret; + + ret = ti_sci_prepare_system_suspend(info); + if (ret) + return ret; /* * We must switch operation to polled mode now as drivers and the genpd * layer may make late TI SCI calls to change clock and device states -- 2.30.2