[RFC PATCH 1/2] watchdog: imx2: fix hang-up on boot for i.MX21, i.MX27 and i.MX31 SoCs
Magnus Lilja
lilja.magnus at gmail.com
Sat Dec 10 11:28:57 PST 2016
Hi,
On 26 September 2016 at 15:02, Guenter Roeck <linux at roeck-us.net> wrote:
> On 09/25/2016 05:39 PM, Vladimir Zapolskiy wrote:
>>
>> Power down counter enable/disable bit switch is located in WMCR
>> register, but watchdog controllers found on legacy i.MX21, i.MX27 and
>> i.MX31 SoCs don't have this register. As a result of writing data to
>> the non-existing register on driver probe the SoC hangs up, to fix the
>> problem add more OF compatible strings and on this basis get
>> information about availability of the WMCR register.
>>
>> Fixes: 5fe65ce7ccbb ("watchdog: imx2_wdt: Disable power down counter on
>> boot")
>> Signed-off-by: Vladimir Zapolskiy <vz at mleia.com>
>> ---
>> drivers/watchdog/imx2_wdt.c | 47
>> +++++++++++++++++++++++++++++++++++++++++++--
>> 1 file changed, 45 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
>> index 62f346b..b6763e0 100644
>> --- a/drivers/watchdog/imx2_wdt.c
>> +++ b/drivers/watchdog/imx2_wdt.c
>> @@ -29,6 +29,7 @@
>> #include <linux/module.h>
>> #include <linux/moduleparam.h>
>> #include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> #include <linux/platform_device.h>
>> #include <linux/regmap.h>
>> #include <linux/watchdog.h>
>> @@ -57,6 +58,10 @@
>>
>> #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8)
>>
>> +struct imx2_wdt_data {
>> + bool has_pdc;
>> +};
>> +
>> struct imx2_wdt_device {
>> struct clk *clk;
>> struct regmap *regmap;
>> @@ -64,6 +69,8 @@ struct imx2_wdt_device {
>> bool ext_reset;
>> };
>>
>> +static const struct of_device_id imx2_wdt_dt_ids[];
>> +
>> static bool nowayout = WATCHDOG_NOWAYOUT;
>> module_param(nowayout, bool, 0);
>> MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started
>> (default="
>> @@ -200,10 +207,13 @@ static const struct regmap_config
>> imx2_wdt_regmap_config = {
>>
>> static int __init imx2_wdt_probe(struct platform_device *pdev)
>> {
>> + const struct of_device_id *of_id;
>> + const struct imx2_wdt_data *data;
>> struct imx2_wdt_device *wdev;
>> struct watchdog_device *wdog;
>> struct resource *res;
>> void __iomem *base;
>> + bool has_pdc;
>> int ret;
>> u32 val;
>>
>> @@ -261,12 +271,24 @@ static int __init imx2_wdt_probe(struct
>> platform_device *pdev)
>> set_bit(WDOG_HW_RUNNING, &wdog->status);
>> }
>>
>> + if (pdev->dev.of_node) {
>> + of_id = of_match_device(imx2_wdt_dt_ids, &pdev->dev);
>> + if (!of_id)
>> + return -ENODEV;
>> +
>> + data = of_id->data;
>> + has_pdc = data->has_pdc;
>> + } else {
>> + has_pdc = false;
>> + }
>> +
>> /*
>> * Disable the watchdog power down counter at boot. Otherwise the
>> power
>> * down counter will pull down the #WDOG interrupt line for one
>> clock
>> * cycle.
>> */
>> - regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
>> + if (has_pdc)
>> + regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);
>>
>> ret = watchdog_register_device(wdog);
>> if (ret) {
>> @@ -363,8 +385,29 @@ static int imx2_wdt_resume(struct device *dev)
>> static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
>> imx2_wdt_resume);
>>
>> +static const struct imx2_wdt_data imx21_wdt_data = {
>> + .has_pdc = false,
>> +};
>> +
>> +static const struct imx2_wdt_data imx25_wdt_data = {
>> + .has_pdc = true,
>> +};
>> +
>> static const struct of_device_id imx2_wdt_dt_ids[] = {
>> - { .compatible = "fsl,imx21-wdt", },
>> + { .compatible = "fsl,imx21-wdt", .data = &imx21_wdt_data },
>
>
> Please just specify the flag directly, as in
> .data = (void *) true
> or, if you prefer, use defines.
> .data = (void *) IMX_SUPPORTS_PDC
>
> Then, in above code:
> has_pdc = (bool) of_id->data;
>
> Guenter
Has this patch (or an updated one) been merged in any tree? I've
tested it on a i.MX31 board with positive result.
Regards, Magnus
More information about the linux-arm-kernel
mailing list