PageRenderTime 13ms CodeModel.GetById 4ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/tidspbridge/core/wdt.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 150 lines | 102 code | 29 blank | 19 comment | 13 complexity | 79b4326a83238efdecbcfb83b88300b6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  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 */
 18#include <linux/types.h>
 19
 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>
 26
 27
 28#ifdef CONFIG_TIDSPBRIDGE_WDT3
 29
 30#define OMAP34XX_WDT3_BASE 		(L4_PER_34XX_BASE + 0x30000)
 31
 32static struct dsp_wdt_setting dsp_wdt;
 33
 34void dsp_wdt_dpc(unsigned long data)
 35{
 36	struct deh_mgr *deh_mgr;
 37	dev_get_deh_mgr(dev_get_first(), &deh_mgr);
 38	if (deh_mgr)
 39		bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
 40}
 41
 42irqreturn_t dsp_wdt_isr(int irq, void *data)
 43{
 44	u32 value;
 45	/* ack wdt3 interrupt */
 46	value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
 47	__raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
 48
 49	tasklet_schedule(&dsp_wdt.wdt3_tasklet);
 50	return IRQ_HANDLED;
 51}
 52
 53int dsp_wdt_init(void)
 54{
 55	int ret = 0;
 56
 57	dsp_wdt.sm_wdt = NULL;
 58	dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE);
 59	tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
 60
 61	dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
 62
 63	if (dsp_wdt.fclk) {
 64		dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
 65		if (!dsp_wdt.iclk) {
 66			clk_put(dsp_wdt.fclk);
 67			dsp_wdt.fclk = NULL;
 68			ret = -EFAULT;
 69		}
 70	} else
 71		ret = -EFAULT;
 72
 73	if (!ret)
 74		ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
 75							"dsp_wdt", &dsp_wdt);
 76
 77	/* Disable at this moment, it will be enabled when DSP starts */
 78	if (!ret)
 79		disable_irq(INT_34XX_WDT3_IRQ);
 80
 81	return ret;
 82}
 83
 84void dsp_wdt_sm_set(void *data)
 85{
 86	dsp_wdt.sm_wdt = data;
 87	dsp_wdt.sm_wdt->wdt_overflow = CONFIG_TIDSPBRIDGE_WDT_TIMEOUT;
 88}
 89
 90
 91void dsp_wdt_exit(void)
 92{
 93	free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
 94	tasklet_kill(&dsp_wdt.wdt3_tasklet);
 95
 96	if (dsp_wdt.fclk)
 97		clk_put(dsp_wdt.fclk);
 98	if (dsp_wdt.iclk)
 99		clk_put(dsp_wdt.iclk);
100
101	dsp_wdt.fclk = NULL;
102	dsp_wdt.iclk = NULL;
103	dsp_wdt.sm_wdt = NULL;
104	dsp_wdt.reg_base = NULL;
105}
106
107void dsp_wdt_enable(bool enable)
108{
109	u32 tmp;
110	static bool wdt_enable;
111
112	if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
113		return;
114
115	wdt_enable = enable;
116
117	if (enable) {
118		clk_enable(dsp_wdt.fclk);
119		clk_enable(dsp_wdt.iclk);
120		dsp_wdt.sm_wdt->wdt_setclocks = 1;
121		tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
122		__raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
123		enable_irq(INT_34XX_WDT3_IRQ);
124	} else {
125		disable_irq(INT_34XX_WDT3_IRQ);
126		dsp_wdt.sm_wdt->wdt_setclocks = 0;
127		clk_disable(dsp_wdt.iclk);
128		clk_disable(dsp_wdt.fclk);
129	}
130}
131
132#else
133void dsp_wdt_enable(bool enable)
134{
135}
136
137void dsp_wdt_sm_set(void *data)
138{
139}
140
141int dsp_wdt_init(void)
142{
143	return 0;
144}
145
146void dsp_wdt_exit(void)
147{
148}
149#endif
150