Message ID | 20090329180912.GA6979@infomag.iguana.be (mailing list archive) |
---|---|
State | Awaiting Upstream, archived |
Headers | show |
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
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,