diff options
Diffstat (limited to 'drivers/power/ltc2941-battery-gauge.c')
-rw-r--r-- | drivers/power/ltc2941-battery-gauge.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/power/ltc2941-battery-gauge.c b/drivers/power/ltc2941-battery-gauge.c index 9bc545393ef8..daeb0860736c 100644 --- a/drivers/power/ltc2941-battery-gauge.c +++ b/drivers/power/ltc2941-battery-gauge.c | |||
@@ -59,7 +59,8 @@ enum ltc294x_reg { | |||
59 | 59 | ||
60 | struct ltc294x_info { | 60 | struct ltc294x_info { |
61 | struct i2c_client *client; /* I2C Client pointer */ | 61 | struct i2c_client *client; /* I2C Client pointer */ |
62 | struct power_supply supply; /* Supply pointer */ | 62 | struct power_supply *supply; /* Supply pointer */ |
63 | struct power_supply_desc supply_desc; /* Supply description */ | ||
63 | struct delayed_work work; /* Work scheduler */ | 64 | struct delayed_work work; /* Work scheduler */ |
64 | int num_regs; /* Number of registers (chip type) */ | 65 | int num_regs; /* Number of registers (chip type) */ |
65 | int id; /* Identifier of ltc294x chip */ | 66 | int id; /* Identifier of ltc294x chip */ |
@@ -294,8 +295,7 @@ static int ltc294x_get_property(struct power_supply *psy, | |||
294 | enum power_supply_property prop, | 295 | enum power_supply_property prop, |
295 | union power_supply_propval *val) | 296 | union power_supply_propval *val) |
296 | { | 297 | { |
297 | struct ltc294x_info *info = | 298 | struct ltc294x_info *info = power_supply_get_drvdata(psy); |
298 | container_of(psy, struct ltc294x_info, supply); | ||
299 | 299 | ||
300 | switch (prop) { | 300 | switch (prop) { |
301 | case POWER_SUPPLY_PROP_CHARGE_NOW: | 301 | case POWER_SUPPLY_PROP_CHARGE_NOW: |
@@ -317,8 +317,7 @@ static int ltc294x_set_property(struct power_supply *psy, | |||
317 | enum power_supply_property psp, | 317 | enum power_supply_property psp, |
318 | const union power_supply_propval *val) | 318 | const union power_supply_propval *val) |
319 | { | 319 | { |
320 | struct ltc294x_info *info = | 320 | struct ltc294x_info *info = power_supply_get_drvdata(psy); |
321 | container_of(psy, struct ltc294x_info, supply); | ||
322 | 321 | ||
323 | switch (psp) { | 322 | switch (psp) { |
324 | case POWER_SUPPLY_PROP_CHARGE_NOW: | 323 | case POWER_SUPPLY_PROP_CHARGE_NOW: |
@@ -345,7 +344,7 @@ static void ltc294x_update(struct ltc294x_info *info) | |||
345 | 344 | ||
346 | if (charge != info->charge) { | 345 | if (charge != info->charge) { |
347 | info->charge = charge; | 346 | info->charge = charge; |
348 | power_supply_changed(&info->supply); | 347 | power_supply_changed(info->supply); |
349 | } | 348 | } |
350 | } | 349 | } |
351 | 350 | ||
@@ -371,8 +370,8 @@ static int ltc294x_i2c_remove(struct i2c_client *client) | |||
371 | struct ltc294x_info *info = i2c_get_clientdata(client); | 370 | struct ltc294x_info *info = i2c_get_clientdata(client); |
372 | 371 | ||
373 | cancel_delayed_work(&info->work); | 372 | cancel_delayed_work(&info->work); |
374 | power_supply_unregister(&info->supply); | 373 | power_supply_unregister(info->supply); |
375 | kfree(info->supply.name); | 374 | kfree(info->supply_desc.name); |
376 | mutex_lock(<c294x_lock); | 375 | mutex_lock(<c294x_lock); |
377 | idr_remove(<c294x_id, info->id); | 376 | idr_remove(<c294x_id, info->id); |
378 | mutex_unlock(<c294x_lock); | 377 | mutex_unlock(<c294x_lock); |
@@ -382,6 +381,7 @@ static int ltc294x_i2c_remove(struct i2c_client *client) | |||
382 | static int ltc294x_i2c_probe(struct i2c_client *client, | 381 | static int ltc294x_i2c_probe(struct i2c_client *client, |
383 | const struct i2c_device_id *id) | 382 | const struct i2c_device_id *id) |
384 | { | 383 | { |
384 | struct power_supply_config psy_cfg = {}; | ||
385 | struct ltc294x_info *info; | 385 | struct ltc294x_info *info; |
386 | int ret; | 386 | int ret; |
387 | int num; | 387 | int num; |
@@ -406,8 +406,9 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
406 | i2c_set_clientdata(client, info); | 406 | i2c_set_clientdata(client, info); |
407 | 407 | ||
408 | info->num_regs = id->driver_data; | 408 | info->num_regs = id->driver_data; |
409 | info->supply.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, num); | 409 | info->supply_desc.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, |
410 | if (!info->supply.name) { | 410 | num); |
411 | if (!info->supply_desc.name) { | ||
411 | ret = -ENOMEM; | 412 | ret = -ENOMEM; |
412 | goto fail_name; | 413 | goto fail_name; |
413 | } | 414 | } |
@@ -446,24 +447,26 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
446 | 447 | ||
447 | info->client = client; | 448 | info->client = client; |
448 | info->id = num; | 449 | info->id = num; |
449 | info->supply.type = POWER_SUPPLY_TYPE_BATTERY; | 450 | info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
450 | info->supply.properties = ltc294x_properties; | 451 | info->supply_desc.properties = ltc294x_properties; |
451 | if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) | 452 | if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) |
452 | info->supply.num_properties = | 453 | info->supply_desc.num_properties = |
453 | ARRAY_SIZE(ltc294x_properties); | 454 | ARRAY_SIZE(ltc294x_properties); |
454 | else if (info->num_regs >= LTC294X_REG_CURRENT_LSB) | 455 | else if (info->num_regs >= LTC294X_REG_CURRENT_LSB) |
455 | info->supply.num_properties = | 456 | info->supply_desc.num_properties = |
456 | ARRAY_SIZE(ltc294x_properties) - 1; | 457 | ARRAY_SIZE(ltc294x_properties) - 1; |
457 | else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB) | 458 | else if (info->num_regs >= LTC294X_REG_VOLTAGE_LSB) |
458 | info->supply.num_properties = | 459 | info->supply_desc.num_properties = |
459 | ARRAY_SIZE(ltc294x_properties) - 2; | 460 | ARRAY_SIZE(ltc294x_properties) - 2; |
460 | else | 461 | else |
461 | info->supply.num_properties = | 462 | info->supply_desc.num_properties = |
462 | ARRAY_SIZE(ltc294x_properties) - 3; | 463 | ARRAY_SIZE(ltc294x_properties) - 3; |
463 | info->supply.get_property = ltc294x_get_property; | 464 | info->supply_desc.get_property = ltc294x_get_property; |
464 | info->supply.set_property = ltc294x_set_property; | 465 | info->supply_desc.set_property = ltc294x_set_property; |
465 | info->supply.property_is_writeable = ltc294x_property_is_writeable; | 466 | info->supply_desc.property_is_writeable = ltc294x_property_is_writeable; |
466 | info->supply.external_power_changed = NULL; | 467 | info->supply_desc.external_power_changed = NULL; |
468 | |||
469 | psy_cfg.drv_data = info; | ||
467 | 470 | ||
468 | INIT_DELAYED_WORK(&info->work, ltc294x_work); | 471 | INIT_DELAYED_WORK(&info->work, ltc294x_work); |
469 | 472 | ||
@@ -473,9 +476,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
473 | goto fail_comm; | 476 | goto fail_comm; |
474 | } | 477 | } |
475 | 478 | ||
476 | ret = power_supply_register(&client->dev, &info->supply, NULL); | 479 | info->supply = power_supply_register(&client->dev, &info->supply_desc, |
477 | if (ret) { | 480 | &psy_cfg); |
481 | if (IS_ERR(info->supply)) { | ||
478 | dev_err(&client->dev, "failed to register ltc2941\n"); | 482 | dev_err(&client->dev, "failed to register ltc2941\n"); |
483 | ret = PTR_ERR(info->supply); | ||
479 | goto fail_register; | 484 | goto fail_register; |
480 | } else { | 485 | } else { |
481 | schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); | 486 | schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); |
@@ -484,7 +489,7 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
484 | return 0; | 489 | return 0; |
485 | 490 | ||
486 | fail_register: | 491 | fail_register: |
487 | kfree(info->supply.name); | 492 | kfree(info->supply_desc.name); |
488 | fail_comm: | 493 | fail_comm: |
489 | fail_name: | 494 | fail_name: |
490 | fail_info: | 495 | fail_info: |