Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e053fcb authored by Clifton Barnes's avatar Clifton Barnes Committed by Linus Torvalds
Browse files

drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal



Fixes the deadlock when inserting and removing the ds2780.

Signed-off-by: default avatarClifton Barnes <cabarnes@indesign-llc.com>
Cc: Evgeniy Polyakov <zbr@ioremap.net>
Cc: <stable@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9fe678fa
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ struct ds2780_device_info {
	struct device *dev;
	struct device *dev;
	struct power_supply bat;
	struct power_supply bat;
	struct device *w1_dev;
	struct device *w1_dev;
	struct task_struct *mutex_holder;
};
};


enum current_types {
enum current_types {
@@ -63,6 +64,9 @@ static inline struct power_supply *to_power_supply(struct device *dev)
static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
static inline int ds2780_battery_io(struct ds2780_device_info *dev_info,
	char *buf, int addr, size_t count, int io)
	char *buf, int addr, size_t count, int io)
{
{
	if (dev_info->mutex_holder == current)
		return w1_ds2780_io_nolock(dev_info->w1_dev, buf, addr, count, io);
	else
		return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
		return w1_ds2780_io(dev_info->w1_dev, buf, addr, count, io);
}
}


@@ -775,6 +779,7 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev)
	dev_info->bat.properties	= ds2780_battery_props;
	dev_info->bat.properties	= ds2780_battery_props;
	dev_info->bat.num_properties	= ARRAY_SIZE(ds2780_battery_props);
	dev_info->bat.num_properties	= ARRAY_SIZE(ds2780_battery_props);
	dev_info->bat.get_property	= ds2780_battery_get_property;
	dev_info->bat.get_property	= ds2780_battery_get_property;
	dev_info->mutex_holder		= current;


	ret = power_supply_register(&pdev->dev, &dev_info->bat);
	ret = power_supply_register(&pdev->dev, &dev_info->bat);
	if (ret) {
	if (ret) {
@@ -804,6 +809,8 @@ static int __devinit ds2780_battery_probe(struct platform_device *pdev)
		goto fail_remove_bin_file;
		goto fail_remove_bin_file;
	}
	}


	dev_info->mutex_holder = NULL;

	return 0;
	return 0;


fail_remove_bin_file:
fail_remove_bin_file:
@@ -823,6 +830,8 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev)
{
{
	struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
	struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);


	dev_info->mutex_holder = current;

	/* remove attributes */
	/* remove attributes */
	sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
	sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);