aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc/omap_remoteproc.c
diff options
context:
space:
mode:
authorShahid Akhtar <sakhtar@ti.com>2011-08-03 18:46:06 -0500
committerIliyan Malchev <malchev@google.com>2011-09-09 12:14:10 -0700
commit9fd61a859a17d18f2fae15677c3368881771bb50 (patch)
tree16b313c58203058651c91959111caf3cc2d1b612 /drivers/remoteproc/omap_remoteproc.c
parent5ea013636ead597c77b132ded34a98cce69a9047 (diff)
downloadkernel_samsung_tuna-9fd61a859a17d18f2fae15677c3368881771bb50.tar.gz
kernel_samsung_tuna-9fd61a859a17d18f2fae15677c3368881771bb50.tar.bz2
kernel_samsung_tuna-9fd61a859a17d18f2fae15677c3368881771bb50.zip
OMAP: remoteproc: watchdog timer for remote cores
Using GP timers as watchdog for M3 cores. The timers are used by both host and M3 cores. The remote cores kick (restart) timer when they reach idle. Change-Id: I8441c78a2c174589d99c7242ffe26694c206e052 Signed-off-by: Shahid Akhtar <sakhtar@ti.com> Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com>
Diffstat (limited to 'drivers/remoteproc/omap_remoteproc.c')
-rw-r--r--drivers/remoteproc/omap_remoteproc.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index c464c1d3d49..2d2bcb68845 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -39,6 +39,7 @@
struct omap_rproc_priv {
struct iommu *iommu;
int (*iommu_cb)(struct rproc *, u64, u32);
+ int (*wdt_cb)(struct rproc *);
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
struct omap_mbox *mbox;
void __iomem *idle;
@@ -321,7 +322,51 @@ static void _destroy_pm_flags(struct rproc *rproc)
}
}
#endif
+#ifdef CONFIG_REMOTEPROC_WATCHDOG
+static int omap_rproc_watchdog_init(struct rproc *rproc,
+ int (*callback)(struct rproc *rproc))
+{
+ struct omap_rproc_priv *rpp = rproc->priv;
+
+ rpp->wdt_cb = callback;
+ return 0;
+}
+
+static int omap_rproc_watchdog_exit(struct rproc *rproc)
+{
+ struct omap_rproc_priv *rpp = rproc->priv;
+
+ rpp->wdt_cb = NULL;
+ return 0;
+}
+
+static irqreturn_t omap_rproc_watchdog_isr(int irq, void *p)
+{
+ struct rproc *rproc = p;
+ struct omap_rproc_pdata *pdata = rproc->dev->platform_data;
+ struct omap_rproc_timers_info *timers = pdata->timers;
+ struct omap_dm_timer *timer = NULL;
+ struct omap_rproc_priv *rpp = rproc->priv;
+ int i;
+
+ for (i = 0; i < pdata->timers_cnt; i++) {
+ if (irq == omap_dm_timer_get_irq(timers[i].odt)) {
+ timer = timers[i].odt;
+ break;
+ }
+ }
+
+ if (!timer)
+ return IRQ_NONE;
+ omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW);
+
+ if (rpp->wdt_cb)
+ rpp->wdt_cb(rproc);
+
+ return IRQ_HANDLED;
+}
+#endif
static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr)
{
struct device *dev = rproc->dev;
@@ -339,6 +384,16 @@ static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr)
goto out;
}
omap_dm_timer_set_source(timers[i].odt, OMAP_TIMER_SRC_SYS_CLK);
+#ifdef CONFIG_REMOTEPROC_WATCHDOG
+ /* GPT 9 and 11 are using as WDT */
+ if (timers[i].id == 9 || timers[i].id == 11) {
+ ret = request_irq(omap_dm_timer_get_irq(timers[i].odt),
+ omap_rproc_watchdog_isr, IRQF_DISABLED,
+ "rproc-wdt", rproc);
+ /* Clean counter, remoteproc proc will set the value */
+ omap_dm_timer_set_load(timers[i].odt, 0, 0);
+ }
+#endif
}
ret = omap_device_enable(pdev);
@@ -413,6 +468,10 @@ static struct rproc_ops omap_rproc_ops = {
.set_lat = omap_rproc_set_lat,
.set_bw = omap_rproc_set_l3_bw,
.scale = omap_rproc_scale,
+#ifdef CONFIG_REMOTEPROC_WATCHDOG
+ .watchdog_init = omap_rproc_watchdog_init,
+ .watchdog_exit = omap_rproc_watchdog_exit,
+#endif
};
static int omap_rproc_probe(struct platform_device *pdev)