diff options
| author | Clifton Barnes <cabarnes@indesign-llc.com> | 2011-11-02 16:39:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:03 -0400 |
| commit | 0e053fcbbbc4d945247cb32cad2767b483cb65f8 (patch) | |
| tree | 7d933aba540f68b8117b4789bc39d4f4eb1de309 | |
| parent | 9fe678fa2feb4aaac0b4220de63e1b7f8ccebae6 (diff) | |
drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
Fixes the deadlock when inserting and removing the ds2780.
Signed-off-by: Clifton Barnes <cabarnes@indesign-llc.com>
Cc: Evgeniy Polyakov <zbr@ioremap.net>
Cc: <stable@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/power/ds2780_battery.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index 2571b4143784..91a783d72360 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c | |||
| @@ -39,6 +39,7 @@ struct ds2780_device_info { | |||
| 39 | struct device *dev; | 39 | struct device *dev; |
| 40 | struct power_supply bat; | 40 | struct power_supply bat; |
| 41 | struct device *w1_dev; | 41 | struct device *w1_dev; |
| 42 | struct task_struct *mutex_holder; | ||
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| 44 | enum current_types { | 45 | enum current_types { |
| @@ -63,6 +64,9 @@ static inline struct power_supply *to_power_supply(struct device *dev) | |||
| 63 | static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, | 64 | static inline int ds2780_battery_io(struct ds2780_device_info *dev_info, |
| 64 | char *buf, int addr, size_t count, int io) | 65 | char *buf, int addr, size_t count, int io) |
| 65 | { | 66 | { |
| 67 | if (dev_info->mutex_holder == current) | ||
| 68 | return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io); | ||
| 69 | else | ||
| 66 | return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); | 70 | return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io); |
| 67 | } | 71 | } |
| 68 | 72 | ||
| @@ -775,6 +779,7 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) | |||
| 775 | dev_info->bat.properties = ds2780_battery_props; | 779 | dev_info->bat.properties = ds2780_battery_props; |
| 776 | dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); | 780 | dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); |
| 777 | dev_info->bat.get_property = ds2780_battery_get_property; | 781 | dev_info->bat.get_property = ds2780_battery_get_property; |
| 782 | dev_info->mutex_holder = current; | ||
| 778 | 783 | ||
| 779 | ret = power_supply_register(&pdev->dev, &dev_info->bat); | 784 | ret = power_supply_register(&pdev->dev, &dev_info->bat); |
| 780 | if (ret) { | 785 | if (ret) { |
| @@ -804,6 +809,8 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev) | |||
| 804 | goto fail_remove_bin_file; | 809 | goto fail_remove_bin_file; |
| 805 | } | 810 | } |
| 806 | 811 | ||
| 812 | dev_info->mutex_holder = NULL; | ||
| 813 | |||
| 807 | return 0; | 814 | return 0; |
| 808 | 815 | ||
| 809 | fail_remove_bin_file: | 816 | fail_remove_bin_file: |
| @@ -823,6 +830,8 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev) | |||
| 823 | { | 830 | { |
| 824 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); | 831 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); |
| 825 | 832 | ||
| 833 | dev_info->mutex_holder = current; | ||
| 834 | |||
| 826 | /* remove attributes */ | 835 | /* remove attributes */ |
| 827 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); | 836 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); |
| 828 | 837 | ||
