Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

watchdog: lantiq: access boot cause register through regmap

This patch avoids accessing the function ltq_reset_cause() and directly
accesses the register given over the syscon interface. The syscon
interface will be implemented for the xway SoCs for the falcon SoCs the
ltq_reset_cause() function never worked, because a wrong offset was used.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Acked-by: Guenter Roeck <linux@reck-us.net>
Cc: martin.blumenstingl@googlemail.com
Cc: john@phrozen.org
Cc: robh@kernel.org
Cc: andy.shevchenko@gmail.com
Cc: p.zabel@pengutronix.de
Cc: kishon@ti.com
Cc: mark.rutland@arm.com
Cc: linux-mips@linux-mips.org
Cc: linux-mtd@lists.infradead.org
Cc: linux-watchdog@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-spi@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/17123/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Hauke Mehrtens and committed by
Ralf Baechle
710322ba 3147f448

+69 -5
+69 -5
drivers/watchdog/lantiq_wdt.c
··· 4 4 * by the Free Software Foundation. 5 5 * 6 6 * Copyright (C) 2010 John Crispin <john@phrozen.org> 7 + * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de> 7 8 * Based on EP93xx wdt driver 8 9 */ 9 10 ··· 18 17 #include <linux/uaccess.h> 19 18 #include <linux/clk.h> 20 19 #include <linux/io.h> 20 + #include <linux/regmap.h> 21 + #include <linux/mfd/syscon.h> 21 22 22 23 #include <lantiq_soc.h> 24 + 25 + #define LTQ_XRX_RCU_RST_STAT 0x0014 26 + #define LTQ_XRX_RCU_RST_STAT_WDT BIT(31) 27 + 28 + /* CPU0 Reset Source Register */ 29 + #define LTQ_FALCON_SYS1_CPU0RS 0x0060 30 + /* reset cause mask */ 31 + #define LTQ_FALCON_SYS1_CPU0RS_MASK 0x0007 32 + #define LTQ_FALCON_SYS1_CPU0RS_WDT 0x02 23 33 24 34 /* 25 35 * Section 3.4 of the datasheet ··· 198 186 .fops = &ltq_wdt_fops, 199 187 }; 200 188 189 + typedef int (*ltq_wdt_bootstatus_set)(struct platform_device *pdev); 190 + 191 + static int ltq_wdt_bootstatus_xrx(struct platform_device *pdev) 192 + { 193 + struct device *dev = &pdev->dev; 194 + struct regmap *rcu_regmap; 195 + u32 val; 196 + int err; 197 + 198 + rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap"); 199 + if (IS_ERR(rcu_regmap)) 200 + return PTR_ERR(rcu_regmap); 201 + 202 + err = regmap_read(rcu_regmap, LTQ_XRX_RCU_RST_STAT, &val); 203 + if (err) 204 + return err; 205 + 206 + if (val & LTQ_XRX_RCU_RST_STAT_WDT) 207 + ltq_wdt_bootstatus = WDIOF_CARDRESET; 208 + 209 + return 0; 210 + } 211 + 212 + static int ltq_wdt_bootstatus_falcon(struct platform_device *pdev) 213 + { 214 + struct device *dev = &pdev->dev; 215 + struct regmap *rcu_regmap; 216 + u32 val; 217 + int err; 218 + 219 + rcu_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, 220 + "lantiq,rcu"); 221 + if (IS_ERR(rcu_regmap)) 222 + return PTR_ERR(rcu_regmap); 223 + 224 + err = regmap_read(rcu_regmap, LTQ_FALCON_SYS1_CPU0RS, &val); 225 + if (err) 226 + return err; 227 + 228 + if ((val & LTQ_FALCON_SYS1_CPU0RS_MASK) == LTQ_FALCON_SYS1_CPU0RS_WDT) 229 + ltq_wdt_bootstatus = WDIOF_CARDRESET; 230 + 231 + return 0; 232 + } 233 + 201 234 static int 202 235 ltq_wdt_probe(struct platform_device *pdev) 203 236 { 204 237 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 205 238 struct clk *clk; 239 + ltq_wdt_bootstatus_set ltq_wdt_bootstatus_set; 240 + int ret; 206 241 207 242 ltq_wdt_membase = devm_ioremap_resource(&pdev->dev, res); 208 243 if (IS_ERR(ltq_wdt_membase)) 209 244 return PTR_ERR(ltq_wdt_membase); 245 + 246 + ltq_wdt_bootstatus_set = of_device_get_match_data(&pdev->dev); 247 + if (ltq_wdt_bootstatus_set) { 248 + ret = ltq_wdt_bootstatus_set(pdev); 249 + if (ret) 250 + return ret; 251 + } 210 252 211 253 /* we do not need to enable the clock as it is always running */ 212 254 clk = clk_get_io(); ··· 270 204 } 271 205 ltq_io_region_clk_rate = clk_get_rate(clk); 272 206 clk_put(clk); 273 - 274 - /* find out if the watchdog caused the last reboot */ 275 - if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) 276 - ltq_wdt_bootstatus = WDIOF_CARDRESET; 277 207 278 208 dev_info(&pdev->dev, "Init done\n"); 279 209 return misc_register(&ltq_wdt_miscdev); ··· 284 222 } 285 223 286 224 static const struct of_device_id ltq_wdt_match[] = { 287 - { .compatible = "lantiq,wdt" }, 225 + { .compatible = "lantiq,wdt", .data = NULL}, 226 + { .compatible = "lantiq,xrx100-wdt", .data = ltq_wdt_bootstatus_xrx }, 227 + { .compatible = "lantiq,falcon-wdt", .data = ltq_wdt_bootstatus_falcon }, 288 228 {}, 289 229 }; 290 230 MODULE_DEVICE_TABLE(of, ltq_wdt_match);