1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Renesas RZ/N1 Watchdog timer. 4 * This is a 12-bit timer driver from a (62.5/16384) MHz clock. It can't even 5 * cope with 2 seconds. 6 * 7 * Copyright 2018 Renesas Electronics Europe Ltd. 8 * 9 * Derived from Ralink RT288x watchdog timer. 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of_address.h> 17 #include <linux/of_irq.h> 18 #include <linux/platform_device.h> 19 #include <linux/reboot.h> 20 #include <linux/watchdog.h> 21 22 #define DEFAULT_TIMEOUT 60 23 24 #define RZN1_WDT_RETRIGGER 0x0 25 #define RZN1_WDT_RETRIGGER_RELOAD_VAL 0 26 #define RZN1_WDT_RETRIGGER_RELOAD_VAL_MASK 0xfff 27 #define RZN1_WDT_RETRIGGER_PRESCALE BIT(12) 28 #define RZN1_WDT_RETRIGGER_ENABLE BIT(13) 29 #define RZN1_WDT_RETRIGGER_WDSI (0x2 << 14) 30 31 #define RZN1_WDT_PRESCALER 16384 32 #define RZN1_WDT_MAX 4095 33 34 struct rzn1_watchdog { 35 struct watchdog_device wdtdev; 36 void __iomem *base; 37 unsigned long clk_rate_khz; 38 }; 39 40 static inline uint32_t max_heart_beat_ms(unsigned long clk_rate_khz) 41 { 42 return (RZN1_WDT_MAX * RZN1_WDT_PRESCALER) / clk_rate_khz; 43 } 44 45 static inline uint32_t compute_reload_value(uint32_t tick_ms, 46 unsigned long clk_rate_khz) 47 { 48 return (tick_ms * clk_rate_khz) / RZN1_WDT_PRESCALER; 49 } 50 51 static int rzn1_wdt_ping(struct watchdog_device *w) 52 { 53 struct rzn1_watchdog *wdt = watchdog_get_drvdata(w); 54 55 /* Any value retrigggers the watchdog */ 56 writel(0, wdt->base + RZN1_WDT_RETRIGGER); 57 58 return 0; 59 } 60 61 static int rzn1_wdt_start(struct watchdog_device *w) 62 { 63 struct rzn1_watchdog *wdt = watchdog_get_drvdata(w); 64 u32 val; 65 66 /* 67 * The hardware allows you to write to this reg only once. 68 * Since this includes the reload value, there is no way to change the 69 * timeout once started. Also note that the WDT clock is half the bus 70 * fabric clock rate, so if the bus fabric clock rate is changed after 71 * the WDT is started, the WDT interval will be wrong. 72 */ 73 val = RZN1_WDT_RETRIGGER_WDSI; 74 val |= RZN1_WDT_RETRIGGER_ENABLE; 75 val |= RZN1_WDT_RETRIGGER_PRESCALE; 76 val |= compute_reload_value(w->max_hw_heartbeat_ms, wdt->clk_rate_khz); 77 writel(val, wdt->base + RZN1_WDT_RETRIGGER); 78 79 return 0; 80 } 81 82 static irqreturn_t rzn1_wdt_irq(int irq, void *_wdt) 83 { 84 pr_crit("RZN1 Watchdog. Initiating system reboot\n"); 85 emergency_restart(); 86 87 return IRQ_HANDLED; 88 } 89 90 static struct watchdog_info rzn1_wdt_info = { 91 .identity = "RZ/N1 Watchdog", 92 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 93 }; 94 95 static const struct watchdog_ops rzn1_wdt_ops = { 96 .owner = THIS_MODULE, 97 .start = rzn1_wdt_start, 98 .ping = rzn1_wdt_ping, 99 }; 100 101 static int rzn1_wdt_probe(struct platform_device *pdev) 102 { 103 struct device *dev = &pdev->dev; 104 struct rzn1_watchdog *wdt; 105 struct device_node *np = dev->of_node; 106 struct clk *clk; 107 unsigned long clk_rate; 108 int ret; 109 int irq; 110 111 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); 112 if (!wdt) 113 return -ENOMEM; 114 115 wdt->base = devm_platform_ioremap_resource(pdev, 0); 116 if (IS_ERR(wdt->base)) 117 return PTR_ERR(wdt->base); 118 119 irq = platform_get_irq(pdev, 0); 120 if (irq < 0) 121 return irq; 122 123 ret = devm_request_irq(dev, irq, rzn1_wdt_irq, 0, 124 np->name, wdt); 125 if (ret) { 126 dev_err(dev, "failed to request irq %d\n", irq); 127 return ret; 128 } 129 130 clk = devm_clk_get_enabled(dev, NULL); 131 if (IS_ERR(clk)) { 132 dev_err(dev, "failed to get the clock\n"); 133 return PTR_ERR(clk); 134 } 135 136 clk_rate = clk_get_rate(clk); 137 if (!clk_rate) { 138 dev_err(dev, "failed to get the clock rate\n"); 139 return -EINVAL; 140 } 141 142 wdt->clk_rate_khz = clk_rate / 1000; 143 wdt->wdtdev.info = &rzn1_wdt_info, 144 wdt->wdtdev.ops = &rzn1_wdt_ops, 145 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS, 146 wdt->wdtdev.parent = dev; 147 /* 148 * The period of the watchdog cannot be changed once set 149 * and is limited to a very short period. 150 * Configure it for a 1s period once and for all, and 151 * rely on the heart-beat provided by the watchdog core 152 * to make this usable by the user-space. 153 */ 154 wdt->wdtdev.max_hw_heartbeat_ms = max_heart_beat_ms(wdt->clk_rate_khz); 155 if (wdt->wdtdev.max_hw_heartbeat_ms > 1000) 156 wdt->wdtdev.max_hw_heartbeat_ms = 1000; 157 158 wdt->wdtdev.timeout = DEFAULT_TIMEOUT; 159 ret = watchdog_init_timeout(&wdt->wdtdev, 0, dev); 160 if (ret) 161 return ret; 162 163 watchdog_set_drvdata(&wdt->wdtdev, wdt); 164 165 return devm_watchdog_register_device(dev, &wdt->wdtdev); 166 } 167 168 169 static const struct of_device_id rzn1_wdt_match[] = { 170 { .compatible = "renesas,rzn1-wdt" }, 171 {}, 172 }; 173 MODULE_DEVICE_TABLE(of, rzn1_wdt_match); 174 175 static struct platform_driver rzn1_wdt_driver = { 176 .probe = rzn1_wdt_probe, 177 .driver = { 178 .name = KBUILD_MODNAME, 179 .of_match_table = rzn1_wdt_match, 180 }, 181 }; 182 183 module_platform_driver(rzn1_wdt_driver); 184 185 MODULE_DESCRIPTION("Renesas RZ/N1 hardware watchdog"); 186 MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>"); 187 MODULE_LICENSE("GPL"); 188