0001
0002
0003
0004
0005 #include <linux/bitops.h>
0006 #include <linux/delay.h>
0007 #include <linux/interrupt.h>
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/of_irq.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/slab.h>
0013 #include <linux/watchdog.h>
0014
0015 #define NPCM_WTCR 0x1C
0016
0017 #define NPCM_WTCLK (BIT(10) | BIT(11))
0018 #define NPCM_WTE BIT(7)
0019 #define NPCM_WTIE BIT(6)
0020 #define NPCM_WTIS (BIT(4) | BIT(5))
0021 #define NPCM_WTIF BIT(3)
0022 #define NPCM_WTRF BIT(2)
0023 #define NPCM_WTRE BIT(1)
0024 #define NPCM_WTR BIT(0)
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 struct npcm_wdt {
0044 struct watchdog_device wdd;
0045 void __iomem *reg;
0046 };
0047
0048 static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
0049 {
0050 return container_of(wdd, struct npcm_wdt, wdd);
0051 }
0052
0053 static int npcm_wdt_ping(struct watchdog_device *wdd)
0054 {
0055 struct npcm_wdt *wdt = to_npcm_wdt(wdd);
0056 u32 val;
0057
0058 val = readl(wdt->reg);
0059 writel(val | NPCM_WTR, wdt->reg);
0060
0061 return 0;
0062 }
0063
0064 static int npcm_wdt_start(struct watchdog_device *wdd)
0065 {
0066 struct npcm_wdt *wdt = to_npcm_wdt(wdd);
0067 u32 val;
0068
0069 if (wdd->timeout < 2)
0070 val = 0x800;
0071 else if (wdd->timeout < 3)
0072 val = 0x420;
0073 else if (wdd->timeout < 6)
0074 val = 0x810;
0075 else if (wdd->timeout < 11)
0076 val = 0x430;
0077 else if (wdd->timeout < 22)
0078 val = 0x820;
0079 else if (wdd->timeout < 44)
0080 val = 0xC00;
0081 else if (wdd->timeout < 87)
0082 val = 0x830;
0083 else if (wdd->timeout < 173)
0084 val = 0xC10;
0085 else if (wdd->timeout < 688)
0086 val = 0xC20;
0087 else
0088 val = 0xC30;
0089
0090 val |= NPCM_WTRE | NPCM_WTE | NPCM_WTR | NPCM_WTIE;
0091
0092 writel(val, wdt->reg);
0093
0094 return 0;
0095 }
0096
0097 static int npcm_wdt_stop(struct watchdog_device *wdd)
0098 {
0099 struct npcm_wdt *wdt = to_npcm_wdt(wdd);
0100
0101 writel(0, wdt->reg);
0102
0103 return 0;
0104 }
0105
0106 static int npcm_wdt_set_timeout(struct watchdog_device *wdd,
0107 unsigned int timeout)
0108 {
0109 if (timeout < 2)
0110 wdd->timeout = 1;
0111 else if (timeout < 3)
0112 wdd->timeout = 2;
0113 else if (timeout < 6)
0114 wdd->timeout = 5;
0115 else if (timeout < 11)
0116 wdd->timeout = 10;
0117 else if (timeout < 22)
0118 wdd->timeout = 21;
0119 else if (timeout < 44)
0120 wdd->timeout = 43;
0121 else if (timeout < 87)
0122 wdd->timeout = 86;
0123 else if (timeout < 173)
0124 wdd->timeout = 172;
0125 else if (timeout < 688)
0126 wdd->timeout = 687;
0127 else
0128 wdd->timeout = 2750;
0129
0130 if (watchdog_active(wdd))
0131 npcm_wdt_start(wdd);
0132
0133 return 0;
0134 }
0135
0136 static irqreturn_t npcm_wdt_interrupt(int irq, void *data)
0137 {
0138 struct npcm_wdt *wdt = data;
0139
0140 watchdog_notify_pretimeout(&wdt->wdd);
0141
0142 return IRQ_HANDLED;
0143 }
0144
0145 static int npcm_wdt_restart(struct watchdog_device *wdd,
0146 unsigned long action, void *data)
0147 {
0148 struct npcm_wdt *wdt = to_npcm_wdt(wdd);
0149
0150 writel(NPCM_WTR | NPCM_WTRE | NPCM_WTE, wdt->reg);
0151 udelay(1000);
0152
0153 return 0;
0154 }
0155
0156 static bool npcm_is_running(struct watchdog_device *wdd)
0157 {
0158 struct npcm_wdt *wdt = to_npcm_wdt(wdd);
0159
0160 return readl(wdt->reg) & NPCM_WTE;
0161 }
0162
0163 static const struct watchdog_info npcm_wdt_info = {
0164 .identity = KBUILD_MODNAME,
0165 .options = WDIOF_SETTIMEOUT
0166 | WDIOF_KEEPALIVEPING
0167 | WDIOF_MAGICCLOSE,
0168 };
0169
0170 static const struct watchdog_ops npcm_wdt_ops = {
0171 .owner = THIS_MODULE,
0172 .start = npcm_wdt_start,
0173 .stop = npcm_wdt_stop,
0174 .ping = npcm_wdt_ping,
0175 .set_timeout = npcm_wdt_set_timeout,
0176 .restart = npcm_wdt_restart,
0177 };
0178
0179 static int npcm_wdt_probe(struct platform_device *pdev)
0180 {
0181 struct device *dev = &pdev->dev;
0182 struct npcm_wdt *wdt;
0183 int irq;
0184 int ret;
0185
0186 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
0187 if (!wdt)
0188 return -ENOMEM;
0189
0190 wdt->reg = devm_platform_ioremap_resource(pdev, 0);
0191 if (IS_ERR(wdt->reg))
0192 return PTR_ERR(wdt->reg);
0193
0194 irq = platform_get_irq(pdev, 0);
0195 if (irq < 0)
0196 return irq;
0197
0198 wdt->wdd.info = &npcm_wdt_info;
0199 wdt->wdd.ops = &npcm_wdt_ops;
0200 wdt->wdd.min_timeout = 1;
0201 wdt->wdd.max_timeout = 2750;
0202 wdt->wdd.parent = dev;
0203
0204 wdt->wdd.timeout = 86;
0205 watchdog_init_timeout(&wdt->wdd, 0, dev);
0206
0207
0208 npcm_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
0209
0210 if (npcm_is_running(&wdt->wdd)) {
0211
0212 npcm_wdt_start(&wdt->wdd);
0213 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
0214 }
0215
0216 ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
0217 wdt);
0218 if (ret)
0219 return ret;
0220
0221 ret = devm_watchdog_register_device(dev, &wdt->wdd);
0222 if (ret)
0223 return ret;
0224
0225 dev_info(dev, "NPCM watchdog driver enabled\n");
0226
0227 return 0;
0228 }
0229
0230 #ifdef CONFIG_OF
0231 static const struct of_device_id npcm_wdt_match[] = {
0232 {.compatible = "nuvoton,wpcm450-wdt"},
0233 {.compatible = "nuvoton,npcm750-wdt"},
0234 {},
0235 };
0236 MODULE_DEVICE_TABLE(of, npcm_wdt_match);
0237 #endif
0238
0239 static struct platform_driver npcm_wdt_driver = {
0240 .probe = npcm_wdt_probe,
0241 .driver = {
0242 .name = "npcm-wdt",
0243 .of_match_table = of_match_ptr(npcm_wdt_match),
0244 },
0245 };
0246 module_platform_driver(npcm_wdt_driver);
0247
0248 MODULE_AUTHOR("Joel Stanley");
0249 MODULE_DESCRIPTION("Watchdog driver for NPCM");
0250 MODULE_LICENSE("GPL v2");