diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-04 03:36:15 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-16 12:53:11 -0500 |
commit | 9634a627b330fcc7cdca25df4d7853ca9c7745de (patch) | |
tree | f5a727d12849a835546f5c5dc7fcb6b82182daae | |
parent | 0ad3dc3af8ba028368263b190a7a270f8d5cf5ae (diff) |
tc1100-wmi - add error handling for device registration
Any of the platform API functions can fail; driver should be prepared
to handle such failures. Also:
- changed to platform_driver_probe() since the device is created
right there with the driver;
- added __devexit annotation to remove method;
- fixed memory leak on module unload - named platform_device_del() is not
enough to free platform device, need platform_device_unregister().
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/platform/x86/tc1100-wmi.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 0d53d5166574..fa2995bfa1d9 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c | |||
@@ -47,22 +47,6 @@ MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); | |||
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505"); | 48 | MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505"); |
49 | 49 | ||
50 | static int tc1100_probe(struct platform_device *device); | ||
51 | static int tc1100_remove(struct platform_device *device); | ||
52 | static int tc1100_suspend(struct platform_device *device, pm_message_t state); | ||
53 | static int tc1100_resume(struct platform_device *device); | ||
54 | |||
55 | static struct platform_driver tc1100_driver = { | ||
56 | .driver = { | ||
57 | .name = "tc1100-wmi", | ||
58 | .owner = THIS_MODULE, | ||
59 | }, | ||
60 | .probe = tc1100_probe, | ||
61 | .remove = tc1100_remove, | ||
62 | .suspend = tc1100_suspend, | ||
63 | .resume = tc1100_resume, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device *tc1100_device; | 50 | static struct platform_device *tc1100_device; |
67 | 51 | ||
68 | struct tc1100_data { | 52 | struct tc1100_data { |
@@ -197,13 +181,13 @@ static struct attribute_group tc1100_attribute_group = { | |||
197 | Driver Model | 181 | Driver Model |
198 | -------------------------------------------------------------------------- */ | 182 | -------------------------------------------------------------------------- */ |
199 | 183 | ||
200 | static int tc1100_probe(struct platform_device *device) | 184 | static int __init tc1100_probe(struct platform_device *device) |
201 | { | 185 | { |
202 | return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group); | 186 | return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group); |
203 | } | 187 | } |
204 | 188 | ||
205 | 189 | ||
206 | static int tc1100_remove(struct platform_device *device) | 190 | static int __devexit tc1100_remove(struct platform_device *device) |
207 | { | 191 | { |
208 | sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group); | 192 | sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group); |
209 | 193 | ||
@@ -240,31 +224,49 @@ static int tc1100_resume(struct platform_device *dev) | |||
240 | return ret; | 224 | return ret; |
241 | } | 225 | } |
242 | 226 | ||
227 | static struct platform_driver tc1100_driver = { | ||
228 | .driver = { | ||
229 | .name = "tc1100-wmi", | ||
230 | .owner = THIS_MODULE, | ||
231 | }, | ||
232 | .remove = __devexit_p(tc1100_remove), | ||
233 | .suspend = tc1100_suspend, | ||
234 | .resume = tc1100_resume, | ||
235 | }; | ||
236 | |||
243 | static int __init tc1100_init(void) | 237 | static int __init tc1100_init(void) |
244 | { | 238 | { |
245 | int result = 0; | 239 | int error; |
246 | 240 | ||
247 | if (!wmi_has_guid(GUID)) | 241 | if (!wmi_has_guid(GUID)) |
248 | return -ENODEV; | 242 | return -ENODEV; |
249 | 243 | ||
250 | result = platform_driver_register(&tc1100_driver); | ||
251 | if (result) | ||
252 | return result; | ||
253 | |||
254 | tc1100_device = platform_device_alloc("tc1100-wmi", -1); | 244 | tc1100_device = platform_device_alloc("tc1100-wmi", -1); |
255 | platform_device_add(tc1100_device); | 245 | if (!tc1100_device) |
246 | return -ENOMEM; | ||
247 | |||
248 | error = platform_device_add(tc1100_device); | ||
249 | if (error) | ||
250 | goto err_device_put; | ||
251 | |||
252 | error = platform_driver_probe(&tc1100_driver, tc1100_probe); | ||
253 | if (error) | ||
254 | goto err_device_del; | ||
256 | 255 | ||
257 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); | 256 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); |
257 | return 0; | ||
258 | 258 | ||
259 | return result; | 259 | err_device_del: |
260 | platform_device_del(tc1100_device); | ||
261 | err_device_put: | ||
262 | platform_device_put(tc1100_device); | ||
263 | return error; | ||
260 | } | 264 | } |
261 | 265 | ||
262 | static void __exit tc1100_exit(void) | 266 | static void __exit tc1100_exit(void) |
263 | { | 267 | { |
264 | platform_device_del(tc1100_device); | 268 | platform_device_unregister(tc1100_device); |
265 | platform_driver_unregister(&tc1100_driver); | 269 | platform_driver_unregister(&tc1100_driver); |
266 | |||
267 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras unloaded\n"); | ||
268 | } | 270 | } |
269 | 271 | ||
270 | module_init(tc1100_init); | 272 | module_init(tc1100_init); |