0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/clk.h>
0022 #include <linux/delay.h>
0023 #include <linux/init.h>
0024 #include <linux/interrupt.h>
0025 #include <linux/io.h>
0026 #include <linux/kernel.h>
0027 #include <linux/module.h>
0028 #include <linux/moduleparam.h>
0029 #include <linux/of_address.h>
0030 #include <linux/platform_device.h>
0031 #include <linux/regmap.h>
0032 #include <linux/watchdog.h>
0033
0034 #define DRIVER_NAME "imx2-wdt"
0035
0036 #define IMX2_WDT_WCR 0x00
0037 #define IMX2_WDT_WCR_WT (0xFF << 8)
0038 #define IMX2_WDT_WCR_WDA BIT(5)
0039 #define IMX2_WDT_WCR_SRS BIT(4)
0040 #define IMX2_WDT_WCR_WRE BIT(3)
0041 #define IMX2_WDT_WCR_WDE BIT(2)
0042 #define IMX2_WDT_WCR_WDZST BIT(0)
0043
0044 #define IMX2_WDT_WSR 0x02
0045 #define IMX2_WDT_SEQ1 0x5555
0046 #define IMX2_WDT_SEQ2 0xAAAA
0047
0048 #define IMX2_WDT_WRSR 0x04
0049 #define IMX2_WDT_WRSR_TOUT BIT(1)
0050
0051 #define IMX2_WDT_WICR 0x06
0052 #define IMX2_WDT_WICR_WIE BIT(15)
0053 #define IMX2_WDT_WICR_WTIS BIT(14)
0054 #define IMX2_WDT_WICR_WICT 0xFF
0055
0056 #define IMX2_WDT_WMCR 0x08
0057
0058 #define IMX2_WDT_MAX_TIME 128U
0059 #define IMX2_WDT_DEFAULT_TIME 60
0060
0061 #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8)
0062
0063 struct imx2_wdt_device {
0064 struct clk *clk;
0065 struct regmap *regmap;
0066 struct watchdog_device wdog;
0067 bool ext_reset;
0068 bool clk_is_on;
0069 bool no_ping;
0070 };
0071
0072 static bool nowayout = WATCHDOG_NOWAYOUT;
0073 module_param(nowayout, bool, 0);
0074 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
0075 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0076
0077 static unsigned timeout;
0078 module_param(timeout, uint, 0);
0079 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
0080 __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")");
0081
0082 static const struct watchdog_info imx2_wdt_info = {
0083 .identity = "imx2+ watchdog",
0084 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
0085 };
0086
0087 static const struct watchdog_info imx2_wdt_pretimeout_info = {
0088 .identity = "imx2+ watchdog",
0089 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
0090 WDIOF_PRETIMEOUT,
0091 };
0092
0093 static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
0094 void *data)
0095 {
0096 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0097 unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
0098
0099
0100 if (wdev->ext_reset)
0101 wcr_enable |= IMX2_WDT_WCR_SRS;
0102 else
0103 wcr_enable |= IMX2_WDT_WCR_WDA;
0104
0105
0106 regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
0107
0108
0109
0110
0111
0112
0113
0114 regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
0115 regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
0116
0117
0118 mdelay(500);
0119
0120 return 0;
0121 }
0122
0123 static inline void imx2_wdt_setup(struct watchdog_device *wdog)
0124 {
0125 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0126 u32 val;
0127
0128 regmap_read(wdev->regmap, IMX2_WDT_WCR, &val);
0129
0130
0131 val |= IMX2_WDT_WCR_WDZST;
0132
0133 val &= ~IMX2_WDT_WCR_WT;
0134
0135 if (!wdev->ext_reset)
0136 val &= ~IMX2_WDT_WCR_WRE;
0137
0138 else
0139 val |= IMX2_WDT_WCR_WRE;
0140
0141 val &= ~IMX2_WDT_WCR_WDE;
0142
0143 val |= WDOG_SEC_TO_COUNT(wdog->timeout);
0144
0145 regmap_write(wdev->regmap, IMX2_WDT_WCR, val);
0146
0147
0148 val |= IMX2_WDT_WCR_WDE;
0149 regmap_write(wdev->regmap, IMX2_WDT_WCR, val);
0150 }
0151
0152 static inline bool imx2_wdt_is_running(struct imx2_wdt_device *wdev)
0153 {
0154 u32 val;
0155
0156 regmap_read(wdev->regmap, IMX2_WDT_WCR, &val);
0157
0158 return val & IMX2_WDT_WCR_WDE;
0159 }
0160
0161 static int imx2_wdt_ping(struct watchdog_device *wdog)
0162 {
0163 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0164
0165 if (!wdev->clk_is_on)
0166 return 0;
0167
0168 regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ1);
0169 regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ2);
0170 return 0;
0171 }
0172
0173 static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
0174 unsigned int new_timeout)
0175 {
0176 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0177
0178 regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
0179 WDOG_SEC_TO_COUNT(new_timeout));
0180 }
0181
0182 static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
0183 unsigned int new_timeout)
0184 {
0185 unsigned int actual;
0186
0187 actual = min(new_timeout, IMX2_WDT_MAX_TIME);
0188 __imx2_wdt_set_timeout(wdog, actual);
0189 wdog->timeout = new_timeout;
0190 return 0;
0191 }
0192
0193 static int imx2_wdt_set_pretimeout(struct watchdog_device *wdog,
0194 unsigned int new_pretimeout)
0195 {
0196 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0197
0198 if (new_pretimeout >= IMX2_WDT_MAX_TIME)
0199 return -EINVAL;
0200
0201 wdog->pretimeout = new_pretimeout;
0202
0203 regmap_update_bits(wdev->regmap, IMX2_WDT_WICR,
0204 IMX2_WDT_WICR_WIE | IMX2_WDT_WICR_WICT,
0205 IMX2_WDT_WICR_WIE | (new_pretimeout << 1));
0206 return 0;
0207 }
0208
0209 static irqreturn_t imx2_wdt_isr(int irq, void *wdog_arg)
0210 {
0211 struct watchdog_device *wdog = wdog_arg;
0212 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0213
0214 regmap_write_bits(wdev->regmap, IMX2_WDT_WICR,
0215 IMX2_WDT_WICR_WTIS, IMX2_WDT_WICR_WTIS);
0216
0217 watchdog_notify_pretimeout(wdog);
0218
0219 return IRQ_HANDLED;
0220 }
0221
0222 static int imx2_wdt_start(struct watchdog_device *wdog)
0223 {
0224 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0225
0226 if (imx2_wdt_is_running(wdev))
0227 imx2_wdt_set_timeout(wdog, wdog->timeout);
0228 else
0229 imx2_wdt_setup(wdog);
0230
0231 set_bit(WDOG_HW_RUNNING, &wdog->status);
0232
0233 return imx2_wdt_ping(wdog);
0234 }
0235
0236 static const struct watchdog_ops imx2_wdt_ops = {
0237 .owner = THIS_MODULE,
0238 .start = imx2_wdt_start,
0239 .ping = imx2_wdt_ping,
0240 .set_timeout = imx2_wdt_set_timeout,
0241 .set_pretimeout = imx2_wdt_set_pretimeout,
0242 .restart = imx2_wdt_restart,
0243 };
0244
0245 static const struct regmap_config imx2_wdt_regmap_config = {
0246 .reg_bits = 16,
0247 .reg_stride = 2,
0248 .val_bits = 16,
0249 .max_register = 0x8,
0250 };
0251
0252 static void imx2_wdt_action(void *data)
0253 {
0254 clk_disable_unprepare(data);
0255 }
0256
0257 static int __init imx2_wdt_probe(struct platform_device *pdev)
0258 {
0259 struct device *dev = &pdev->dev;
0260 struct imx2_wdt_device *wdev;
0261 struct watchdog_device *wdog;
0262 void __iomem *base;
0263 int ret;
0264 u32 val;
0265
0266 wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL);
0267 if (!wdev)
0268 return -ENOMEM;
0269
0270 base = devm_platform_ioremap_resource(pdev, 0);
0271 if (IS_ERR(base))
0272 return PTR_ERR(base);
0273
0274 wdev->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
0275 &imx2_wdt_regmap_config);
0276 if (IS_ERR(wdev->regmap)) {
0277 dev_err(dev, "regmap init failed\n");
0278 return PTR_ERR(wdev->regmap);
0279 }
0280
0281 wdev->clk = devm_clk_get(dev, NULL);
0282 if (IS_ERR(wdev->clk)) {
0283 dev_err(dev, "can't get Watchdog clock\n");
0284 return PTR_ERR(wdev->clk);
0285 }
0286
0287 wdog = &wdev->wdog;
0288 wdog->info = &imx2_wdt_info;
0289 wdog->ops = &imx2_wdt_ops;
0290 wdog->min_timeout = 1;
0291 wdog->timeout = IMX2_WDT_DEFAULT_TIME;
0292 wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
0293 wdog->parent = dev;
0294
0295 ret = platform_get_irq(pdev, 0);
0296 if (ret > 0)
0297 if (!devm_request_irq(dev, ret, imx2_wdt_isr, 0,
0298 dev_name(dev), wdog))
0299 wdog->info = &imx2_wdt_pretimeout_info;
0300
0301 ret = clk_prepare_enable(wdev->clk);
0302 if (ret)
0303 return ret;
0304
0305 ret = devm_add_action_or_reset(dev, imx2_wdt_action, wdev->clk);
0306 if (ret)
0307 return ret;
0308
0309 wdev->clk_is_on = true;
0310
0311 regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val);
0312 wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
0313
0314 wdev->ext_reset = of_property_read_bool(dev->of_node,
0315 "fsl,ext-reset-output");
0316
0317
0318
0319
0320 wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
0321 platform_set_drvdata(pdev, wdog);
0322 watchdog_set_drvdata(wdog, wdev);
0323 watchdog_set_nowayout(wdog, nowayout);
0324 watchdog_set_restart_priority(wdog, 128);
0325 watchdog_init_timeout(wdog, timeout, dev);
0326 if (wdev->no_ping)
0327 watchdog_stop_ping_on_suspend(wdog);
0328
0329 if (imx2_wdt_is_running(wdev)) {
0330 imx2_wdt_set_timeout(wdog, wdog->timeout);
0331 set_bit(WDOG_HW_RUNNING, &wdog->status);
0332 }
0333
0334
0335
0336
0337
0338
0339 regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
0340
0341 return devm_watchdog_register_device(dev, wdog);
0342 }
0343
0344 static void imx2_wdt_shutdown(struct platform_device *pdev)
0345 {
0346 struct watchdog_device *wdog = platform_get_drvdata(pdev);
0347 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0348
0349 if (imx2_wdt_is_running(wdev)) {
0350
0351
0352
0353
0354 imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
0355 imx2_wdt_ping(wdog);
0356 dev_crit(&pdev->dev, "Device shutdown: Expect reboot!\n");
0357 }
0358 }
0359
0360
0361 static int __maybe_unused imx2_wdt_suspend(struct device *dev)
0362 {
0363 struct watchdog_device *wdog = dev_get_drvdata(dev);
0364 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0365
0366
0367 if (imx2_wdt_is_running(wdev)) {
0368
0369
0370
0371
0372 __imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
0373 imx2_wdt_ping(wdog);
0374 }
0375
0376 if (wdev->no_ping) {
0377 clk_disable_unprepare(wdev->clk);
0378
0379 wdev->clk_is_on = false;
0380 }
0381
0382 return 0;
0383 }
0384
0385
0386 static int __maybe_unused imx2_wdt_resume(struct device *dev)
0387 {
0388 struct watchdog_device *wdog = dev_get_drvdata(dev);
0389 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
0390 int ret;
0391
0392 if (wdev->no_ping) {
0393 ret = clk_prepare_enable(wdev->clk);
0394
0395 if (ret)
0396 return ret;
0397
0398 wdev->clk_is_on = true;
0399 }
0400
0401 if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
0402
0403
0404
0405
0406
0407 imx2_wdt_setup(wdog);
0408 }
0409 if (imx2_wdt_is_running(wdev)) {
0410 imx2_wdt_set_timeout(wdog, wdog->timeout);
0411 imx2_wdt_ping(wdog);
0412 }
0413
0414 return 0;
0415 }
0416
0417 static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
0418 imx2_wdt_resume);
0419
0420 static const struct of_device_id imx2_wdt_dt_ids[] = {
0421 { .compatible = "fsl,imx21-wdt", },
0422 { .compatible = "fsl,imx7d-wdt", },
0423 { }
0424 };
0425 MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
0426
0427 static struct platform_driver imx2_wdt_driver = {
0428 .shutdown = imx2_wdt_shutdown,
0429 .driver = {
0430 .name = DRIVER_NAME,
0431 .pm = &imx2_wdt_pm_ops,
0432 .of_match_table = imx2_wdt_dt_ids,
0433 },
0434 };
0435
0436 module_platform_driver_probe(imx2_wdt_driver, imx2_wdt_probe);
0437
0438 MODULE_AUTHOR("Wolfram Sang");
0439 MODULE_DESCRIPTION("Watchdog driver for IMX2 and later");
0440 MODULE_LICENSE("GPL v2");
0441 MODULE_ALIAS("platform:" DRIVER_NAME);