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 198 if (rwdt_blacklisted(dev)) 199 return -ENODEV; 200 201 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 202 if (!priv) 203 return -ENOMEM; 204 205 priv->base = devm_platform_ioremap_resource(pdev, 0); 206 if (IS_ERR(priv->base)) 207 return PTR_ERR(priv->base); 208 209 clk = devm_clk_get(dev, NULL); 210 if (IS_ERR(clk)) 211 return PTR_ERR(clk); 212 213 pm_runtime_enable(dev); 214 pm_runtime_get_sync(dev); 215 priv->clk_rate = clk_get_rate(clk); 216 priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) & 217 RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0; 218 pm_runtime_put(dev); 219 220 if (!priv->clk_rate) { 221 ret = -ENOENT; 222 goto out_pm_disable; 223 } 224 225 for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { 226 clks_per_sec = priv->clk_rate / clk_divs[i]; 227 if (clks_per_sec && clks_per_sec < 65536) { 228 priv->cks = i; 229 break; 230 } 231 } 232 233 if (i < 0) { 234 dev_err(dev, "Can't find suitable clock divider\n"); 235 ret = -ERANGE; 236 goto out_pm_disable; 237 } 238 239 priv->wdev.info = &rwdt_ident; 240 priv->wdev.ops = &rwdt_ops; 241 priv->wdev.parent = dev; 242 priv->wdev.min_timeout = 1; 243 priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); 244 priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); 245 246 platform_set_drvdata(pdev, priv); 247 watchdog_set_drvdata(&priv->wdev, priv); 248 watchdog_set_nowayout(&priv->wdev, nowayout); 249 watchdog_set_restart_priority(&priv->wdev, 0); 250 watchdog_stop_on_unregister(&priv->wdev); 251 252 /* This overrides the default timeout only if DT configuration was found */ 253 watchdog_init_timeout(&priv->wdev, 0, dev); 254 255 ret = watchdog_register_device(&priv->wdev); 256 if (ret < 0) 257 goto out_pm_disable; 258 259 return 0; 260 261 out_pm_disable: 262 pm_runtime_disable(dev); 263 return ret; 264 } 265 266 static int rwdt_remove(struct platform_device *pdev) 267 { 268 struct rwdt_priv *priv = platform_get_drvdata(pdev); 269 270 watchdog_unregister_device(&priv->wdev); 271 pm_runtime_disable(&pdev->dev); 272 273 return 0; 274 } 275 276 static int __maybe_unused rwdt_suspend(struct device *dev) 277 { 278 struct rwdt_priv *priv = dev_get_drvdata(dev); 279 280 if (watchdog_active(&priv->wdev)) 281 rwdt_stop(&priv->wdev); 282 283 return 0; 284 } 285 286 static int __maybe_unused rwdt_resume(struct device *dev) 287 { 288 struct rwdt_priv *priv = dev_get_drvdata(dev); 289 290 if (watchdog_active(&priv->wdev)) 291 rwdt_start(&priv->wdev); 292 293 return 0; 294 } 295 296 static SIMPLE_DEV_PM_OPS(rwdt_pm_ops, rwdt_suspend, rwdt_resume); 297 298 static const struct of_device_id rwdt_ids[] = { 299 { .compatible = "renesas,rcar-gen2-wdt", }, 300 { .compatible = "renesas,rcar-gen3-wdt", }, 301 { /* sentinel */ } 302 }; 303 MODULE_DEVICE_TABLE(of, rwdt_ids); 304 305 static struct platform_driver rwdt_driver = { 306 .driver = { 307 .name = "renesas_wdt", 308 .of_match_table = rwdt_ids, 309 .pm = &rwdt_pm_ops, 310 }, 311 .probe = rwdt_probe, 312 .remove = rwdt_remove, 313 }; 314 module_platform_driver(rwdt_driver); 315 316 MODULE_DESCRIPTION("Renesas WDT Watchdog Driver"); 317 MODULE_LICENSE("GPL v2"); 318 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); 319