[DRIVER MODEL] Fix sgivwfb
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Sat, 5 Nov 2005 21:22:39 +0000 (21:22 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 5 Nov 2005 21:22:39 +0000 (21:22 +0000)
Statically allocated devices in module data is a potential cause
of oopsen.  The device may be in use by a userspace process, which
will keep a reference to the device.  If the module is unloaded,
the module data will be freed.  Subsequent use of the platform
device will cause a kernel oops.

Use generic platform device allocation/release code in modules.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/video/sgivwfb.c

index cf5106eab2d583ee387a9496bae2bc2373739f62..5ce81f44c7692f3d05421930cedc1b43e6a838b9 100644 (file)
@@ -751,10 +751,6 @@ int __init sgivwfb_setup(char *options)
 /*
  *  Initialisation
  */
-static void sgivwfb_release(struct device *device)
-{
-}
-
 static int __init sgivwfb_probe(struct device *device)
 {
        struct platform_device *dev = to_platform_device(device);
@@ -859,13 +855,7 @@ static struct device_driver sgivwfb_driver = {
        .remove = sgivwfb_remove,
 };
 
-static struct platform_device sgivwfb_device = {
-       .name   = "sgivwfb",
-       .id     = 0,
-       .dev    = {
-               .release = sgivwfb_release,
-       }
-};
+static struct platform_device *sgivwfb_device;
 
 int __init sgivwfb_init(void)
 {
@@ -880,9 +870,15 @@ int __init sgivwfb_init(void)
 #endif
        ret = driver_register(&sgivwfb_driver);
        if (!ret) {
-               ret = platform_device_register(&sgivwfb_device);
-               if (ret)
+               sgivwfb_device = platform_device_alloc("sgivwfb", 0);
+               if (sgivwfb_device) {
+                       ret = platform_device_add(sgivwfb_device);
+               } else
+                       ret = -ENOMEM;
+               if (ret) {
                        driver_unregister(&sgivwfb_driver);
+                       platform_device_put(sgivwfb_device);
+               }
        }
        return ret;
 }
@@ -894,7 +890,7 @@ MODULE_LICENSE("GPL");
 
 static void __exit sgivwfb_exit(void)
 {
-       platform_device_unregister(&sgivwfb_device);
+       platform_device_unregister(sgivwfb_device);
        driver_unregister(&sgivwfb_driver);
 }