watch dog: prepare driver for kernel3.10
authorhhb <hhb@rock-chips.com>
Tue, 4 Mar 2014 07:05:09 +0000 (15:05 +0800)
committerhhb <hhb@rock-chips.com>
Tue, 4 Mar 2014 07:05:09 +0000 (15:05 +0800)
arch/arm/boot/dts/rk3188.dtsi
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/rk29_wdt.c

index 4472b94cb96c1eff179e5b3dd243335edef1199c..34d96873a1f107dd6230c7ea67e57aa67f5a728c 100755 (executable)
                rockchip,clocksource = <1>;
        };
 
+       watchdog:wdt@2004c000 {
+               compatible = "rockchip,watch dog";
+               reg = <0x2004c000 0x100>;
+               clocks = <&clk_gates7 15>;
+               clock-names = "pclk_wdt";
+               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+               rockchip,irq = <1>;
+               rockchip,timeout = <5>;
+               rockchip,atboot = <1>;
+               rockchip,debug = <0>;
+               status = "disabled";
+       };
+
        amba {
                #address-cells = <1>;
                #size-cells = <1>;
index e89fc313397233bf80a7d210d8b0db2a36492314..47a54895542213f4dd5282a8df3b79d6198aaee0 100644 (file)
@@ -107,6 +107,30 @@ config WM8350_WATCHDOG
 
 # ARM Architecture
 
+config RK29_WATCHDOG
+       tristate "RK29 watchdog"
+       help
+         Watchdog timer embedded into RK29xx chips. This will reboot your
+         system when the timeout is reached.
+
+config RK29_FEED_DOG_BY_INTE
+       bool "feed watchdog by interrupt"
+       depends on RK29_WATCHDOG
+
+config RK29_WATCHDOG_ATBOOT
+       bool "start watchdog at system boot"
+       depends on RK29_WATCHDOG
+
+config RK29_WATCHDOG_DEFAULT_TIME
+       int "set watchdog time out value (unit second)"
+       depends on RK29_WATCHDOG
+       help
+         the real time out value is two times more than the setting value
+
+config RK29_WATCHDOG_DEBUG
+       bool "enable watchdog debug"
+       depends on RK29_WATCHDOG
+
 config ARM_SP805_WATCHDOG
        tristate "ARM SP805 Watchdog"
        depends on ARM && ARM_AMBA
index a300b948f254f6cd86a971fb44bb5d1d10959465..63ad0297c06f9cfb0e5dc87d77254bb70b7c1c67 100644 (file)
@@ -50,6 +50,7 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
 obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
+obj-$(CONFIG_RK29_WATCHDOG) += rk29_wdt.o
 obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
 obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
 obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
index 06a06c31e031fdc40b4dcac571e76f54374f45a9..990b6d1455755b842027a7c095e836cc324255cc 100644 (file)
@@ -33,6 +33,9 @@
 #include <linux/uaccess.h>\r
 #include <linux/io.h>\r
 #include <asm/mach/map.h>\r
+#ifdef CONFIG_OF\r
+#include <linux/of.h>\r
+#endif\r
 \r
 \r
 /* RK29 registers define */\r
@@ -139,7 +142,7 @@ static void __rk29_wdt_stop(void)
 void rk29_wdt_stop(void)\r
 {\r
        __rk29_wdt_stop();\r
-       clk_disable(wdt_clock);\r
+       clk_disable_unprepare(wdt_clock);\r
 }\r
 \r
 /* timeout unit second */\r
@@ -174,7 +177,7 @@ int rk29_wdt_set_heartbeat(int timeout)
 void rk29_wdt_start(void)\r
 {\r
        unsigned long wtcon;\r
-       clk_enable(wdt_clock);\r
+       clk_prepare_enable(wdt_clock);\r
        rk29_wdt_set_heartbeat(tmr_margin);\r
        wtcon = (RK29_WDT_EN << 0) | (RK29_RESPONSE_MODE << 1) | (RK29_RESET_PULSE << 2);\r
        wdt_writel(wtcon, RK29_WDT_CR);\r
@@ -319,65 +322,69 @@ static irqreturn_t rk29_wdt_irq_handler(int irqno, void *param)
 \r
 /* device interface */\r
 \r
-static int __devinit rk29_wdt_probe(struct platform_device *pdev)\r
+static int rk29_wdt_probe(struct platform_device *pdev)\r
 {\r
        struct resource *res;\r
        struct device *dev;\r
        int started = 0;\r
-       int ret;\r
-       int size;\r
+       int ret, val;\r
 \r
        dev = &pdev->dev;\r
        wdt_dev = &pdev->dev;\r
 \r
        /* get the memory region for the watchdog timer */\r
-\r
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);\r
        if (res == NULL) {\r
                dev_err(dev, "no memory resource specified\n");\r
                return -ENOENT;\r
        }\r
 \r
-       size = (res->end - res->start) + 1;\r
-       wdt_mem = request_mem_region(res->start, size, pdev->name);\r
-       if (wdt_mem == NULL) {\r
-               dev_err(dev, "failed to get memory region\n");\r
-               ret = -ENOENT;\r
-               goto err_req;\r
-       }\r
-\r
-       wdt_base = ioremap(res->start, size);\r
+       wdt_base = devm_request_and_ioremap(&pdev->dev, res);\r
        if (wdt_base == NULL) {\r
                dev_err(dev, "failed to ioremap() region\n");\r
-               ret = -EINVAL;\r
-               goto err_req;\r
+               return -EINVAL;\r
        }\r
-\r
+       \r
+#ifdef CONFIG_OF\r
+       if(!of_property_read_u32(pdev->dev.of_node, "rockchip,atboot", &val))\r
+               tmr_atboot = val;\r
+       else\r
+               tmr_atboot = 0;\r
+\r
+       if(!of_property_read_u32(pdev->dev.of_node, "rockchip,timeout", &val))\r
+               tmr_margin = val;\r
+       else\r
+               tmr_margin = 0;\r
+\r
+       if(!of_property_read_u32(pdev->dev.of_node, "rockchip,debug", &val))\r
+               debug = val;\r
+       else\r
+               debug = 0;\r
        DBG("probe: mapped wdt_base=%p\n", wdt_base);\r
 \r
+       of_property_read_u32(pdev->dev.of_node, "rockchip,irq", &val);\r
+#endif\r
 \r
-#ifdef CONFIG_RK29_FEED_DOG_BY_INTE\r
-\r
-       wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);\r
-       if (wdt_irq == NULL) {\r
-               dev_err(dev, "no irq resource specified\n");\r
-               ret = -ENOENT;\r
-               goto err_map;\r
-       }\r
-\r
-       ret = request_irq(wdt_irq->start, rk29_wdt_irq_handler, 0, pdev->name, pdev);\r
-\r
-       if (ret != 0) {\r
-               dev_err(dev, "failed to install irq (%d)\n", ret);\r
-               goto err_map;\r
-       }\r
-\r
+#ifdef CONFIG_RK29_FEED_DOG_BY_INTE\r
+       val = 1;\r
 #endif\r
+       //printk("atboot:%d, timeout:%ds, debug:%d, irq:%d\n", tmr_atboot, tmr_margin, debug, val);\r
+       \r
+       if(val == 1) {\r
+               wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);\r
+               if (wdt_irq == NULL) {\r
+                       dev_err(dev, "no irq resource specified\n");\r
+                       return -ENOENT;\r
+               }\r
 \r
-       wdt_clock = clk_get(&pdev->dev, "wdt");\r
-       if (IS_ERR(wdt_clock)) {\r
-               wdt_clock = clk_get(&pdev->dev, "pclk_wdt");\r
+               ret = request_irq(wdt_irq->start, rk29_wdt_irq_handler, 0, pdev->name, pdev);\r
+               if (ret != 0) {\r
+                       dev_err(dev, "failed to install irq (%d)\n", ret);\r
+                       return ret;\r
+               }\r
        }\r
+\r
+       wdt_clock = devm_clk_get(&pdev->dev, "pclk_wdt");\r
        if (IS_ERR(wdt_clock)) {\r
                dev_err(dev, "failed to find watchdog clock source\n");\r
                ret = PTR_ERR(wdt_clock);\r
@@ -388,7 +395,7 @@ static int __devinit rk29_wdt_probe(struct platform_device *pdev)
        if (ret) {\r
                dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",\r
                        WATCHDOG_MINOR, ret);\r
-               goto err_clk;\r
+               goto err_irq;\r
        }\r
        if (tmr_atboot && started == 0) {\r
                dev_info(dev, "starting watchdog timer\n");\r
@@ -400,42 +407,21 @@ static int __devinit rk29_wdt_probe(struct platform_device *pdev)
 \r
                rk29_wdt_stop();\r
        }\r
-\r
        return 0;\r
 \r
- err_clk:\r
-       clk_disable(wdt_clock);\r
-       clk_put(wdt_clock);\r
-\r
- err_irq:\r
+err_irq:\r
        free_irq(wdt_irq->start, pdev);\r
-\r
- err_map:\r
-       iounmap(wdt_base);\r
-\r
- err_req:\r
-       release_resource(wdt_mem);\r
-       kfree(wdt_mem);\r
-\r
        return ret;\r
 }\r
 \r
-static int __devexit rk29_wdt_remove(struct platform_device *dev)\r
+static int rk29_wdt_remove(struct platform_device *dev)\r
 {\r
-       release_resource(wdt_mem);\r
-       kfree(wdt_mem);\r
        wdt_mem = NULL;\r
-\r
        free_irq(wdt_irq->start, dev);\r
        wdt_irq = NULL;\r
-\r
-       clk_disable(wdt_clock);\r
-       clk_put(wdt_clock);\r
+       clk_disable_unprepare(wdt_clock);\r
        wdt_clock = NULL;\r
-\r
-       iounmap(wdt_base);\r
        misc_deregister(&rk29_wdt_miscdev);\r
-\r
        return 0;\r
 }\r
 \r
@@ -463,15 +449,23 @@ static int rk29_wdt_resume(struct platform_device *dev)
 #define rk29_wdt_resume  NULL\r
 #endif /* CONFIG_PM */\r
 \r
-\r
+#ifdef CONFIG_OF\r
+static const struct of_device_id of_rk29_wdt_match[] = {\r
+       { .compatible = "rockchip,watch dog" },\r
+       { /* Sentinel */ }\r
+};\r
+#endif\r
 static struct platform_driver rk29_wdt_driver = {\r
        .probe          = rk29_wdt_probe,\r
-       .remove         = __devexit_p(rk29_wdt_remove),\r
+       .remove         = rk29_wdt_remove,\r
        .shutdown       = rk29_wdt_shutdown,\r
        .suspend        = rk29_wdt_suspend,\r
        .resume         = rk29_wdt_resume,\r
        .driver         = {\r
                .owner  = THIS_MODULE,\r
+#ifdef CONFIG_OF\r
+               .of_match_table = of_rk29_wdt_match,\r
+#endif\r
                .name   = "rk29-wdt",\r
        },\r
 };\r