On j7200, a reserved memory region is needed for TF-A to save its context during suspend to ram. In ti-sci suspend, check if the region was defined, if not return an error. Signed-off-by: Thomas Richard <thomas.richard@xxxxxxxxxxx> --- drivers/firmware/ti_sci.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index c26ec86a5ff2..deaca17322df 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -77,6 +77,8 @@ struct ti_sci_xfers_info { * simultaneously in the system * @max_msg_size: Maximum size of data per message that can be handled. * @restore_irqs: Set to true if allocated irqs shall be restored at resume + * @lpm_region: Set to true if a reserved memory region is needed for suspend to + * ram */ struct ti_sci_desc { u8 default_host_id; @@ -84,6 +86,7 @@ struct ti_sci_desc { int max_msgs; int max_msg_size; bool restore_irqs; + bool lpm_region; }; /** @@ -3359,6 +3362,32 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, return NOTIFY_BAD; } +static bool ti_sci_check_lpm_region(void) +{ + struct device_node *parent, *node; + + parent = of_find_node_by_path("/reserved-memory"); + for_each_child_of_node(parent, node) { + if (of_node_name_eq(node, "lpm-memory")) + return true; + } + + return false; +} + +static int __maybe_unused ti_sci_suspend(struct device *dev) +{ + const struct ti_sci_desc *desc = device_get_match_data(dev); + + if (pm_suspend_target_state == PM_SUSPEND_MEM && + desc->lpm_region && !ti_sci_check_lpm_region()) { + dev_err(dev, "lpm region is required for suspend to ram but is not provided\n"); + return -EINVAL; + } + + return 0; +} + static int __maybe_unused ti_sci_resume_noirq(struct device *dev) { const struct ti_sci_desc *desc = device_get_match_data(dev); @@ -3387,6 +3416,7 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev) } static const struct dev_pm_ops ti_sci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ti_sci_suspend, NULL) SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ti_sci_resume_noirq) }; @@ -3419,6 +3449,7 @@ static const struct ti_sci_desc ti_sci_pmmc_j7200_desc = { .max_msgs = 20, .max_msg_size = 64, .restore_irqs = true, + .lpm_region = true, }; static const struct of_device_id ti_sci_of_match[] = { @@ -3546,6 +3577,11 @@ static int ti_sci_probe(struct platform_device *pdev) } } +#ifdef CONFIG_PM_SLEEP + if (desc->lpm_region && !ti_sci_check_lpm_region()) + dev_warn(dev, "lpm region is required for suspend to ram but is not provided\n"); +#endif + dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n", info->handle.version.abi_major, info->handle.version.abi_minor, info->handle.version.firmware_revision, -- 2.39.2