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