Message ID | 20200204184322.22744-1-ansuelsmth@gmail.com |
---|---|
State | New |
Headers | show |
Series | watchdog: qcom-wdt: disable pretimeout on timer platform | expand |
On Tue, Feb 04, 2020 at 07:43:22PM +0100, Ansuel Smith wrote: > Some platform like ipq806x doesn't support pretimeout and define > some interrupts used by qcom,msm-timer. Change the driver to check > and use pretimeout only on qcom,kpss-wdt as it's the only platform > that actually supports it. > > Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> > --- > drivers/watchdog/qcom-wdt.c | 31 +++++++++++++++++++++++-------- > 1 file changed, 23 insertions(+), 8 deletions(-) > > diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c > index a494543d3ae1..195fe49ca32e 100644 > --- a/drivers/watchdog/qcom-wdt.c > +++ b/drivers/watchdog/qcom-wdt.c > @@ -40,6 +40,11 @@ static const u32 reg_offset_data_kpss[] = { > [WDT_BITE_TIME] = 0x14, > }; > > +struct qcom_wdt_match_data { > + const u32 *offset; > + bool pretimeout; > +}; > + > struct qcom_wdt { > struct watchdog_device wdd; > unsigned long rate; > @@ -179,19 +184,29 @@ static void qcom_clk_disable_unprepare(void *data) > clk_disable_unprepare(data); > } > > +static const struct qcom_wdt_match_data match_data_apcs_tmr = { > + .offset = reg_offset_data_apcs_tmr, > + .pretimeout = false, > +}; > + > +static const struct qcom_wdt_match_data match_data_kpss = { > + .offset = reg_offset_data_kpss, > + .pretimeout = true, > +}; > + > static int qcom_wdt_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > struct qcom_wdt *wdt; > struct resource *res; > struct device_node *np = dev->of_node; > - const u32 *regs; > + const struct qcom_wdt_match_data *data; > u32 percpu_offset; > int irq, ret; > struct clk *clk; > > - regs = of_device_get_match_data(dev); > - if (!regs) { > + data = of_device_get_match_data(dev); > + if (!data && !data->offset) { This should be ||. However, the second check is really unnecessary (it would be a coding error). Guenter > dev_err(dev, "Unsupported QCOM WDT module\n"); > return -ENODEV; > } > @@ -247,7 +262,7 @@ static int qcom_wdt_probe(struct platform_device *pdev) > > /* check if there is pretimeout support */ > irq = platform_get_irq(pdev, 0); > - if (irq > 0) { > + if (data->pretimeout && irq > 0) { > ret = devm_request_irq(dev, irq, qcom_wdt_isr, > IRQF_TRIGGER_RISING, > "wdt_bark", &wdt->wdd); > @@ -267,7 +282,7 @@ static int qcom_wdt_probe(struct platform_device *pdev) > wdt->wdd.min_timeout = 1; > wdt->wdd.max_timeout = 0x10000000U / wdt->rate; > wdt->wdd.parent = dev; > - wdt->layout = regs; > + wdt->layout = data->offset; > > if (readl(wdt_addr(wdt, WDT_STS)) & 1) > wdt->wdd.bootstatus = WDIOF_CARDRESET; > @@ -311,9 +326,9 @@ static int __maybe_unused qcom_wdt_resume(struct device *dev) > static SIMPLE_DEV_PM_OPS(qcom_wdt_pm_ops, qcom_wdt_suspend, qcom_wdt_resume); > > static const struct of_device_id qcom_wdt_of_table[] = { > - { .compatible = "qcom,kpss-timer", .data = reg_offset_data_apcs_tmr }, > - { .compatible = "qcom,scss-timer", .data = reg_offset_data_apcs_tmr }, > - { .compatible = "qcom,kpss-wdt", .data = reg_offset_data_kpss }, > + { .compatible = "qcom,kpss-timer", .data = &match_data_apcs_tmr }, > + { .compatible = "qcom,scss-timer", .data = &match_data_apcs_tmr }, > + { .compatible = "qcom,kpss-wdt", .data = &match_data_kpss }, > { }, > }; > MODULE_DEVICE_TABLE(of, qcom_wdt_of_table); > -- > 2.24.0 >
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c index a494543d3ae1..195fe49ca32e 100644 --- a/drivers/watchdog/qcom-wdt.c +++ b/drivers/watchdog/qcom-wdt.c @@ -40,6 +40,11 @@ static const u32 reg_offset_data_kpss[] = { [WDT_BITE_TIME] = 0x14, }; +struct qcom_wdt_match_data { + const u32 *offset; + bool pretimeout; +}; + struct qcom_wdt { struct watchdog_device wdd; unsigned long rate; @@ -179,19 +184,29 @@ static void qcom_clk_disable_unprepare(void *data) clk_disable_unprepare(data); } +static const struct qcom_wdt_match_data match_data_apcs_tmr = { + .offset = reg_offset_data_apcs_tmr, + .pretimeout = false, +}; + +static const struct qcom_wdt_match_data match_data_kpss = { + .offset = reg_offset_data_kpss, + .pretimeout = true, +}; + static int qcom_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct qcom_wdt *wdt; struct resource *res; struct device_node *np = dev->of_node; - const u32 *regs; + const struct qcom_wdt_match_data *data; u32 percpu_offset; int irq, ret; struct clk *clk; - regs = of_device_get_match_data(dev); - if (!regs) { + data = of_device_get_match_data(dev); + if (!data && !data->offset) { dev_err(dev, "Unsupported QCOM WDT module\n"); return -ENODEV; } @@ -247,7 +262,7 @@ static int qcom_wdt_probe(struct platform_device *pdev) /* check if there is pretimeout support */ irq = platform_get_irq(pdev, 0); - if (irq > 0) { + if (data->pretimeout && irq > 0) { ret = devm_request_irq(dev, irq, qcom_wdt_isr, IRQF_TRIGGER_RISING, "wdt_bark", &wdt->wdd); @@ -267,7 +282,7 @@ static int qcom_wdt_probe(struct platform_device *pdev) wdt->wdd.min_timeout = 1; wdt->wdd.max_timeout = 0x10000000U / wdt->rate; wdt->wdd.parent = dev; - wdt->layout = regs; + wdt->layout = data->offset; if (readl(wdt_addr(wdt, WDT_STS)) & 1) wdt->wdd.bootstatus = WDIOF_CARDRESET; @@ -311,9 +326,9 @@ static int __maybe_unused qcom_wdt_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(qcom_wdt_pm_ops, qcom_wdt_suspend, qcom_wdt_resume); static const struct of_device_id qcom_wdt_of_table[] = { - { .compatible = "qcom,kpss-timer", .data = reg_offset_data_apcs_tmr }, - { .compatible = "qcom,scss-timer", .data = reg_offset_data_apcs_tmr }, - { .compatible = "qcom,kpss-wdt", .data = reg_offset_data_kpss }, + { .compatible = "qcom,kpss-timer", .data = &match_data_apcs_tmr }, + { .compatible = "qcom,scss-timer", .data = &match_data_apcs_tmr }, + { .compatible = "qcom,kpss-wdt", .data = &match_data_kpss }, { }, }; MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
Some platform like ipq806x doesn't support pretimeout and define some interrupts used by qcom,msm-timer. Change the driver to check and use pretimeout only on qcom,kpss-wdt as it's the only platform that actually supports it. Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> --- drivers/watchdog/qcom-wdt.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)