Re: [PATCH 35/58] move omap_wdt's probe function to .devinit.text

Uwe Kleine-König
2009-03-29T18:16:36Z

Hi Wim,

On Sun, Mar 29, 2009 at 08:09:12PM +0200, Wim Van Sebroeck wrote:
> Hi Uwe,
>
> > A pointer to omap_wdt_probe is passed to the core via
> > platform_driver_register and so the function must not disappear when the
> > .init sections are discarded. Otherwise (if also having HOTPLUG=y)
> > unbinding and binding a device to the driver via sysfs will result in an
> > oops as does a device being registered late.
> >
> > An alternative to this patch is using platform_driver_probe instead of
> > platform_driver_register plus removing the pointer to the probe function
> > from the struct platform_driver.
>
> Agree with the explanation, but ...
>
> > diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> > index 2f2ce74..c9c14dd 100644
> > --- a/drivers/watchdog/omap_wdt.c
> > +++ b/drivers/watchdog/omap_wdt.c
> > @@ -269,7 +269,7 @@ static const struct file_operations omap_wdt_fops = {
> > .release = omap_wdt_release,
> > };
> >
> > -static int __init omap_wdt_probe(struct platform_device *pdev)
> > +static int __devinit omap_wdt_probe(struct platform_device *pdev)
> > {
> > struct resource *res, *mem;
> > struct omap_wdt_dev *wdev;
>
> ...imho this would be the correct fix:
>
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> index aa5ad6e..f271385 100644
> --- a/drivers/watchdog/omap_wdt.c
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -258,7 +258,7 @@ static const struct file_operations omap_wdt_fops = {
> .release = omap_wdt_release,
> };
>
> -static int __init omap_wdt_probe(struct platform_device *pdev)
> +static int __devinit omap_wdt_probe(struct platform_device *pdev)
> {
> struct resource *res, *mem;
> struct omap_wdt_dev *wdev;
> @@ -367,7 +367,7 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
> omap_wdt_disable(wdev);
> }
>
> -static int omap_wdt_remove(struct platform_device *pdev)
> +static int __devexit omap_wdt_remove(struct platform_device *pdev)
> {
> struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -426,7 +426,7 @@ static int omap_wdt_resume(struct platform_device *pdev)
>
> static struct platform_driver omap_wdt_driver = {
> .probe = omap_wdt_probe,
> - .remove = omap_wdt_remove,
> + .remove = __devexit_p(omap_wdt_remove),
> .shutdown = omap_wdt_shutdown,
> .suspend = omap_wdt_suspend,
> .resume = omap_wdt_resume,
Your change is OK, but only "my" part is an important fix. With
omap_wdt_probe being defined with __init your kernel can oops.
omap_wdt_remove only occupies memory for too long if defined without
__devexit. That's why I only fixed the first part (with the remove
functions on my todo list though).

Grüßle
Uwe

--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |