diff options
author | Xiubo Li <Li.Xiubo@freescale.com> | 2014-04-03 21:33:25 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2014-06-10 15:42:46 -0400 |
commit | a7977003293ed0c13e62d95fc8cd1d20e22b7282 (patch) | |
tree | d39aefdae458a465a05f83a34fdd6583bc1d1006 | |
parent | 30cb042a846353929042d93d13c9f8e1e5227aa7 (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/watchdog/imx2_wdt.c | 50 |
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 | |||
378 | config IMX2_WDT | 378 | config 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 | ||
62 | static struct { | 63 | static 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 | ||
88 | static inline void imx2_wdt_setup(void) | 89 | static 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 | ||
110 | static inline void imx2_wdt_ping(void) | 113 | static 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 | ||
116 | static void imx2_wdt_timer_ping(unsigned long arg) | 119 | static void imx2_wdt_timer_ping(unsigned long arg) |
@@ -143,12 +146,8 @@ static void imx2_wdt_stop(void) | |||
143 | 146 | ||
144 | static void imx2_wdt_set_timeout(int new_timeout) | 147 | static 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 | ||
154 | static int imx2_wdt_open(struct inode *inode, struct file *file) | 153 | static 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 | ||
257 | static 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 | |||
258 | static int __init imx2_wdt_probe(struct platform_device *pdev) | 264 | static 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)) { |