aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/ipaq_micro_battery.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/ipaq_micro_battery.c')
-rw-r--r--drivers/power/ipaq_micro_battery.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/power/ipaq_micro_battery.c b/drivers/power/ipaq_micro_battery.c
index 9d694605cdb7..f03014ea1dc4 100644
--- a/drivers/power/ipaq_micro_battery.c
+++ b/drivers/power/ipaq_micro_battery.c
@@ -93,7 +93,7 @@ static void micro_battery_work(struct work_struct *work)
static int get_capacity(struct power_supply *b)
{
- struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+ struct micro_battery *mb = dev_get_drvdata(b->dev.parent);
switch (mb->flag & 0x07) {
case MICRO_BATT_STATUS_HIGH:
@@ -113,7 +113,7 @@ static int get_capacity(struct power_supply *b)
static int get_status(struct power_supply *b)
{
- struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+ struct micro_battery *mb = dev_get_drvdata(b->dev.parent);
if (mb->flag == MICRO_BATT_STATUS_UNKNOWN)
return POWER_SUPPLY_STATUS_UNKNOWN;
@@ -132,7 +132,7 @@ static int micro_batt_get_property(struct power_supply *b,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+ struct micro_battery *mb = dev_get_drvdata(b->dev.parent);
switch (psp) {
case POWER_SUPPLY_PROP_TECHNOLOGY:
@@ -180,7 +180,7 @@ static int micro_ac_get_property(struct power_supply *b,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+ struct micro_battery *mb = dev_get_drvdata(b->dev.parent);
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
@@ -202,7 +202,7 @@ static enum power_supply_property micro_batt_power_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
};
-static struct power_supply micro_batt_power = {
+static const struct power_supply_desc micro_batt_power_desc = {
.name = "main-battery",
.type = POWER_SUPPLY_TYPE_BATTERY,
.properties = micro_batt_power_props,
@@ -215,7 +215,7 @@ static enum power_supply_property micro_ac_power_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
-static struct power_supply micro_ac_power = {
+static const struct power_supply_desc micro_ac_power_desc = {
.name = "ac",
.type = POWER_SUPPLY_TYPE_MAINS,
.properties = micro_ac_power_props,
@@ -223,9 +223,12 @@ static struct power_supply micro_ac_power = {
.get_property = micro_ac_get_property,
};
+static struct power_supply *micro_batt_power, *micro_ac_power;
+
static int micro_batt_probe(struct platform_device *pdev)
{
struct micro_battery *mb;
+ int ret;
mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL);
if (!mb)
@@ -233,14 +236,36 @@ static int micro_batt_probe(struct platform_device *pdev)
mb->micro = dev_get_drvdata(pdev->dev.parent);
mb->wq = create_singlethread_workqueue("ipaq-battery-wq");
+ if (!mb->wq)
+ return -ENOMEM;
+
INIT_DELAYED_WORK(&mb->update, micro_battery_work);
platform_set_drvdata(pdev, mb);
queue_delayed_work(mb->wq, &mb->update, 1);
- power_supply_register(&pdev->dev, &micro_batt_power);
- power_supply_register(&pdev->dev, &micro_ac_power);
+
+ micro_batt_power = power_supply_register(&pdev->dev,
+ &micro_batt_power_desc, NULL);
+ if (IS_ERR(micro_batt_power)) {
+ ret = PTR_ERR(micro_batt_power);
+ goto batt_err;
+ }
+
+ micro_ac_power = power_supply_register(&pdev->dev,
+ &micro_ac_power_desc, NULL);
+ if (IS_ERR(micro_ac_power)) {
+ ret = PTR_ERR(micro_ac_power);
+ goto ac_err;
+ }
dev_info(&pdev->dev, "iPAQ micro battery driver\n");
return 0;
+
+ac_err:
+ power_supply_unregister(micro_ac_power);
+batt_err:
+ cancel_delayed_work_sync(&mb->update);
+ destroy_workqueue(mb->wq);
+ return ret;
}
static int micro_batt_remove(struct platform_device *pdev)
@@ -248,9 +273,10 @@ static int micro_batt_remove(struct platform_device *pdev)
{
struct micro_battery *mb = platform_get_drvdata(pdev);
- power_supply_unregister(&micro_ac_power);
- power_supply_unregister(&micro_batt_power);
+ power_supply_unregister(micro_ac_power);
+ power_supply_unregister(micro_batt_power);
cancel_delayed_work_sync(&mb->update);
+ destroy_workqueue(mb->wq);
return 0;
}