aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/davinci_wdt.c
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@ti.com>2013-12-04 14:39:27 -0500
committerWim Van Sebroeck <wim@iguana.be>2014-01-28 15:19:55 -0500
commit6d9a6cf5c63fe4f08b05fc53f7a17048df86d3ac (patch)
tree7219c364560d306f73ec4f54f663bca1cb4f33a4 /drivers/watchdog/davinci_wdt.c
parentf48f3ceabf2ce4fb5b8aa0672166e1e9001946b9 (diff)
watchdog: davinci: use davinci_wdt_device structure to hold device data
Some SoCs, like Keystone 2, can support more than one WDT and each watchdog device has to use it's own base address, clock source, watchdog device, so add new davinci_wdt_device structure to hold device data. Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Guenter roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog/davinci_wdt.c')
-rw-r--r--drivers/watchdog/davinci_wdt.c74
1 files changed, 48 insertions, 26 deletions
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index bb8f23cd449a..6d76fcf00525 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -56,51 +56,63 @@
56#define WDKEY_SEQ1 (0xda7e << 16) 56#define WDKEY_SEQ1 (0xda7e << 16)
57 57
58static int heartbeat; 58static int heartbeat;
59static void __iomem *wdt_base; 59
60struct clk *wdt_clk; 60/*
61static struct watchdog_device wdt_wdd; 61 * struct to hold data for each WDT device
62 * @base - base io address of WD device
63 * @clk - source clock of WDT
64 * @wdd - hold watchdog device as is in WDT core
65 */
66struct davinci_wdt_device {
67 void __iomem *base;
68 struct clk *clk;
69 struct watchdog_device wdd;
70};
62 71
63static int davinci_wdt_start(struct watchdog_device *wdd) 72static int davinci_wdt_start(struct watchdog_device *wdd)
64{ 73{
65 u32 tgcr; 74 u32 tgcr;
66 u32 timer_margin; 75 u32 timer_margin;
67 unsigned long wdt_freq; 76 unsigned long wdt_freq;
77 struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
68 78
69 wdt_freq = clk_get_rate(wdt_clk); 79 wdt_freq = clk_get_rate(davinci_wdt->clk);
70 80
71 /* disable, internal clock source */ 81 /* disable, internal clock source */
72 iowrite32(0, wdt_base + TCR); 82 iowrite32(0, davinci_wdt->base + TCR);
73 /* reset timer, set mode to 64-bit watchdog, and unreset */ 83 /* reset timer, set mode to 64-bit watchdog, and unreset */
74 iowrite32(0, wdt_base + TGCR); 84 iowrite32(0, davinci_wdt->base + TGCR);
75 tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET; 85 tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
76 iowrite32(tgcr, wdt_base + TGCR); 86 iowrite32(tgcr, davinci_wdt->base + TGCR);
77 /* clear counter regs */ 87 /* clear counter regs */
78 iowrite32(0, wdt_base + TIM12); 88 iowrite32(0, davinci_wdt->base + TIM12);
79 iowrite32(0, wdt_base + TIM34); 89 iowrite32(0, davinci_wdt->base + TIM34);
80 /* set timeout period */ 90 /* set timeout period */
81 timer_margin = (((u64)wdd->timeout * wdt_freq) & 0xffffffff); 91 timer_margin = (((u64)wdd->timeout * wdt_freq) & 0xffffffff);
82 iowrite32(timer_margin, wdt_base + PRD12); 92 iowrite32(timer_margin, davinci_wdt->base + PRD12);
83 timer_margin = (((u64)wdd->timeout * wdt_freq) >> 32); 93 timer_margin = (((u64)wdd->timeout * wdt_freq) >> 32);
84 iowrite32(timer_margin, wdt_base + PRD34); 94 iowrite32(timer_margin, davinci_wdt->base + PRD34);
85 /* enable run continuously */ 95 /* enable run continuously */
86 iowrite32(ENAMODE12_PERIODIC, wdt_base + TCR); 96 iowrite32(ENAMODE12_PERIODIC, davinci_wdt->base + TCR);
87 /* Once the WDT is in pre-active state write to 97 /* Once the WDT is in pre-active state write to
88 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are 98 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
89 * write protected (except for the WDKEY field) 99 * write protected (except for the WDKEY field)
90 */ 100 */
91 /* put watchdog in pre-active state */ 101 /* put watchdog in pre-active state */
92 iowrite32(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR); 102 iowrite32(WDKEY_SEQ0 | WDEN, davinci_wdt->base + WDTCR);
93 /* put watchdog in active state */ 103 /* put watchdog in active state */
94 iowrite32(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR); 104 iowrite32(WDKEY_SEQ1 | WDEN, davinci_wdt->base + WDTCR);
95 return 0; 105 return 0;
96} 106}
97 107
98static int davinci_wdt_ping(struct watchdog_device *wdd) 108static int davinci_wdt_ping(struct watchdog_device *wdd)
99{ 109{
110 struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
111
100 /* put watchdog in service state */ 112 /* put watchdog in service state */
101 iowrite32(WDKEY_SEQ0, wdt_base + WDTCR); 113 iowrite32(WDKEY_SEQ0, davinci_wdt->base + WDTCR);
102 /* put watchdog in active state */ 114 /* put watchdog in active state */
103 iowrite32(WDKEY_SEQ1, wdt_base + WDTCR); 115 iowrite32(WDKEY_SEQ1, davinci_wdt->base + WDTCR);
104 return 0; 116 return 0;
105} 117}
106 118
@@ -122,14 +134,21 @@ static int davinci_wdt_probe(struct platform_device *pdev)
122 struct device *dev = &pdev->dev; 134 struct device *dev = &pdev->dev;
123 struct resource *wdt_mem; 135 struct resource *wdt_mem;
124 struct watchdog_device *wdd; 136 struct watchdog_device *wdd;
137 struct davinci_wdt_device *davinci_wdt;
138
139 davinci_wdt = devm_kzalloc(dev, sizeof(*davinci_wdt), GFP_KERNEL);
140 if (!davinci_wdt)
141 return -ENOMEM;
125 142
126 wdt_clk = devm_clk_get(dev, NULL); 143 davinci_wdt->clk = devm_clk_get(dev, NULL);
127 if (WARN_ON(IS_ERR(wdt_clk))) 144 if (WARN_ON(IS_ERR(davinci_wdt->clk)))
128 return PTR_ERR(wdt_clk); 145 return PTR_ERR(davinci_wdt->clk);
129 146
130 clk_prepare_enable(wdt_clk); 147 clk_prepare_enable(davinci_wdt->clk);
131 148
132 wdd = &wdt_wdd; 149 platform_set_drvdata(pdev, davinci_wdt);
150
151 wdd = &davinci_wdt->wdd;
133 wdd->info = &davinci_wdt_info; 152 wdd->info = &davinci_wdt_info;
134 wdd->ops = &davinci_wdt_ops; 153 wdd->ops = &davinci_wdt_ops;
135 wdd->min_timeout = 1; 154 wdd->min_timeout = 1;
@@ -140,12 +159,13 @@ static int davinci_wdt_probe(struct platform_device *pdev)
140 159
141 dev_info(dev, "heartbeat %d sec\n", wdd->timeout); 160 dev_info(dev, "heartbeat %d sec\n", wdd->timeout);
142 161
162 watchdog_set_drvdata(wdd, davinci_wdt);
143 watchdog_set_nowayout(wdd, 1); 163 watchdog_set_nowayout(wdd, 1);
144 164
145 wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 165 wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
146 wdt_base = devm_ioremap_resource(dev, wdt_mem); 166 davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
147 if (IS_ERR(wdt_base)) 167 if (IS_ERR(davinci_wdt->base))
148 return PTR_ERR(wdt_base); 168 return PTR_ERR(davinci_wdt->base);
149 169
150 ret = watchdog_register_device(wdd); 170 ret = watchdog_register_device(wdd);
151 if (ret < 0) 171 if (ret < 0)
@@ -156,8 +176,10 @@ static int davinci_wdt_probe(struct platform_device *pdev)
156 176
157static int davinci_wdt_remove(struct platform_device *pdev) 177static int davinci_wdt_remove(struct platform_device *pdev)
158{ 178{
159 watchdog_unregister_device(&wdt_wdd); 179 struct davinci_wdt_device *davinci_wdt = platform_get_drvdata(pdev);
160 clk_disable_unprepare(wdt_clk); 180
181 watchdog_unregister_device(&davinci_wdt->wdd);
182 clk_disable_unprepare(davinci_wdt->clk);
161 183
162 return 0; 184 return 0;
163} 185}