On Mon, Apr 17, 2017 at 09:29:33PM +0200, Hauke Mehrtens wrote: > 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@xxxxxxxxxx> Acked-by: Guenter Roeck <linux@xxxxxxxxxxx> > --- > drivers/watchdog/lantiq_wdt.c | 47 +++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 43 insertions(+), 4 deletions(-) > > diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c > index e0823677d8c1..0e349ad03fdf 100644 > --- a/drivers/watchdog/lantiq_wdt.c > +++ b/drivers/watchdog/lantiq_wdt.c > @@ -17,9 +17,14 @@ > #include <linux/uaccess.h> > #include <linux/clk.h> > #include <linux/io.h> > +#include <linux/regmap.h> > +#include <linux/mfd/syscon.h> > > #include <lantiq_soc.h> > > +#define LTQ_RST_CAUSE_WDT_XRX BIT(31) > +#define LTQ_RST_CAUSE_WDT_FALCON 0x02 > + > /* > * Section 3.4 of the datasheet > * The password sequence protects the WDT control register from unintended > @@ -186,6 +191,40 @@ static struct miscdevice ltq_wdt_miscdev = { > .fops = <q_wdt_fops, > }; > > +static void ltq_set_wdt_bootstatus(struct platform_device *pdev) > +{ > + struct device_node *np = pdev->dev.of_node; > + struct regmap *rcu_regmap; > + u32 status_reg_offset; > + u32 val; > + int err; > + > + rcu_regmap = syscon_regmap_lookup_by_phandle(np, > + "lantiq,rcu-syscon"); > + if (IS_ERR_OR_NULL(rcu_regmap)) > + return; > + > + err = of_property_read_u32_index(np, "lantiq,rcu-syscon", 1, > + &status_reg_offset); > + if (err) { > + dev_err(&pdev->dev, "Failed to get RCU reg offset\n"); > + return; > + } > + > + err = regmap_read(rcu_regmap, status_reg_offset, &val); > + if (err) > + return; > + > + /* find out if the watchdog caused the last reboot */ > + if (of_device_is_compatible(np, "lantiq,wdt-xrx100")) { > + if (val & LTQ_RST_CAUSE_WDT_XRX) > + ltq_wdt_bootstatus = WDIOF_CARDRESET; > + } else if (of_device_is_compatible(np, "lantiq,wdt-falcon")) { > + if ((val & 0x7) == LTQ_RST_CAUSE_WDT_FALCON) > + ltq_wdt_bootstatus = WDIOF_CARDRESET; > + } > +} > + > static int > ltq_wdt_probe(struct platform_device *pdev) > { > @@ -205,9 +244,7 @@ ltq_wdt_probe(struct platform_device *pdev) > ltq_io_region_clk_rate = clk_get_rate(clk); > clk_put(clk); > > - /* find out if the watchdog caused the last reboot */ > - if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) > - ltq_wdt_bootstatus = WDIOF_CARDRESET; > + ltq_set_wdt_bootstatus(pdev); > > dev_info(&pdev->dev, "Init done\n"); > return misc_register(<q_wdt_miscdev); > @@ -222,7 +259,9 @@ ltq_wdt_remove(struct platform_device *pdev) > } > > static const struct of_device_id ltq_wdt_match[] = { > - { .compatible = "lantiq,wdt" }, > + { .compatible = "lantiq,wdt"}, > + { .compatible = "lantiq,wdt-xrx100"}, > + { .compatible = "lantiq,wdt-falcon"}, > {}, > }; > MODULE_DEVICE_TABLE(of, ltq_wdt_match);