]> git.karo-electronics.de Git - linux-beck.git/commitdiff
watchdog: imx2_wdt: convert to use regmap API.
authorXiubo Li <Li.Xiubo@freescale.com>
Fri, 4 Apr 2014 01:33:25 +0000 (09:33 +0800)
committerWim Van Sebroeck <wim@iguana.be>
Tue, 10 Jun 2014 19:42:46 +0000 (21:42 +0200)
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>
drivers/watchdog/Kconfig
drivers/watchdog/imx2_wdt.c

index 2b4c1fc8765340f8cedd5f976476adbdd31e2961..65ef91e3e497f4b543fa9964f638fc1fde970bb4 100644 (file)
@@ -378,6 +378,7 @@ config MAX63XX_WATCHDOG
 config IMX2_WDT
        tristate "IMX2+ Watchdog"
        depends on ARCH_MXC
 config IMX2_WDT
        tristate "IMX2+ Watchdog"
        depends on ARCH_MXC
+       select REGMAP_MMIO
        help
          This is the driver for the hardware watchdog
          on the Freescale IMX2 and later processors.
        help
          This is the driver for the hardware watchdog
          on the Freescale IMX2 and later processors.
index 179592288c9be3f19c72753f6055dc33e1787047..76fa724930ca562fd5e35dfef7c4bfe2fbfbdb7d 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/timer.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
 #include <linux/timer.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
@@ -61,7 +62,7 @@
 
 static struct {
        struct clk *clk;
 
 static struct {
        struct clk *clk;
-       void __iomem *base;
+       struct regmap *regmap;
        unsigned timeout;
        unsigned long status;
        struct timer_list timer;        /* Pings the watchdog when closed */
        unsigned timeout;
        unsigned long status;
        struct timer_list timer;        /* Pings the watchdog when closed */
@@ -87,7 +88,9 @@ static const struct watchdog_info imx2_wdt_info = {
 
 static inline void imx2_wdt_setup(void)
 {
 
 static inline void imx2_wdt_setup(void)
 {
-       u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR);
+       u32 val;
+
+       regmap_read(imx2_wdt.regmap, IMX2_WDT_WCR, &val);
 
        /* Suspend timer in low power mode, write once-only */
        val |= IMX2_WDT_WCR_WDZST;
 
        /* Suspend timer in low power mode, write once-only */
        val |= IMX2_WDT_WCR_WDZST;
@@ -100,17 +103,17 @@ static inline void imx2_wdt_setup(void)
        /* Set the watchdog's Time-Out value */
        val |= WDOG_SEC_TO_COUNT(imx2_wdt.timeout);
 
        /* Set the watchdog's Time-Out value */
        val |= WDOG_SEC_TO_COUNT(imx2_wdt.timeout);
 
-       __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR);
+       regmap_write(imx2_wdt.regmap, IMX2_WDT_WCR, val);
 
        /* enable the watchdog */
        val |= IMX2_WDT_WCR_WDE;
 
        /* enable the watchdog */
        val |= IMX2_WDT_WCR_WDE;
-       __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR);
+       regmap_write(imx2_wdt.regmap, IMX2_WDT_WCR, val);
 }
 
 static inline void imx2_wdt_ping(void)
 {
 }
 
 static inline void imx2_wdt_ping(void)
 {
-       __raw_writew(IMX2_WDT_SEQ1, imx2_wdt.base + IMX2_WDT_WSR);
-       __raw_writew(IMX2_WDT_SEQ2, imx2_wdt.base + IMX2_WDT_WSR);
+       regmap_write(imx2_wdt.regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ1);
+       regmap_write(imx2_wdt.regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ2);
 }
 
 static void imx2_wdt_timer_ping(unsigned long arg)
 }
 
 static void imx2_wdt_timer_ping(unsigned long arg)
@@ -143,12 +146,8 @@ static void imx2_wdt_stop(void)
 
 static void imx2_wdt_set_timeout(int new_timeout)
 {
 
 static void imx2_wdt_set_timeout(int new_timeout)
 {
-       u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR);
-
-       /* set the new timeout value in the WSR */
-       val &= ~IMX2_WDT_WCR_WT;
-       val |= WDOG_SEC_TO_COUNT(new_timeout);
-       __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR);
+       regmap_update_bits(imx2_wdt.regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
+                          WDOG_SEC_TO_COUNT(new_timeout));
 }
 
 static int imx2_wdt_open(struct inode *inode, struct file *file)
 }
 
 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,
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
        int new_value;
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
        int new_value;
-       u16 val;
+       u32 val;
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
@@ -192,7 +191,7 @@ static long imx2_wdt_ioctl(struct file *file, unsigned int cmd,
                return put_user(0, p);
 
        case WDIOC_GETBOOTSTATUS:
                return put_user(0, p);
 
        case WDIOC_GETBOOTSTATUS:
-               val = __raw_readw(imx2_wdt.base + IMX2_WDT_WRSR);
+               regmap_read(imx2_wdt.regmap, IMX2_WDT_WRSR, &val);
                new_value = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
                return put_user(new_value, p);
 
                new_value = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
                return put_user(new_value, p);
 
@@ -255,15 +254,30 @@ static struct miscdevice imx2_wdt_miscdev = {
        .fops = &imx2_wdt_fops,
 };
 
        .fops = &imx2_wdt_fops,
 };
 
+static struct regmap_config imx2_wdt_regmap_config = {
+       .reg_bits = 16,
+       .reg_stride = 2,
+       .val_bits = 16,
+       .max_register = 0x8,
+};
+
 static int __init imx2_wdt_probe(struct platform_device *pdev)
 {
 static int __init imx2_wdt_probe(struct platform_device *pdev)
 {
-       int ret;
        struct resource *res;
        struct resource *res;
+       void __iomem *base;
+       int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       imx2_wdt.base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(imx2_wdt.base))
-               return PTR_ERR(imx2_wdt.base);
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       imx2_wdt.regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
+                                                   &imx2_wdt_regmap_config);
+       if (IS_ERR(imx2_wdt.regmap)) {
+               dev_err(&pdev->dev, "regmap init failed\n");
+               return PTR_ERR(imx2_wdt.regmap);
+       }
 
        imx2_wdt.clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(imx2_wdt.clk)) {
 
        imx2_wdt.clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(imx2_wdt.clk)) {