1 /* 2 * Copyright 2016 IBM Corporation 3 * 4 * Joel Stanley <joel@jms.id.au> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/delay.h> 13 #include <linux/io.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/watchdog.h> 19 20 struct aspeed_wdt { 21 struct watchdog_device wdd; 22 void __iomem *base; 23 u32 ctrl; 24 }; 25 26 static const struct of_device_id aspeed_wdt_of_table[] = { 27 { .compatible = "aspeed,ast2400-wdt" }, 28 { .compatible = "aspeed,ast2500-wdt" }, 29 { }, 30 }; 31 MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table); 32 33 #define WDT_STATUS 0x00 34 #define WDT_RELOAD_VALUE 0x04 35 #define WDT_RESTART 0x08 36 #define WDT_CTRL 0x0C 37 #define WDT_CTRL_RESET_MODE_SOC (0x00 << 5) 38 #define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5) 39 #define WDT_CTRL_1MHZ_CLK BIT(4) 40 #define WDT_CTRL_WDT_EXT BIT(3) 41 #define WDT_CTRL_WDT_INTR BIT(2) 42 #define WDT_CTRL_RESET_SYSTEM BIT(1) 43 #define WDT_CTRL_ENABLE BIT(0) 44 45 #define WDT_RESTART_MAGIC 0x4755 46 47 /* 32 bits at 1MHz, in milliseconds */ 48 #define WDT_MAX_TIMEOUT_MS 4294967 49 #define WDT_DEFAULT_TIMEOUT 30 50 #define WDT_RATE_1MHZ 1000000 51 52 static struct aspeed_wdt *to_aspeed_wdt(struct watchdog_device *wdd) 53 { 54 return container_of(wdd, struct aspeed_wdt, wdd); 55 } 56 57 static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count) 58 { 59 wdt->ctrl |= WDT_CTRL_ENABLE; 60 61 writel(0, wdt->base + WDT_CTRL); 62 writel(count, wdt->base + WDT_RELOAD_VALUE); 63 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 64 writel(wdt->ctrl, wdt->base + WDT_CTRL); 65 } 66 67 static int aspeed_wdt_start(struct watchdog_device *wdd) 68 { 69 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 70 71 aspeed_wdt_enable(wdt, wdd->timeout * WDT_RATE_1MHZ); 72 73 return 0; 74 } 75 76 static int aspeed_wdt_stop(struct watchdog_device *wdd) 77 { 78 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 79 80 wdt->ctrl &= ~WDT_CTRL_ENABLE; 81 writel(wdt->ctrl, wdt->base + WDT_CTRL); 82 83 return 0; 84 } 85 86 static int aspeed_wdt_ping(struct watchdog_device *wdd) 87 { 88 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 89 90 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 91 92 return 0; 93 } 94 95 static int aspeed_wdt_set_timeout(struct watchdog_device *wdd, 96 unsigned int timeout) 97 { 98 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 99 u32 actual; 100 101 wdd->timeout = timeout; 102 103 actual = min(timeout, wdd->max_hw_heartbeat_ms * 1000); 104 105 writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE); 106 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); 107 108 return 0; 109 } 110 111 static int aspeed_wdt_restart(struct watchdog_device *wdd, 112 unsigned long action, void *data) 113 { 114 struct aspeed_wdt *wdt = to_aspeed_wdt(wdd); 115 116 aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000); 117 118 mdelay(1000); 119 120 return 0; 121 } 122 123 static const struct watchdog_ops aspeed_wdt_ops = { 124 .start = aspeed_wdt_start, 125 .stop = aspeed_wdt_stop, 126 .ping = aspeed_wdt_ping, 127 .set_timeout = aspeed_wdt_set_timeout, 128 .restart = aspeed_wdt_restart, 129 .owner = THIS_MODULE, 130 }; 131 132 static const struct watchdog_info aspeed_wdt_info = { 133 .options = WDIOF_KEEPALIVEPING 134 | WDIOF_MAGICCLOSE 135 | WDIOF_SETTIMEOUT, 136 .identity = KBUILD_MODNAME, 137 }; 138 139 static int aspeed_wdt_remove(struct platform_device *pdev) 140 { 141 struct aspeed_wdt *wdt = platform_get_drvdata(pdev); 142 143 watchdog_unregister_device(&wdt->wdd); 144 145 return 0; 146 } 147 148 static int aspeed_wdt_probe(struct platform_device *pdev) 149 { 150 struct aspeed_wdt *wdt; 151 struct resource *res; 152 int ret; 153 154 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 155 if (!wdt) 156 return -ENOMEM; 157 158 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 159 wdt->base = devm_ioremap_resource(&pdev->dev, res); 160 if (IS_ERR(wdt->base)) 161 return PTR_ERR(wdt->base); 162 163 /* 164 * The ast2400 wdt can run at PCLK, or 1MHz. The ast2500 only 165 * runs at 1MHz. We chose to always run at 1MHz, as there's no 166 * good reason to have a faster watchdog counter. 167 */ 168 wdt->wdd.info = &aspeed_wdt_info; 169 wdt->wdd.ops = &aspeed_wdt_ops; 170 wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS; 171 wdt->wdd.parent = &pdev->dev; 172 173 wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT; 174 watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev); 175 176 /* 177 * Control reset on a per-device basis to ensure the 178 * host is not affected by a BMC reboot, so only reset 179 * the SOC and not the full chip 180 */ 181 wdt->ctrl = WDT_CTRL_RESET_MODE_SOC | 182 WDT_CTRL_1MHZ_CLK | 183 WDT_CTRL_RESET_SYSTEM; 184 185 if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { 186 aspeed_wdt_start(&wdt->wdd); 187 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); 188 } 189 190 ret = watchdog_register_device(&wdt->wdd); 191 if (ret) { 192 dev_err(&pdev->dev, "failed to register\n"); 193 return ret; 194 } 195 196 platform_set_drvdata(pdev, wdt); 197 198 return 0; 199 } 200 201 static struct platform_driver aspeed_watchdog_driver = { 202 .probe = aspeed_wdt_probe, 203 .remove = aspeed_wdt_remove, 204 .driver = { 205 .name = KBUILD_MODNAME, 206 .of_match_table = of_match_ptr(aspeed_wdt_of_table), 207 }, 208 }; 209 module_platform_driver(aspeed_watchdog_driver); 210 211 MODULE_DESCRIPTION("Aspeed Watchdog Driver"); 212 MODULE_LICENSE("GPL"); 213