1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Maxim MAX77620 Watchdog Driver 4 * 5 * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. 6 * Copyright (C) 2022 Luca Ceresoli 7 * 8 * Author: Laxman Dewangan <ldewangan@nvidia.com> 9 * Author: Luca Ceresoli <luca.ceresoli@bootlin.com> 10 */ 11 12 #include <linux/err.h> 13 #include <linux/init.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/mod_devicetable.h> 17 #include <linux/mfd/max77620.h> 18 #include <linux/mfd/max77714.h> 19 #include <linux/platform_device.h> 20 #include <linux/regmap.h> 21 #include <linux/slab.h> 22 #include <linux/watchdog.h> 23 24 static bool nowayout = WATCHDOG_NOWAYOUT; 25 26 /** 27 * struct max77620_variant - Data specific to a chip variant 28 * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset 29 * @reg_cnfg_glbl2: CNFG_GLBL2 register offset 30 * @reg_cnfg_glbl3: CNFG_GLBL3 register offset 31 * @wdtc_mask: WDTC bit mask in CNFG_GLBL3 (=bits to update to ping the watchdog) 32 * @bit_wd_rst_wk: WD_RST_WK bit offset within ONOFF_CNFG2 33 * @cnfg_glbl2_cfg_bits: configuration bits to enable in CNFG_GLBL2 register 34 */ 35 struct max77620_variant { 36 u8 reg_onoff_cnfg2; 37 u8 reg_cnfg_glbl2; 38 u8 reg_cnfg_glbl3; 39 u8 wdtc_mask; 40 u8 bit_wd_rst_wk; 41 u8 cnfg_glbl2_cfg_bits; 42 }; 43 44 struct max77620_wdt { 45 struct device *dev; 46 struct regmap *rmap; 47 const struct max77620_variant *drv_data; 48 struct watchdog_device wdt_dev; 49 }; 50 51 static const struct max77620_variant max77620_wdt_data = { 52 .reg_onoff_cnfg2 = MAX77620_REG_ONOFFCNFG2, 53 .reg_cnfg_glbl2 = MAX77620_REG_CNFGGLBL2, 54 .reg_cnfg_glbl3 = MAX77620_REG_CNFGGLBL3, 55 .wdtc_mask = MAX77620_WDTC_MASK, 56 .bit_wd_rst_wk = MAX77620_ONOFFCNFG2_WD_RST_WK, 57 /* Set WDT clear in OFF and sleep mode */ 58 .cnfg_glbl2_cfg_bits = MAX77620_WDTSLPC | MAX77620_WDTOFFC, 59 }; 60 61 static const struct max77620_variant max77714_wdt_data = { 62 .reg_onoff_cnfg2 = MAX77714_CNFG2_ONOFF, 63 .reg_cnfg_glbl2 = MAX77714_CNFG_GLBL2, 64 .reg_cnfg_glbl3 = MAX77714_CNFG_GLBL3, 65 .wdtc_mask = MAX77714_WDTC, 66 .bit_wd_rst_wk = MAX77714_WD_RST_WK, 67 /* Set WDT clear in sleep mode (there is no WDTOFFC on MAX77714) */ 68 .cnfg_glbl2_cfg_bits = MAX77714_WDTSLPC, 69 }; 70 71 static int max77620_wdt_start(struct watchdog_device *wdt_dev) 72 { 73 struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); 74 75 return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, 76 MAX77620_WDTEN, MAX77620_WDTEN); 77 } 78 79 static int max77620_wdt_stop(struct watchdog_device *wdt_dev) 80 { 81 struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); 82 83 return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, 84 MAX77620_WDTEN, 0); 85 } 86 87 static int max77620_wdt_ping(struct watchdog_device *wdt_dev) 88 { 89 struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); 90 91 return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, 92 wdt->drv_data->wdtc_mask, 0x1); 93 } 94 95 static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, 96 unsigned int timeout) 97 { 98 struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); 99 unsigned int wdt_timeout; 100 u8 regval; 101 int ret; 102 103 switch (timeout) { 104 case 0 ... 2: 105 regval = MAX77620_TWD_2s; 106 wdt_timeout = 2; 107 break; 108 109 case 3 ... 16: 110 regval = MAX77620_TWD_16s; 111 wdt_timeout = 16; 112 break; 113 114 case 17 ... 64: 115 regval = MAX77620_TWD_64s; 116 wdt_timeout = 64; 117 break; 118 119 default: 120 regval = MAX77620_TWD_128s; 121 wdt_timeout = 128; 122 break; 123 } 124 125 /* 126 * "If the value of TWD needs to be changed, clear the system 127 * watchdog timer first [...], then change the value of TWD." 128 * (MAX77714 datasheet but applies to MAX77620 too) 129 */ 130 ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, 131 wdt->drv_data->wdtc_mask, 0x1); 132 if (ret < 0) 133 return ret; 134 135 ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, 136 MAX77620_TWD_MASK, regval); 137 if (ret < 0) 138 return ret; 139 140 wdt_dev->timeout = wdt_timeout; 141 142 return 0; 143 } 144 145 static const struct watchdog_info max77620_wdt_info = { 146 .identity = "max77620-watchdog", 147 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 148 }; 149 150 static const struct watchdog_ops max77620_wdt_ops = { 151 .start = max77620_wdt_start, 152 .stop = max77620_wdt_stop, 153 .ping = max77620_wdt_ping, 154 .set_timeout = max77620_wdt_set_timeout, 155 }; 156 157 static int max77620_wdt_probe(struct platform_device *pdev) 158 { 159 const struct platform_device_id *id = platform_get_device_id(pdev); 160 struct device *dev = &pdev->dev; 161 struct max77620_wdt *wdt; 162 struct watchdog_device *wdt_dev; 163 unsigned int regval; 164 int ret; 165 166 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); 167 if (!wdt) 168 return -ENOMEM; 169 170 wdt->dev = dev; 171 wdt->drv_data = (const struct max77620_variant *) id->driver_data; 172 173 wdt->rmap = dev_get_regmap(dev->parent, NULL); 174 if (!wdt->rmap) { 175 dev_err(wdt->dev, "Failed to get parent regmap\n"); 176 return -ENODEV; 177 } 178 179 wdt_dev = &wdt->wdt_dev; 180 wdt_dev->info = &max77620_wdt_info; 181 wdt_dev->ops = &max77620_wdt_ops; 182 wdt_dev->min_timeout = 2; 183 wdt_dev->max_timeout = 128; 184 wdt_dev->max_hw_heartbeat_ms = 128 * 1000; 185 186 platform_set_drvdata(pdev, wdt); 187 188 /* Enable WD_RST_WK - WDT expire results in a restart */ 189 ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_onoff_cnfg2, 190 wdt->drv_data->bit_wd_rst_wk, 191 wdt->drv_data->bit_wd_rst_wk); 192 if (ret < 0) { 193 dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret); 194 return ret; 195 } 196 197 /* Set the "auto WDT clear" bits available on the chip */ 198 ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, 199 wdt->drv_data->cnfg_glbl2_cfg_bits, 200 wdt->drv_data->cnfg_glbl2_cfg_bits); 201 if (ret < 0) { 202 dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret); 203 return ret; 204 } 205 206 /* Check if WDT running and if yes then set flags properly */ 207 ret = regmap_read(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, ®val); 208 if (ret < 0) { 209 dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret); 210 return ret; 211 } 212 213 switch (regval & MAX77620_TWD_MASK) { 214 case MAX77620_TWD_2s: 215 wdt_dev->timeout = 2; 216 break; 217 case MAX77620_TWD_16s: 218 wdt_dev->timeout = 16; 219 break; 220 case MAX77620_TWD_64s: 221 wdt_dev->timeout = 64; 222 break; 223 default: 224 wdt_dev->timeout = 128; 225 break; 226 } 227 228 if (regval & MAX77620_WDTEN) 229 set_bit(WDOG_HW_RUNNING, &wdt_dev->status); 230 231 watchdog_set_nowayout(wdt_dev, nowayout); 232 watchdog_set_drvdata(wdt_dev, wdt); 233 234 watchdog_stop_on_unregister(wdt_dev); 235 return devm_watchdog_register_device(dev, wdt_dev); 236 } 237 238 static const struct platform_device_id max77620_wdt_devtype[] = { 239 { "max77620-watchdog", (kernel_ulong_t)&max77620_wdt_data }, 240 { "max77714-watchdog", (kernel_ulong_t)&max77714_wdt_data }, 241 { }, 242 }; 243 MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); 244 245 static struct platform_driver max77620_wdt_driver = { 246 .driver = { 247 .name = "max77620-watchdog", 248 }, 249 .probe = max77620_wdt_probe, 250 .id_table = max77620_wdt_devtype, 251 }; 252 253 module_platform_driver(max77620_wdt_driver); 254 255 MODULE_DESCRIPTION("Max77620 watchdog timer driver"); 256 257 module_param(nowayout, bool, 0); 258 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 259 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 260 261 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 262 MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>"); 263 MODULE_LICENSE("GPL v2"); 264