[PATCH] watchdog: fix error in probe() of s3c2410_wdt (reset at booting)

MyungJoo Ham myungjoo.ham at gmail.com
Tue Jan 31 00:30:00 EST 2012


On Tue, Jan 31, 2012 at 4:01 AM, Wim Van Sebroeck <wim at iguana.be> wrote:
> Hi,
>
>> Yes, if we set wdt_count value properly before request_irq, it's fine.
>>
>> Anyway, as registering the device (watchdog_register_device()) may be
>> done after request_irq without any problem, moving request_irq right
>> before it, not after it should be fine.
>
> So what that be attached patch then? Could you also test this patch?

This patch looks fine and works. It's tested in Exynos4 machine.

Acked-by: MyungJoo Ham <myungjoo.ham at samsung.com>


Thanks.

Cheers!
MyungJoo.

>
> Kind regards,
> Wim.
> ---
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index 4bc3744..404172f 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -312,18 +312,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
>        dev = &pdev->dev;
>        wdt_dev = &pdev->dev;
>
> -       /* get the memory region for the watchdog timer */
> -
>        wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>        if (wdt_mem == NULL) {
>                dev_err(dev, "no memory resource specified\n");
>                return -ENOENT;
>        }
>
> +       wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +       if (wdt_irq == NULL) {
> +               dev_err(dev, "no irq resource specified\n");
> +               ret = -ENOENT;
> +               goto err;
> +       }
> +
> +       /* get the memory region for the watchdog timer */
> +
>        size = resource_size(wdt_mem);
>        if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
>                dev_err(dev, "failed to get memory region\n");
> -               return -EBUSY;
> +               ret = -EBUSY;
> +               goto err;
>        }
>
>        wdt_base = ioremap(wdt_mem->start, size);
> @@ -335,29 +343,17 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
>
>        DBG("probe: mapped wdt_base=%p\n", wdt_base);
>
> -       wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -       if (wdt_irq == NULL) {
> -               dev_err(dev, "no irq resource specified\n");
> -               ret = -ENOENT;
> -               goto err_map;
> -       }
> -
> -       ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
> -       if (ret != 0) {
> -               dev_err(dev, "failed to install irq (%d)\n", ret);
> -               goto err_map;
> -       }
> -
>        wdt_clock = clk_get(&pdev->dev, "watchdog");
>        if (IS_ERR(wdt_clock)) {
>                dev_err(dev, "failed to find watchdog clock source\n");
>                ret = PTR_ERR(wdt_clock);
> -               goto err_irq;
> +               goto err_map;
>        }
>
>        clk_enable(wdt_clock);
>
> -       if (s3c2410wdt_cpufreq_register() < 0) {
> +       ret = s3c2410wdt_cpufreq_register();
> +       if (ret < 0) {
>                printk(KERN_ERR PFX "failed to register cpufreq\n");
>                goto err_clk;
>        }
> @@ -378,12 +374,18 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
>                                                        "cannot start\n");
>        }
>
> +       ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
> +       if (ret != 0) {
> +               dev_err(dev, "failed to install irq (%d)\n", ret);
> +               goto err_cpufreq;
> +       }
> +
>        watchdog_set_nowayout(&s3c2410_wdd, nowayout);
>
>        ret = watchdog_register_device(&s3c2410_wdd);
>        if (ret) {
>                dev_err(dev, "cannot register watchdog (%d)\n", ret);
> -               goto err_cpufreq;
> +               goto err_irq;
>        }
>
>        if (tmr_atboot && started == 0) {
> @@ -408,23 +410,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
>
>        return 0;
>
> + err_irq:
> +       free_irq(wdt_irq->start, pdev);
> +
>  err_cpufreq:
>        s3c2410wdt_cpufreq_deregister();
>
>  err_clk:
>        clk_disable(wdt_clock);
>        clk_put(wdt_clock);
> -
> - err_irq:
> -       free_irq(wdt_irq->start, pdev);
> +       wdt_clock = NULL;
>
>  err_map:
>        iounmap(wdt_base);
>
>  err_req:
>        release_mem_region(wdt_mem->start, size);
> -       wdt_mem = NULL;
>
> + err:
> +       wdt_irq = NULL;
> +       wdt_mem = NULL;
>        return ret;
>  }
>
> @@ -432,18 +437,18 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
>  {
>        watchdog_unregister_device(&s3c2410_wdd);
>
> +       free_irq(wdt_irq->start, dev);
> +
>        s3c2410wdt_cpufreq_deregister();
>
>        clk_disable(wdt_clock);
>        clk_put(wdt_clock);
>        wdt_clock = NULL;
>
> -       free_irq(wdt_irq->start, dev);
> -       wdt_irq = NULL;
> -
>        iounmap(wdt_base);
>
>        release_mem_region(wdt_mem->start, resource_size(wdt_mem));
> +       wdt_irq = NULL;
>        wdt_mem = NULL;
>        return 0;
>  }



-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics



More information about the linux-arm-kernel mailing list