1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Watchdog driver for Renesas WDT watchdog 4 * 5 * Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> 6 * Copyright (C) 2015-17 Renesas Electronics Corporation 7 */ 8 #include <linux/bitops.h> 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/smp.h> 18 #include <linux/sys_soc.h> 19 #include <linux/watchdog.h> 20 21 #define RWTCNT 0 22 #define RWTCSRA 4 23 #define RWTCSRA_WOVF BIT(4) 24 #define RWTCSRA_WRFLG BIT(5) 25 #define RWTCSRA_TME BIT(7) 26 #define RWTCSRB 8 27 28 #define RWDT_DEFAULT_TIMEOUT 60U 29 30 /* 31 * In probe, clk_rate is checked to be not more than 16 bit * biggest clock 32 * divider (12 bits). d is only a factor to fully utilize the WDT counter and 33 * will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits. 34 */ 35 #define MUL_BY_CLKS_PER_SEC(p, d) \ 36 DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks]) 37 38 /* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */ 39 #define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate) 40 41 static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; 42 43 static bool nowayout = WATCHDOG_NOWAYOUT; 44 module_param(nowayout, bool, 0); 45 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 46 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 47 48 struct rwdt_priv { 49 void __iomem *base; 50 struct watchdog_device wdev; 51 unsigned long clk_rate; 52 u8 cks; 53 }; 54 55 static void rwdt_write(struct rwdt_priv *priv, u32 val, unsigned int reg) 56 { 57 if (reg == RWTCNT) 58 val |= 0x5a5a0000; 59 else 60 val |= 0xa5a5a500; 61 62 writel_relaxed(val, priv->base + reg); 63 } 64 65 static int rwdt_init_timeout(struct watchdog_device *wdev) 66 { 67 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 68 69 rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), RWTCNT); 70 71 return 0; 72 } 73 74 static void rwdt_wait_cycles(struct rwdt_priv *priv, unsigned int cycles) 75 { 76 unsigned int delay; 77 78 delay = DIV_ROUND_UP(cycles * 1000000, priv->clk_rate); 79 80 usleep_range(delay, 2 * delay); 81 } 82 83 static int rwdt_start(struct watchdog_device *wdev) 84 { 85 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 86 u8 val; 87 88 pm_runtime_get_sync(wdev->parent); 89 90 /* Stop the timer before we modify any register */ 91 val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME; 92 rwdt_write(priv, val, RWTCSRA); 93 /* Delay 2 cycles before setting watchdog counter */ 94 rwdt_wait_cycles(priv, 2); 95 96 rwdt_init_timeout(wdev); 97 rwdt_write(priv, priv->cks, RWTCSRA); 98 rwdt_write(priv, 0, RWTCSRB); 99 100 while (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WRFLG) 101 cpu_relax(); 102 103 rwdt_write(priv, priv->cks | RWTCSRA_TME, RWTCSRA); 104 105 return 0; 106 } 107 108 static int rwdt_stop(struct watchdog_device *wdev) 109 { 110 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 111 112 rwdt_write(priv, priv->cks, RWTCSRA); 113 /* Delay 3 cycles before disabling module clock */ 114 rwdt_wait_cycles(priv, 3); 115 pm_runtime_put(wdev->parent); 116 117 return 0; 118 } 119 120 static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev) 121 { 122 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 123 u16 val = readw_relaxed(priv->base + RWTCNT); 124 125 return DIV_BY_CLKS_PER_SEC(priv, 65536 - val); 126 } 127 128 static int rwdt_restart(struct watchdog_device *wdev, unsigned long action, 129 void *data) 130 { 131 struct rwdt_priv *priv = watchdog_get_drvdata(wdev); 132 133 rwdt_start(wdev); 134 rwdt_write(priv, 0xffff, RWTCNT); 135 return 0; 136 } 137 138 static const struct watchdog_info rwdt_ident = { 139 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 140 WDIOF_CARDRESET, 141 .identity = "Renesas WDT Watchdog", 142 }; 143 144 static const struct watchdog_ops rwdt_ops = { 145 .owner = THIS_MODULE, 146 .start = rwdt_start, 147 .stop = rwdt_stop, 148 .ping = rwdt_init_timeout, 149 .get_timeleft = rwdt_get_timeleft, 150 .restart = rwdt_restart, 151 }; 152 153 #if defined(CONFIG_ARCH_RCAR_GEN2) && defined(CONFIG_SMP) 154 /* 155 * Watchdog-reset integration is broken on early revisions of R-Car Gen2 SoCs 156 */ 157 static const struct soc_device_attribute rwdt_quirks_match[] = { 158 { 159 .soc_id = "r8a7790", 160 .revision = "ES1.*", 161 .data = (void *)1, /* needs single CPU */ 162 }, { 163 .soc_id = "r8a7791", 164 .revision = "ES1.*", 165 .data = (void *)1, /* needs single CPU */ 166 }, { 167 .soc_id = "r8a7792", 168 .data = (void *)0, /* needs SMP disabled */ 169 }, 170 { /* sentinel */ } 171 }; 172 173 static bool rwdt_blacklisted(struct device *dev) 174 { 175 const struct soc_device_attribute *attr; 176 177 attr = soc_device_match(rwdt_quirks_match); 178 if (attr && setup_max_cpus > (uintptr_t)attr->data) { 179 dev_info(dev, "Watchdog blacklisted on %s %s\n", attr->soc_id, 180 attr->revision); 181 return true; 182 } 183 184 return false; 185 } 186 #else /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ 187 static inline bool rwdt_blacklisted(struct device *dev) { return false; } 188 #endif /* !CONFIG_ARCH_RCAR_GEN2 || !CONFIG_SMP */ 189 190 static int rwdt_probe(struct platform_device *pdev) 191 { 192 struct device *dev = &pdev->dev; 193 struct rwdt_priv *priv; 194 struct clk *clk; 195 unsigned long clks_per_sec; 196 int ret, i; 197 u8 csra; 198 199 if (rwdt_blacklisted(dev)) 200 return -ENODEV; 201 202 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 203 if (!priv) 204 return -ENOMEM; 205 206 priv->base = devm_platform_ioremap_resource(pdev, 0); 207 if (IS_ERR(priv->base)) 208 return PTR_ERR(priv->base); 209 210 clk = devm_clk_get(dev, NULL); 211 if (IS_ERR(clk)) 212 return PTR_ERR(clk); 213 214 pm_runtime_enable(dev); 215 pm_runtime_get_sync(dev); 216 priv->clk_rate = clk_get_rate(clk); 217 csra = readb_relaxed(priv->base + RWTCSRA); 218 priv->wdev.bootstatus = csra & RWTCSRA_WOVF ? WDIOF_CARDRESET : 0; 219 pm_runtime_put(dev); 220 221 if (!priv->clk_rate) { 222 ret = -ENOENT; 223 goto out_pm_disable; 224 } 225 226 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { 227 clks_per_sec = priv->clk_rate / clk_divs[i]; 228 if (clks_per_sec && clks_per_sec < 65536) { 229 priv->cks = i; 230 break; 231 } 232 } 233 234 if (i < 0) { 235 dev_err(dev, "Can't find suitable clock divider\n"); 236 ret = -ERANGE; 237 goto out_pm_disable; 238 } 239 240 priv->wdev.info = &rwdt_ident; 241 priv->wdev.ops = &rwdt_ops; 242 priv->wdev.parent = dev; 243 priv->wdev.min_timeout = 1; 244 priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); 245 priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); 246 247 platform_set_drvdata(pdev, priv); 248 watchdog_set_drvdata(&priv->wdev, priv); 249 watchdog_set_nowayout(&priv->wdev, nowayout); 250 watchdog_set_restart_priority(&priv->wdev, 0); 251 watchdog_stop_on_unregister(&priv->wdev); 252 253 /* This overrides the default timeout only if DT configuration was found */ 254 watchdog_init_timeout(&priv->wdev, 0, dev); 255 256 /* Check if FW enabled the watchdog */ 257 if (csra & RWTCSRA_TME) { 258 /* Ensure properly initialized dividers */ 259 rwdt_start(&priv->wdev); 260 set_bit(WDOG_HW_RUNNING, &priv->wdev.status); 261 } 262 263 ret = watchdog_register_device(&priv->wdev); 264 if (ret < 0) 265 goto out_pm_disable; 266 267 return 0; 268 269 out_pm_disable: 270 pm_runtime_disable(dev); 271 return ret; 272 } 273 274 static int rwdt_remove(struct platform_device *pdev) 275 { 276 struct rwdt_priv *priv = platform_get_drvdata(pdev); 277 278 watchdog_unregister_device(&priv->wdev); 279 pm_runtime_disable(&pdev->dev); 280 281 return 0; 282 } 283 284 static int __maybe_unused rwdt_suspend(struct device *dev) 285 { 286 struct rwdt_priv *priv = dev_get_drvdata(dev); 287 288 if (watchdog_active(&priv->wdev)) 289 rwdt_stop(&priv->wdev); 290 291 return 0; 292 } 293 294 static int __maybe_unused rwdt_resume(struct device *dev) 295 { 296 struct rwdt_priv *priv = dev_get_drvdata(dev); 297 298 if (watchdog_active(&priv->wdev)) 299 rwdt_start(&priv->wdev); 300 301 return 0; 302 } 303 304 static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume); 305 306 static const struct of_device_id rwdt_ids[] = { 307 { .compatible = "renesas,rcar-gen2-wdt", }, 308 { .compatible = "renesas,rcar-gen3-wdt", }, 309 { /* sentinel */ } 310 }; 311 MODULE_DEVICE_TABLE(of, rwdt_ids); 312 313 static struct platform_driver rwdt_driver = { 314 .driver = { 315 .name = "renesas_wdt", 316 .of_match_table = rwdt_ids, 317 .pm = &rwdt_pm_ops, 318 }, 319 .probe = rwdt_probe, 320 .remove = rwdt_remove, 321 }; 322 module_platform_driver(rwdt_driver); 323 324 MODULE_DESCRIPTION("Renesas WDT Watchdog Driver"); 325 MODULE_LICENSE("GPL v2"); 326 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); 327