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:
parent
14ea1d04ed
commit
410119ee29
|
@ -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),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue