aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2014-04-03 21:33:25 -0400
committerWim Van Sebroeck <wim@iguana.be>2014-06-10 15:42:46 -0400
commita7977003293ed0c13e62d95fc8cd1d20e22b7282 (patch)
treed39aefdae458a465a05f83a34fdd6583bc1d1006
parent30cb042a846353929042d93d13c9f8e1e5227aa7 (diff)
watchdog: imx2_wdt: convert to use regmap API.
This watchdog driver will be working on IMX2+, Vybrid, LS1, LS2+ platforms, and will be in different endianness mode in those SoCs: SoCs CPU endian mode WDT endian mode ------------------------------------------------ IMX2+ LE LE Vybird LE LE LS1 LE BE LS2 LE LE Other possible SoCs: SoCs CPU endian mode WDT endian mode ------------------------------------------------ Soc1 BE BE Soc2 BE LE And also the watchdog's registers will be 32-bits for some versions, and though it is 16-bits in IMX2+, Vybird and LS+. Using the regmap APIs, could be more easy to support different endianness and also more easy to support 32-bits version... Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r--drivers/watchdog/Kconfig1
-rw-r--r--drivers/watchdog/imx2_wdt.c50
2 files changed, 33 insertions, 18 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 2b4c1fc87653..65ef91e3e497 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -378,6 +378,7 @@ config MAX63XX_WATCHDOG
378config IMX2_WDT 378config IMX2_WDT
379 tristate "IMX2+ Watchdog" 379 tristate "IMX2+ Watchdog"
380 depends on ARCH_MXC 380 depends on ARCH_MXC
381 select REGMAP_MMIO
381 help 382 help
382 This is the driver for the hardware watchdog 383 This is the driver for the hardware watchdog
383 on the Freescale IMX2 and later processors. 384 on the Freescale IMX2 and later processors.
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 179592288c9b..76fa724930ca 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/regmap.h>
34#include <linux/timer.h> 35#include <linux/timer.h>
35#include <linux/uaccess.h> 36#include <linux/uaccess.h>
36#include <linux/watchdog.h> 37#include <linux/watchdog.h>
@@ -61,7 +62,7 @@
61 62
62static struct { 63static struct {
63 struct clk *clk; 64 struct clk *clk;
64 void __iomem *base; 65 struct regmap *regmap;
65 unsigned timeout; 66 unsigned timeout;
66 unsigned long status; 67 unsigned long status;
67 struct timer_list timer; /* Pings the watchdog when closed */ 68 struct timer_list timer; /* Pings the watchdog when closed */
@@ -87,7 +88,9 @@ static const struct watchdog_info imx2_wdt_info = {
87 88
88static inline void imx2_wdt_setup(void) 89static inline void imx2_wdt_setup(void)
89{ 90{
90 u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR); 91 u32 val;
92
93 regmap_read(imx2_wdt.regmap, IMX2_WDT_WCR, &val);
91 94
92 /* Suspend timer in low power mode, write once-only */ 95 /* Suspend timer in low power mode, write once-only */
93 val |= IMX2_WDT_WCR_WDZST; 96 val |= IMX2_WDT_WCR_WDZST;
@@ -100,17 +103,17 @@ static inline void imx2_wdt_setup(void)
100 /* Set the watchdog's Time-Out value */ 103 /* Set the watchdog's Time-Out value */
101 val |= WDOG_SEC_TO_COUNT(imx2_wdt.timeout); 104 val |= WDOG_SEC_TO_COUNT(imx2_wdt.timeout);
102 105
103 __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR); 106 regmap_write(imx2_wdt.regmap, IMX2_WDT_WCR, val);
104 107
105 /* enable the watchdog */ 108 /* enable the watchdog */
106 val |= IMX2_WDT_WCR_WDE; 109 val |= IMX2_WDT_WCR_WDE;
107 __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR); 110 regmap_write(imx2_wdt.regmap, IMX2_WDT_WCR, val);
108} 111}
109 112
110static inline void imx2_wdt_ping(void) 113static inline void imx2_wdt_ping(void)
111{ 114{
112 __raw_writew(IMX2_WDT_SEQ1, imx2_wdt.base + IMX2_WDT_WSR); 115 regmap_write(imx2_wdt.regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ1);
113 __raw_writew(IMX2_WDT_SEQ2, imx2_wdt.base + IMX2_WDT_WSR); 116 regmap_write(imx2_wdt.regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ2);
114} 117}
115 118
116static void imx2_wdt_timer_ping(unsigned long arg) 119static void imx2_wdt_timer_ping(unsigned long arg)
@@ -143,12 +146,8 @@ static void imx2_wdt_stop(void)
143 146
144static void imx2_wdt_set_timeout(int new_timeout) 147static void imx2_wdt_set_timeout(int new_timeout)
145{ 148{
146 u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR); 149 regmap_update_bits(imx2_wdt.regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
147 150 WDOG_SEC_TO_COUNT(new_timeout));
148 /* set the new timeout value in the WSR */
149 val &= ~IMX2_WDT_WCR_WT;
150 val |= WDOG_SEC_TO_COUNT(new_timeout);
151 __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR);
152} 151}
153 152
154static int imx2_wdt_open(struct inode *inode, struct file *file) 153static int imx2_wdt_open(struct inode *inode, struct file *file)
@@ -181,7 +180,7 @@ static long imx2_wdt_ioctl(struct file *file, unsigned int cmd,
181 void __user *argp = (void __user *)arg; 180 void __user *argp = (void __user *)arg;
182 int __user *p = argp; 181 int __user *p = argp;
183 int new_value; 182 int new_value;
184 u16 val; 183 u32 val;
185 184
186 switch (cmd) { 185 switch (cmd) {
187 case WDIOC_GETSUPPORT: 186 case WDIOC_GETSUPPORT:
@@ -192,7 +191,7 @@ static long imx2_wdt_ioctl(struct file *file, unsigned int cmd,
192 return put_user(0, p); 191 return put_user(0, p);
193 192
194 case WDIOC_GETBOOTSTATUS: 193 case WDIOC_GETBOOTSTATUS:
195 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WRSR); 194 regmap_read(imx2_wdt.regmap, IMX2_WDT_WRSR, &val);
196 new_value = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0; 195 new_value = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
197 return put_user(new_value, p); 196 return put_user(new_value, p);
198 197
@@ -255,15 +254,30 @@ static struct miscdevice imx2_wdt_miscdev = {
255 .fops = &imx2_wdt_fops, 254 .fops = &imx2_wdt_fops,
256}; 255};
257 256
257static struct regmap_config imx2_wdt_regmap_config = {
258 .reg_bits = 16,
259 .reg_stride = 2,
260 .val_bits = 16,
261 .max_register = 0x8,
262};
263
258static int __init imx2_wdt_probe(struct platform_device *pdev) 264static int __init imx2_wdt_probe(struct platform_device *pdev)
259{ 265{
260 int ret;
261 struct resource *res; 266 struct resource *res;
267 void __iomem *base;
268 int ret;
262 269
263 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 270 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
264 imx2_wdt.base = devm_ioremap_resource(&pdev->dev, res); 271 base = devm_ioremap_resource(&pdev->dev, res);
265 if (IS_ERR(imx2_wdt.base)) 272 if (IS_ERR(base))
266 return PTR_ERR(imx2_wdt.base); 273 return PTR_ERR(base);
274
275 imx2_wdt.regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
276 &imx2_wdt_regmap_config);
277 if (IS_ERR(imx2_wdt.regmap)) {
278 dev_err(&pdev->dev, "regmap init failed\n");
279 return PTR_ERR(imx2_wdt.regmap);
280 }
267 281
268 imx2_wdt.clk = devm_clk_get(&pdev->dev, NULL); 282 imx2_wdt.clk = devm_clk_get(&pdev->dev, NULL);
269 if (IS_ERR(imx2_wdt.clk)) { 283 if (IS_ERR(imx2_wdt.clk)) {