0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/clk.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_irq.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reboot.h>
0020 #include <linux/watchdog.h>
0021
0022 #define DEFAULT_TIMEOUT 60
0023
0024 #define RZN1_WDT_RETRIGGER 0x0
0025 #define RZN1_WDT_RETRIGGER_RELOAD_VAL 0
0026 #define RZN1_WDT_RETRIGGER_RELOAD_VAL_MASK 0xfff
0027 #define RZN1_WDT_RETRIGGER_PRESCALE BIT(12)
0028 #define RZN1_WDT_RETRIGGER_ENABLE BIT(13)
0029 #define RZN1_WDT_RETRIGGER_WDSI (0x2 << 14)
0030
0031 #define RZN1_WDT_PRESCALER 16384
0032 #define RZN1_WDT_MAX 4095
0033
0034 struct rzn1_watchdog {
0035 struct watchdog_device wdtdev;
0036 void __iomem *base;
0037 unsigned long clk_rate_khz;
0038 };
0039
0040 static inline uint32_t max_heart_beat_ms(unsigned long clk_rate_khz)
0041 {
0042 return (RZN1_WDT_MAX * RZN1_WDT_PRESCALER) / clk_rate_khz;
0043 }
0044
0045 static inline uint32_t compute_reload_value(uint32_t tick_ms,
0046 unsigned long clk_rate_khz)
0047 {
0048 return (tick_ms * clk_rate_khz) / RZN1_WDT_PRESCALER;
0049 }
0050
0051 static int rzn1_wdt_ping(struct watchdog_device *w)
0052 {
0053 struct rzn1_watchdog *wdt = watchdog_get_drvdata(w);
0054
0055
0056 writel(0, wdt->base + RZN1_WDT_RETRIGGER);
0057
0058 return 0;
0059 }
0060
0061 static int rzn1_wdt_start(struct watchdog_device *w)
0062 {
0063 struct rzn1_watchdog *wdt = watchdog_get_drvdata(w);
0064 u32 val;
0065
0066
0067
0068
0069
0070
0071
0072
0073 val = RZN1_WDT_RETRIGGER_WDSI;
0074 val |= RZN1_WDT_RETRIGGER_ENABLE;
0075 val |= RZN1_WDT_RETRIGGER_PRESCALE;
0076 val |= compute_reload_value(w->max_hw_heartbeat_ms, wdt->clk_rate_khz);
0077 writel(val, wdt->base + RZN1_WDT_RETRIGGER);
0078
0079 return 0;
0080 }
0081
0082 static irqreturn_t rzn1_wdt_irq(int irq, void *_wdt)
0083 {
0084 pr_crit("RZN1 Watchdog. Initiating system reboot\n");
0085 emergency_restart();
0086
0087 return IRQ_HANDLED;
0088 }
0089
0090 static struct watchdog_info rzn1_wdt_info = {
0091 .identity = "RZ/N1 Watchdog",
0092 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0093 };
0094
0095 static const struct watchdog_ops rzn1_wdt_ops = {
0096 .owner = THIS_MODULE,
0097 .start = rzn1_wdt_start,
0098 .ping = rzn1_wdt_ping,
0099 };
0100
0101 static void rzn1_wdt_clk_disable_unprepare(void *data)
0102 {
0103 clk_disable_unprepare(data);
0104 }
0105
0106 static int rzn1_wdt_probe(struct platform_device *pdev)
0107 {
0108 struct device *dev = &pdev->dev;
0109 struct rzn1_watchdog *wdt;
0110 struct device_node *np = dev->of_node;
0111 struct clk *clk;
0112 unsigned long clk_rate;
0113 int ret;
0114 int irq;
0115
0116 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
0117 if (!wdt)
0118 return -ENOMEM;
0119
0120 wdt->base = devm_platform_ioremap_resource(pdev, 0);
0121 if (IS_ERR(wdt->base))
0122 return PTR_ERR(wdt->base);
0123
0124 irq = platform_get_irq(pdev, 0);
0125 if (irq < 0)
0126 return irq;
0127
0128 ret = devm_request_irq(dev, irq, rzn1_wdt_irq, 0,
0129 np->name, wdt);
0130 if (ret) {
0131 dev_err(dev, "failed to request irq %d\n", irq);
0132 return ret;
0133 }
0134
0135 clk = devm_clk_get(dev, NULL);
0136 if (IS_ERR(clk)) {
0137 dev_err(dev, "failed to get the clock\n");
0138 return PTR_ERR(clk);
0139 }
0140
0141 ret = clk_prepare_enable(clk);
0142 if (ret) {
0143 dev_err(dev, "failed to prepare/enable the clock\n");
0144 return ret;
0145 }
0146
0147 ret = devm_add_action_or_reset(dev, rzn1_wdt_clk_disable_unprepare,
0148 clk);
0149 if (ret)
0150 return ret;
0151
0152 clk_rate = clk_get_rate(clk);
0153 if (!clk_rate) {
0154 dev_err(dev, "failed to get the clock rate\n");
0155 return -EINVAL;
0156 }
0157
0158 wdt->clk_rate_khz = clk_rate / 1000;
0159 wdt->wdtdev.info = &rzn1_wdt_info,
0160 wdt->wdtdev.ops = &rzn1_wdt_ops,
0161 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS,
0162 wdt->wdtdev.parent = dev;
0163
0164
0165
0166
0167
0168
0169
0170 wdt->wdtdev.max_hw_heartbeat_ms = max_heart_beat_ms(wdt->clk_rate_khz);
0171 if (wdt->wdtdev.max_hw_heartbeat_ms > 1000)
0172 wdt->wdtdev.max_hw_heartbeat_ms = 1000;
0173
0174 wdt->wdtdev.timeout = DEFAULT_TIMEOUT;
0175 ret = watchdog_init_timeout(&wdt->wdtdev, 0, dev);
0176 if (ret)
0177 return ret;
0178
0179 watchdog_set_drvdata(&wdt->wdtdev, wdt);
0180
0181 return devm_watchdog_register_device(dev, &wdt->wdtdev);
0182 }
0183
0184
0185 static const struct of_device_id rzn1_wdt_match[] = {
0186 { .compatible = "renesas,rzn1-wdt" },
0187 {},
0188 };
0189 MODULE_DEVICE_TABLE(of, rzn1_wdt_match);
0190
0191 static struct platform_driver rzn1_wdt_driver = {
0192 .probe = rzn1_wdt_probe,
0193 .driver = {
0194 .name = KBUILD_MODNAME,
0195 .of_match_table = rzn1_wdt_match,
0196 },
0197 };
0198
0199 module_platform_driver(rzn1_wdt_driver);
0200
0201 MODULE_DESCRIPTION("Renesas RZ/N1 hardware watchdog");
0202 MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>");
0203 MODULE_LICENSE("GPL");