[v2] firmware: imx: scu: ensure wakeup procedure calls pm_system_wakeup()
Commit Message
There will still be mu irq in the suspend stage, for
example, in imx8. When the system enters the suspend
state, the GPIO enters the pad wakeup state. Calling
pm_system_wakeup() at this time will cause the system
suspend to terminate, so when it is set to wakeup, call
pm_system_wakeup(), through rtcwake -s 10 -v -m freeze
verification.
mxc_gpio_noirq_suspend
mxc_gpio_set_pad_wakeup
mbox_send_message
imx_mu_isr
imx_mu_generic_rxdb
Fixes: 0caf847975b2 ("firmware: imx: make sure MU irq can wake up system from suspend mode")
Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
---
Changes in v2:
- Fix warning: 'imx_scu_pm_ops' defined but not used [-Wunused-const-variable=] and etested it
drivers/firmware/imx/imx-scu-irq.c | 4 +++-
drivers/firmware/imx/imx-scu.c | 21 +++++++++++++++++++++
include/linux/firmware/imx/sci.h | 1 +
3 files changed, 25 insertions(+), 1 deletion(-)
@@ -20,6 +20,7 @@
#define IMX_SC_IRQ_NUM_GROUP 9
static u32 mu_resource_id;
+int scu_suspend;
struct imx_sc_msg_irq_get_status {
struct imx_sc_rpc_msg hdr;
@@ -109,7 +110,8 @@ static void imx_scu_irq_work_handler(struct work_struct *work)
scu_irq_wakeup[i].wakeup_src = irq_status;
}
- pm_system_wakeup();
+ if (scu_suspend)
+ pm_system_wakeup();
imx_scu_irq_notifier_call_chain(irq_status, &i);
}
}
@@ -342,15 +342,36 @@ static int imx_scu_probe(struct platform_device *pdev)
return devm_of_platform_populate(dev);
}
+
+
static const struct of_device_id imx_scu_match[] = {
{ .compatible = "fsl,imx-scu", },
{ /* Sentinel */ }
};
+static int __maybe_unused imx_scu_suspend_noirq(struct device *dev)
+{
+ scu_suspend = true;
+
+ return 0;
+}
+
+static int __maybe_unused imx_scu_resume_noirq(struct device *dev)
+{
+ scu_suspend = false;
+
+ return 0;
+};
+
+static const struct dev_pm_ops imx_scu_pm_ops = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_scu_suspend_noirq,
+ imx_scu_resume_noirq)
+};
static struct platform_driver imx_scu_driver = {
.driver = {
.name = "imx-scu",
.of_match_table = imx_scu_match,
+ .pm = &imx_scu_pm_ops,
},
.probe = imx_scu_probe,
};
@@ -17,6 +17,7 @@
#include <linux/firmware/imx/svc/rm.h>
#if IS_ENABLED(CONFIG_IMX_SCU)
+extern int scu_suspend;
int imx_scu_enable_general_irq_channel(struct device *dev);
int imx_scu_irq_register_notifier(struct notifier_block *nb);
int imx_scu_irq_unregister_notifier(struct notifier_block *nb);