remoteproc: stm32: wakeup the system by wdg irq

If the device node defines the 'wakeup-source' property, use the WDG
exti IRQ as a wakeup source of the system.

Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
Link: https://lore.kernel.org/r/1566833923-16718-3-git-send-email-fabien.dessenne@st.com
[bjorn: Replace ifdef with __maybe_unused for suspend/resume functions]
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
Fabien Dessenne 2019-08-26 17:38:43 +02:00 committed by Bjorn Andersson
parent 14ea1d04ed
commit 410119ee29

View File

@ -15,6 +15,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_reserved_mem.h> #include <linux/of_reserved_mem.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/remoteproc.h> #include <linux/remoteproc.h>
#include <linux/reset.h> #include <linux/reset.h>
@ -69,6 +70,7 @@ struct stm32_rproc {
struct reset_control *rst; struct reset_control *rst;
struct stm32_syscon hold_boot; struct stm32_syscon hold_boot;
struct stm32_syscon pdds; struct stm32_syscon pdds;
int wdg_irq;
u32 nb_rmems; u32 nb_rmems;
struct stm32_rproc_mem *rmems; struct stm32_rproc_mem *rmems;
struct stm32_mbox mb[MBOX_NB_MBX]; struct stm32_mbox mb[MBOX_NB_MBX];
@ -546,6 +548,13 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
return err; 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"); dev_info(dev, "wdg irq registered\n");
} }
@ -633,6 +642,10 @@ free_mb:
free_wkq: free_wkq:
destroy_workqueue(ddata->workqueue); destroy_workqueue(ddata->workqueue);
free_rproc: free_rproc:
if (device_may_wakeup(dev)) {
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc); rproc_free(rproc);
return ret; return ret;
} }
@ -641,6 +654,7 @@ static int stm32_rproc_remove(struct platform_device *pdev)
{ {
struct rproc *rproc = platform_get_drvdata(pdev); struct rproc *rproc = platform_get_drvdata(pdev);
struct stm32_rproc *ddata = rproc->priv; struct stm32_rproc *ddata = rproc->priv;
struct device *dev = &pdev->dev;
if (atomic_read(&rproc->power) > 0) if (atomic_read(&rproc->power) > 0)
rproc_shutdown(rproc); rproc_shutdown(rproc);
@ -648,16 +662,47 @@ static int stm32_rproc_remove(struct platform_device *pdev)
rproc_del(rproc); rproc_del(rproc);
stm32_rproc_free_mbox(rproc); stm32_rproc_free_mbox(rproc);
destroy_workqueue(ddata->workqueue); destroy_workqueue(ddata->workqueue);
if (device_may_wakeup(dev)) {
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc); rproc_free(rproc);
return 0; 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 = { static struct platform_driver stm32_rproc_driver = {
.probe = stm32_rproc_probe, .probe = stm32_rproc_probe,
.remove = stm32_rproc_remove, .remove = stm32_rproc_remove,
.driver = { .driver = {
.name = "stm32-rproc", .name = "stm32-rproc",
.pm = &stm32_rproc_pm_ops,
.of_match_table = of_match_ptr(stm32_rproc_match), .of_match_table = of_match_ptr(stm32_rproc_match),
}, },
}; };