From 1a561c521ba901ac86acaf698e79ad6ecedbec2b Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Tue, 21 Sep 2021 16:04:27 +0530 Subject: [PATCH] soc: qcom: smp2p: Add wakeup capability to SMP2P IRQ Remote susbsystems notify fatal crash through smp2p interrupt. When remoteproc crashes it can cause soc to come out of low power state and may not allow again to enter in low power state until crash is handled. Mark smp2p interrupt wakeup capable so that interrupt handler is executed and remoteproc crash can be handled in system resume path. This patch marks interrupt wakeup capable but keeps wakeup disabled by default. User space can enable it based on its requirement for wakeup from suspend. Signed-off-by: Deepak Kumar Singh Reviewed-by: Stephen Boyd Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/1632220467-27410-1-git-send-email-deesin@codeaurora.org --- drivers/soc/qcom/smp2p.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 2df488333be9c..38585a7edfe75 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -538,9 +539,26 @@ static int qcom_smp2p_probe(struct platform_device *pdev) goto unwind_interfaces; } + /* + * Treat smp2p interrupt as wakeup source, but keep it disabled + * by default. User space can decide enabling it depending on its + * use cases. For example if remoteproc crashes and device wants + * to handle it immediatedly (e.g. to not miss phone calls) it can + * enable wakeup source from user space, while other devices which + * do not have proper autosleep feature may want to handle it with + * other wakeup events (e.g. Power button) instead waking up immediately. + */ + device_set_wakeup_capable(&pdev->dev, true); + + ret = dev_pm_set_wake_irq(&pdev->dev, irq); + if (ret) + goto set_wake_irq_fail; return 0; +set_wake_irq_fail: + dev_pm_clear_wake_irq(&pdev->dev); + unwind_interfaces: list_for_each_entry(entry, &smp2p->inbound, node) irq_domain_remove(entry->domain); @@ -565,6 +583,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev) struct qcom_smp2p *smp2p = platform_get_drvdata(pdev); struct smp2p_entry *entry; + dev_pm_clear_wake_irq(&pdev->dev); + list_for_each_entry(entry, &smp2p->inbound, node) irq_domain_remove(entry->domain); -- 2.30.2