blob: 70055c8111ed2d208162dbcd7f93f3b6c52c70c7 [file] [log] [blame]
Omar Ramirez Luna999e07d2010-06-23 16:01:56 +03001/*
2 * wdt.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * IO dispatcher for a shared memory channel driver.
7 *
8 * Copyright (C) 2010 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
Nishanth Menon2094f122010-07-12 17:56:01 -050018#include <linux/types.h>
Omar Ramirez Luna999e07d2010-06-23 16:01:56 +030019
Omar Ramirez Luna999e07d2010-06-23 16:01:56 +030020#include <dspbridge/dbdefs.h>
21#include <dspbridge/dspdeh.h>
22#include <dspbridge/dev.h>
23#include <dspbridge/_chnl_sm.h>
24#include <dspbridge/wdt.h>
25#include <dspbridge/host_os.h>
26
27
Omar Ramirez Luna999e07d2010-06-23 16:01:56 +030028#define OMAP34XX_WDT3_BASE (L4_PER_34XX_BASE + 0x30000)
29
30static struct dsp_wdt_setting dsp_wdt;
31
32void dsp_wdt_dpc(unsigned long data)
33{
34 struct deh_mgr *deh_mgr;
35 dev_get_deh_mgr(dev_get_first(), &deh_mgr);
36 if (deh_mgr)
37 bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
38}
39
40irqreturn_t dsp_wdt_isr(int irq, void *data)
41{
42 u32 value;
43 /* ack wdt3 interrupt */
44 value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
45 __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
46
47 tasklet_schedule(&dsp_wdt.wdt3_tasklet);
48 return IRQ_HANDLED;
49}
50
51int dsp_wdt_init(void)
52{
53 int ret = 0;
54
55 dsp_wdt.sm_wdt = NULL;
56 dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE);
57 tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
58
59 dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
60
61 if (dsp_wdt.fclk) {
62 dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
63 if (!dsp_wdt.iclk) {
64 clk_put(dsp_wdt.fclk);
65 dsp_wdt.fclk = NULL;
66 ret = -EFAULT;
67 }
68 } else
69 ret = -EFAULT;
70
71 if (!ret)
72 ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
73 "dsp_wdt", &dsp_wdt);
74
75 /* Disable at this moment, it will be enabled when DSP starts */
76 if (!ret)
77 disable_irq(INT_34XX_WDT3_IRQ);
78
79 return ret;
80}
81
82void dsp_wdt_sm_set(void *data)
83{
84 dsp_wdt.sm_wdt = data;
Omar Ramirez Luna18db4fe2012-02-21 20:46:20 -060085 dsp_wdt.sm_wdt->wdt_overflow = 5; /* in seconds */
Omar Ramirez Luna999e07d2010-06-23 16:01:56 +030086}
87
88
89void dsp_wdt_exit(void)
90{
91 free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
92 tasklet_kill(&dsp_wdt.wdt3_tasklet);
93
94 if (dsp_wdt.fclk)
95 clk_put(dsp_wdt.fclk);
96 if (dsp_wdt.iclk)
97 clk_put(dsp_wdt.iclk);
98
99 dsp_wdt.fclk = NULL;
100 dsp_wdt.iclk = NULL;
101 dsp_wdt.sm_wdt = NULL;
102 dsp_wdt.reg_base = NULL;
103}
104
105void dsp_wdt_enable(bool enable)
106{
107 u32 tmp;
108 static bool wdt_enable;
109
110 if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
111 return;
112
113 wdt_enable = enable;
114
115 if (enable) {
116 clk_enable(dsp_wdt.fclk);
117 clk_enable(dsp_wdt.iclk);
118 dsp_wdt.sm_wdt->wdt_setclocks = 1;
119 tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
120 __raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
121 enable_irq(INT_34XX_WDT3_IRQ);
122 } else {
123 disable_irq(INT_34XX_WDT3_IRQ);
124 dsp_wdt.sm_wdt->wdt_setclocks = 0;
125 clk_disable(dsp_wdt.iclk);
126 clk_disable(dsp_wdt.fclk);
127 }
128}