4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * IO dispatcher for a shared memory channel driver.
8 * Copyright (C) 2010 Texas Instruments, Inc.
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.
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.
18 #include <linux/types.h>
20 #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>
28 #define OMAP34XX_WDT3_BASE (0x49000000 + 0x30000)
29 #define INT_34XX_WDT3_IRQ (36 + NR_IRQS)
31 static struct dsp_wdt_setting dsp_wdt;
33 void dsp_wdt_dpc(unsigned long data)
35 struct deh_mgr *deh_mgr;
36 dev_get_deh_mgr(dev_get_first(), &deh_mgr);
38 bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
41 irqreturn_t dsp_wdt_isr(int irq, void *data)
44 /* ack wdt3 interrupt */
45 value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
46 __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
48 tasklet_schedule(&dsp_wdt.wdt3_tasklet);
52 int dsp_wdt_init(void)
56 dsp_wdt.sm_wdt = NULL;
57 dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K);
58 if (!dsp_wdt.reg_base)
61 tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
63 dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
65 if (!IS_ERR(dsp_wdt.fclk)) {
66 clk_prepare(dsp_wdt.fclk);
68 dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
69 if (IS_ERR(dsp_wdt.iclk)) {
70 clk_put(dsp_wdt.fclk);
74 clk_prepare(dsp_wdt.iclk);
80 ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
83 /* Disable at this moment, it will be enabled when DSP starts */
85 disable_irq(INT_34XX_WDT3_IRQ);
90 void dsp_wdt_sm_set(void *data)
92 dsp_wdt.sm_wdt = data;
93 dsp_wdt.sm_wdt->wdt_overflow = 5; /* in seconds */
97 void dsp_wdt_exit(void)
99 free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
100 tasklet_kill(&dsp_wdt.wdt3_tasklet);
103 clk_unprepare(dsp_wdt.fclk);
104 clk_put(dsp_wdt.fclk);
107 clk_unprepare(dsp_wdt.iclk);
108 clk_put(dsp_wdt.iclk);
113 dsp_wdt.sm_wdt = NULL;
115 if (dsp_wdt.reg_base)
116 iounmap(dsp_wdt.reg_base);
117 dsp_wdt.reg_base = NULL;
120 void dsp_wdt_enable(bool enable)
123 static bool wdt_enable;
125 if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
131 clk_enable(dsp_wdt.fclk);
132 clk_enable(dsp_wdt.iclk);
133 dsp_wdt.sm_wdt->wdt_setclocks = 1;
134 tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
135 __raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
136 enable_irq(INT_34XX_WDT3_IRQ);
138 disable_irq(INT_34XX_WDT3_IRQ);
139 dsp_wdt.sm_wdt->wdt_setclocks = 0;
140 clk_disable(dsp_wdt.iclk);
141 clk_disable(dsp_wdt.fclk);