Message ID | 20190705114522.42565-5-tomas.melin@vaisala.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | watchdog: cadence_wdt: Support all available prescaler values | expand |
On Fri, Jul 05, 2019 at 11:46:04AM +0000, Melin Tomas wrote: > Cadence watchdog HW supports prescaler values of > 8, 64, 512 and 4096. > > Add support to select prescaler values of 8 and 64 for lower > input clock frequencies. > > Prescaler value is selected to keep timeout resolution of 1 second. > For clock frequencies below 32kHz, 1 second resolution does > no longer hold, thereby returning an error. > > Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> > --- > drivers/watchdog/cadence_wdt.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c > index 4657800d9d8e..39109b5721c1 100644 > --- a/drivers/watchdog/cadence_wdt.c > +++ b/drivers/watchdog/cadence_wdt.c > @@ -33,16 +33,17 @@ > #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000 > > /* Clock prescaler value and selection */ > +#define CDNS_WDT_PRESCALE_8 8 > #define CDNS_WDT_PRESCALE_64 64 > #define CDNS_WDT_PRESCALE_512 512 > #define CDNS_WDT_PRESCALE_4096 4096 > +#define CDNS_WDT_PRESCALE_SELECT_8 0 > #define CDNS_WDT_PRESCALE_SELECT_64 1 > #define CDNS_WDT_PRESCALE_SELECT_512 2 > #define CDNS_WDT_PRESCALE_SELECT_4096 3 > > -/* Input clock frequency */ > -#define CDNS_WDT_CLK_10MHZ 10000000 > -#define CDNS_WDT_CLK_75MHZ 75000000 > +/* Base input clock frequency */ > +#define CDNS_WDT_CLK_32KHZ 32768 > > /* Counter maximum value */ > #define CDNS_WDT_COUNTER_MAX 0xFFF > @@ -304,7 +305,16 @@ static int cdns_wdt_probe(struct platform_device *pdev) > } > > clock_f = clk_get_rate(wdt->clk); > - if (clock_f <= CDNS_WDT_CLK_75MHZ) { > + if (clock_f < CDNS_WDT_CLK_32KHZ) { > + dev_err(&pdev->dev, "cannot find suitable clock prescaler\n"); > + return -ERANGE; /* Math result not representable */ is a bit misleading here. I understand there isn't a good option, but using math errors isn't it. Just use -EINVAL if you don't have a better idea. It might also make sense to display the returned clock frequency. > + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_8) { > + wdt->prescaler = CDNS_WDT_PRESCALE_8; > + wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_8; > + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_64) { > + wdt->prescaler = CDNS_WDT_PRESCALE_64; > + wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_64; > + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_512) { > wdt->prescaler = CDNS_WDT_PRESCALE_512; > wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512; > } else {
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 4657800d9d8e..39109b5721c1 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -33,16 +33,17 @@ #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000 /* Clock prescaler value and selection */ +#define CDNS_WDT_PRESCALE_8 8 #define CDNS_WDT_PRESCALE_64 64 #define CDNS_WDT_PRESCALE_512 512 #define CDNS_WDT_PRESCALE_4096 4096 +#define CDNS_WDT_PRESCALE_SELECT_8 0 #define CDNS_WDT_PRESCALE_SELECT_64 1 #define CDNS_WDT_PRESCALE_SELECT_512 2 #define CDNS_WDT_PRESCALE_SELECT_4096 3 -/* Input clock frequency */ -#define CDNS_WDT_CLK_10MHZ 10000000 -#define CDNS_WDT_CLK_75MHZ 75000000 +/* Base input clock frequency */ +#define CDNS_WDT_CLK_32KHZ 32768 /* Counter maximum value */ #define CDNS_WDT_COUNTER_MAX 0xFFF @@ -304,7 +305,16 @@ static int cdns_wdt_probe(struct platform_device *pdev) } clock_f = clk_get_rate(wdt->clk); - if (clock_f <= CDNS_WDT_CLK_75MHZ) { + if (clock_f < CDNS_WDT_CLK_32KHZ) { + dev_err(&pdev->dev, "cannot find suitable clock prescaler\n"); + return -ERANGE; + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_8) { + wdt->prescaler = CDNS_WDT_PRESCALE_8; + wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_8; + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_64) { + wdt->prescaler = CDNS_WDT_PRESCALE_64; + wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_64; + } else if (clock_f <= CDNS_WDT_CLK_32KHZ * CDNS_WDT_PRESCALE_512) { wdt->prescaler = CDNS_WDT_PRESCALE_512; wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512; } else {
Cadence watchdog HW supports prescaler values of 8, 64, 512 and 4096. Add support to select prescaler values of 8 and 64 for lower input clock frequencies. Prescaler value is selected to keep timeout resolution of 1 second. For clock frequencies below 32kHz, 1 second resolution does no longer hold, thereby returning an error. Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> --- drivers/watchdog/cadence_wdt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)