On Sun, Nov 07, 2021 at 10:29:39PM +0200, Sam Protsenko wrote: > On new Exynos chips (e.g. Exynos850) new CLUSTERx_NONCPU_OUT register is > introduced, where CNT_EN_WDT bit must be enabled to make watchdog > counter running. Add corresponding quirk and proper infrastructure to > handle that register if the quirk is set. > > This commit doesn't bring any functional change to existing devices, but > merely provides an infrastructure for upcoming chips support. > > Signed-off-by: Sam Protsenko <semen.protsenko@xxxxxxxxxx> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxxxxx> Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx> > --- > Changes in v3: > - Added R-b tag by Krzysztof Kozlowski > > Changes in v2: > - Used quirks instead of callbacks for all added PMU registers > - Used BIT() macro > - Extracted cleanup code to separate patch to minimize changes and > ease the review and porting > > drivers/watchdog/s3c2410_wdt.c | 28 +++++++++++++++++++++++++++- > 1 file changed, 27 insertions(+), 1 deletion(-) > > diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c > index 2a61b6ea5602..ec341c876225 100644 > --- a/drivers/watchdog/s3c2410_wdt.c > +++ b/drivers/watchdog/s3c2410_wdt.c > @@ -60,11 +60,13 @@ > #define QUIRK_HAS_RST_STAT (1 << 1) > #define QUIRK_HAS_WTCLRINT_REG (1 << 2) > #define QUIRK_HAS_PMU_AUTO_DISABLE (1 << 3) > +#define QUIRK_HAS_PMU_CNT_EN (1 << 4) > > /* These quirks require that we have a PMU register map */ > #define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \ > QUIRK_HAS_RST_STAT | \ > - QUIRK_HAS_PMU_AUTO_DISABLE) > + QUIRK_HAS_PMU_AUTO_DISABLE | \ > + QUIRK_HAS_PMU_CNT_EN) > > static bool nowayout = WATCHDOG_NOWAYOUT; > static int tmr_margin; > @@ -98,6 +100,8 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to > * @rst_stat_reg: Offset in pmureg for the register that has the reset status. > * @rst_stat_bit: Bit number in the rst_stat register indicating a watchdog > * reset. > + * @cnt_en_reg: Offset in pmureg for the register that enables WDT counter. > + * @cnt_en_bit: Bit number for "watchdog counter enable" in cnt_en register. > * @quirks: A bitfield of quirks. > */ > > @@ -108,6 +112,8 @@ struct s3c2410_wdt_variant { > int mask_bit; > int rst_stat_reg; > int rst_stat_bit; > + int cnt_en_reg; > + int cnt_en_bit; > u32 quirks; > }; > > @@ -233,6 +239,20 @@ static int s3c2410wdt_mask_wdt_reset(struct s3c2410_wdt *wdt, bool mask) > return ret; > } > > +static int s3c2410wdt_enable_counter(struct s3c2410_wdt *wdt, bool en) > +{ > + const u32 mask_val = BIT(wdt->drv_data->cnt_en_bit); > + const u32 val = en ? mask_val : 0; > + int ret; > + > + ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->cnt_en_reg, > + mask_val, val); > + if (ret < 0) > + dev_err(wdt->dev, "failed to update reg(%d)\n", ret); > + > + return ret; > +} > + > static int s3c2410wdt_mask_and_disable_reset(struct s3c2410_wdt *wdt, bool mask) > { > int ret; > @@ -249,6 +269,12 @@ static int s3c2410wdt_mask_and_disable_reset(struct s3c2410_wdt *wdt, bool mask) > return ret; > } > > + if (wdt->drv_data->quirks & QUIRK_HAS_PMU_CNT_EN) { > + ret = s3c2410wdt_enable_counter(wdt, !mask); > + if (ret < 0) > + return ret; > + } > + > return 0; > } > > -- > 2.30.2 >