diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2011-09-05 12:45:28 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-09-07 07:32:34 -0400 |
commit | dde58cfcc3b6dd2f160ffd355f76ae526155a4df (patch) | |
tree | 519419a6ef60a0a0f3b17a0ec3c7c12ce268843d | |
parent | 6d1db0777981e1626ae71243984ac300b61789ff (diff) |
HID: wacom: Fix error path of power-supply initialization
power_supply_unregister() must not be called if power_supply_register() failed.
The wdata->psy.dev pointer may point to invalid memory after a failed
power_supply_register() and hence wacom_remove() will fail while calling
power_supply_unregister().
This changes the wacom_probe function to fail if it cannot register the
power_supply devices. If we would want to keep the previous behaviour we had to
keep some flag about the power_supply state and check it on wacom_remove, but
this seems inappropriate here. Hence, we simply fail, too, if
power_supply_register fails.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-wacom.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 06888323828c..f66a597cff63 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -353,11 +353,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
353 | if (ret) { | 353 | if (ret) { |
354 | hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", | 354 | hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", |
355 | ret); | 355 | ret); |
356 | /* | 356 | goto err_battery; |
357 | * battery attribute is not critical for the tablet, but if it | ||
358 | * failed then there is no need to create ac attribute | ||
359 | */ | ||
360 | goto move_on; | ||
361 | } | 357 | } |
362 | 358 | ||
363 | wdata->ac.properties = wacom_ac_props; | 359 | wdata->ac.properties = wacom_ac_props; |
@@ -371,14 +367,8 @@ static int wacom_probe(struct hid_device *hdev, | |||
371 | if (ret) { | 367 | if (ret) { |
372 | hid_warn(hdev, | 368 | hid_warn(hdev, |
373 | "can't create ac battery attribute, err: %d\n", ret); | 369 | "can't create ac battery attribute, err: %d\n", ret); |
374 | /* | 370 | goto err_ac; |
375 | * ac attribute is not critical for the tablet, but if it | ||
376 | * failed then we don't want to battery attribute to exist | ||
377 | */ | ||
378 | power_supply_unregister(&wdata->battery); | ||
379 | } | 371 | } |
380 | |||
381 | move_on: | ||
382 | #endif | 372 | #endif |
383 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); | 373 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); |
384 | input = hidinput->input; | 374 | input = hidinput->input; |
@@ -416,6 +406,13 @@ move_on: | |||
416 | 406 | ||
417 | return 0; | 407 | return 0; |
418 | 408 | ||
409 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
410 | err_ac: | ||
411 | power_supply_unregister(&wdata->battery); | ||
412 | err_battery: | ||
413 | device_remove_file(&hdev->dev, &dev_attr_speed); | ||
414 | hid_hw_stop(hdev); | ||
415 | #endif | ||
419 | err_free: | 416 | err_free: |
420 | kfree(wdata); | 417 | kfree(wdata); |
421 | return ret; | 418 | return ret; |