diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-11-05 21:22:39 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-05 21:22:39 +0000 |
commit | 2c119aa8091a15a87920f09aa0f17e05960fe11b (patch) | |
tree | 28871ec8da0830362f045906fb2b97722cb6837f /drivers | |
parent | abbf268ae8f51e19779cdf3f5fbb8144f1a5fbc3 (diff) | |
download | op-kernel-dev-2c119aa8091a15a87920f09aa0f17e05960fe11b.zip op-kernel-dev-2c119aa8091a15a87920f09aa0f17e05960fe11b.tar.gz |
[DRIVER MODEL] Fix sgivwfb
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/sgivwfb.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index cf5106e..5ce81f4 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -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); } |