summaryrefslogtreecommitdiff
path: root/drivers/remoteproc/stm32_rproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc/stm32_rproc.c')
-rw-r--r--drivers/remoteproc/stm32_rproc.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index f791770b8850..4adc9cefb532 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -15,6 +15,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
+#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>
@@ -69,6 +70,7 @@ struct stm32_rproc {
struct reset_control *rst;
struct stm32_syscon hold_boot;
struct stm32_syscon pdds;
+ int wdg_irq;
u32 nb_rmems;
struct stm32_rproc_mem *rmems;
struct stm32_mbox mb[MBOX_NB_MBX];
@@ -546,6 +548,13 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
return err;
}
+ ddata->wdg_irq = irq;
+
+ if (of_property_read_bool(np, "wakeup-source")) {
+ device_init_wakeup(dev, true);
+ dev_pm_set_wake_irq(dev, irq);
+ }
+
dev_info(dev, "wdg irq registered\n");
}
@@ -633,6 +642,10 @@ free_mb:
free_wkq:
destroy_workqueue(ddata->workqueue);
free_rproc:
+ if (device_may_wakeup(dev)) {
+ dev_pm_clear_wake_irq(dev);
+ device_init_wakeup(dev, false);
+ }
rproc_free(rproc);
return ret;
}
@@ -641,6 +654,7 @@ static int stm32_rproc_remove(struct platform_device *pdev)
{
struct rproc *rproc = platform_get_drvdata(pdev);
struct stm32_rproc *ddata = rproc->priv;
+ struct device *dev = &pdev->dev;
if (atomic_read(&rproc->power) > 0)
rproc_shutdown(rproc);
@@ -648,16 +662,47 @@ static int stm32_rproc_remove(struct platform_device *pdev)
rproc_del(rproc);
stm32_rproc_free_mbox(rproc);
destroy_workqueue(ddata->workqueue);
+
+ if (device_may_wakeup(dev)) {
+ dev_pm_clear_wake_irq(dev);
+ device_init_wakeup(dev, false);
+ }
rproc_free(rproc);
return 0;
}
+static int __maybe_unused stm32_rproc_suspend(struct device *dev)
+{
+ struct rproc *rproc = dev_get_drvdata(dev);
+ struct stm32_rproc *ddata = rproc->priv;
+
+ if (device_may_wakeup(dev))
+ return enable_irq_wake(ddata->wdg_irq);
+
+ return 0;
+}
+
+static int __maybe_unused stm32_rproc_resume(struct device *dev)
+{
+ struct rproc *rproc = dev_get_drvdata(dev);
+ struct stm32_rproc *ddata = rproc->priv;
+
+ if (device_may_wakeup(dev))
+ return disable_irq_wake(ddata->wdg_irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops,
+ stm32_rproc_suspend, stm32_rproc_resume);
+
static struct platform_driver stm32_rproc_driver = {
.probe = stm32_rproc_probe,
.remove = stm32_rproc_remove,
.driver = {
.name = "stm32-rproc",
+ .pm = &stm32_rproc_pm_ops,
.of_match_table = of_match_ptr(stm32_rproc_match),
},
};