diff options
106 files changed, 5435 insertions, 2104 deletions
diff --git a/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt b/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt new file mode 100644 index 000000000000..c07228da92ac --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | Dialog Semiconductor DA9150 IIO GPADC bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "dlg,da9150-gpadc" for DA9150 IIO GPADC | ||
| 5 | - #io-channel-cells: Should be set to <1> | ||
| 6 | (See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info) | ||
| 7 | |||
| 8 | For further information on GPADC channels, see device datasheet. | ||
| 9 | |||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | gpadc: da9150-gpadc { | ||
| 14 | compatible = "dlg,da9150-gpadc"; | ||
| 15 | #io-channel-cells = <1>; | ||
| 16 | }; | ||
diff --git a/Documentation/devicetree/bindings/power/da9150-charger.txt b/Documentation/devicetree/bindings/power/da9150-charger.txt new file mode 100644 index 000000000000..f3906663c454 --- /dev/null +++ b/Documentation/devicetree/bindings/power/da9150-charger.txt | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | Dialog Semiconductor DA9150 Charger Power Supply bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "dlg,da9150-charger" for DA9150 Charger Power Supply | ||
| 5 | |||
| 6 | Optional properties: | ||
| 7 | - io-channels: List of phandle and IIO specifier pairs | ||
| 8 | - io-channel-names: List of channel names used by charger | ||
| 9 | ["CHAN_IBUS", "CHAN_VBUS", "CHAN_TJUNC", "CHAN_VBAT"] | ||
| 10 | (See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info) | ||
| 11 | |||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | da9150-charger { | ||
| 16 | compatible = "dlg,da9150-charger"; | ||
| 17 | |||
| 18 | io-channels = <&gpadc 0>, | ||
| 19 | <&gpadc 2>, | ||
| 20 | <&gpadc 8>, | ||
| 21 | <&gpadc 5>; | ||
| 22 | io-channel-names = "CHAN_IBUS", | ||
| 23 | "CHAN_VBUS", | ||
| 24 | "CHAN_TJUNC", | ||
| 25 | "CHAN_VBAT"; | ||
| 26 | }; | ||
diff --git a/Documentation/devicetree/bindings/power/reset/syscon-poweroff.txt b/Documentation/devicetree/bindings/power/reset/syscon-poweroff.txt new file mode 100644 index 000000000000..1e2546f8b08a --- /dev/null +++ b/Documentation/devicetree/bindings/power/reset/syscon-poweroff.txt | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | Generic SYSCON mapped register poweroff driver | ||
| 2 | |||
| 3 | This is a generic poweroff driver using syscon to map the poweroff register. | ||
| 4 | The poweroff is generally performed with a write to the poweroff register | ||
| 5 | defined by the register map pointed by syscon reference plus the offset | ||
| 6 | with the mask defined in the poweroff node. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - compatible: should contain "syscon-poweroff" | ||
| 10 | - regmap: this is phandle to the register map node | ||
| 11 | - offset: offset in the register map for the poweroff register (in bytes) | ||
| 12 | - mask: the poweroff value written to the poweroff register (32 bit access) | ||
| 13 | |||
| 14 | Default will be little endian mode, 32 bit access only. | ||
| 15 | |||
| 16 | Examples: | ||
| 17 | |||
| 18 | poweroff { | ||
| 19 | compatible = "syscon-poweroff"; | ||
| 20 | regmap = <®mapnode>; | ||
| 21 | offset = <0x0>; | ||
| 22 | mask = <0x7a>; | ||
| 23 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 8d2ee8e010a1..a123c39b4f0e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3137,12 +3137,15 @@ S: Supported | |||
| 3137 | F: Documentation/hwmon/da90?? | 3137 | F: Documentation/hwmon/da90?? |
| 3138 | F: drivers/gpio/gpio-da90??.c | 3138 | F: drivers/gpio/gpio-da90??.c |
| 3139 | F: drivers/hwmon/da90??-hwmon.c | 3139 | F: drivers/hwmon/da90??-hwmon.c |
| 3140 | F: drivers/iio/adc/da91??-*.c | ||
| 3140 | F: drivers/input/misc/da90??_onkey.c | 3141 | F: drivers/input/misc/da90??_onkey.c |
| 3141 | F: drivers/input/touchscreen/da9052_tsi.c | 3142 | F: drivers/input/touchscreen/da9052_tsi.c |
| 3142 | F: drivers/leds/leds-da90??.c | 3143 | F: drivers/leds/leds-da90??.c |
| 3143 | F: drivers/mfd/da903x.c | 3144 | F: drivers/mfd/da903x.c |
| 3144 | F: drivers/mfd/da90??-*.c | 3145 | F: drivers/mfd/da90??-*.c |
| 3146 | F: drivers/mfd/da91??-*.c | ||
| 3145 | F: drivers/power/da9052-battery.c | 3147 | F: drivers/power/da9052-battery.c |
| 3148 | F: drivers/power/da91??-*.c | ||
| 3146 | F: drivers/regulator/da903x.c | 3149 | F: drivers/regulator/da903x.c |
| 3147 | F: drivers/regulator/da9???-regulator.[ch] | 3150 | F: drivers/regulator/da9???-regulator.[ch] |
| 3148 | F: drivers/rtc/rtc-da90??.c | 3151 | F: drivers/rtc/rtc-da90??.c |
| @@ -3152,6 +3155,7 @@ F: include/linux/mfd/da903x.h | |||
| 3152 | F: include/linux/mfd/da9052/ | 3155 | F: include/linux/mfd/da9052/ |
| 3153 | F: include/linux/mfd/da9055/ | 3156 | F: include/linux/mfd/da9055/ |
| 3154 | F: include/linux/mfd/da9063/ | 3157 | F: include/linux/mfd/da9063/ |
| 3158 | F: include/linux/mfd/da9150/ | ||
| 3155 | F: include/sound/da[79]*.h | 3159 | F: include/sound/da[79]*.h |
| 3156 | F: sound/soc/codecs/da[79]*.[ch] | 3160 | F: sound/soc/codecs/da[79]*.[ch] |
| 3157 | 3161 | ||
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index a762b23ac830..6dc4f025e674 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
| @@ -758,8 +758,10 @@ static void raumfeld_power_signal_charged(void) | |||
| 758 | struct power_supply *psy = | 758 | struct power_supply *psy = |
| 759 | power_supply_get_by_name(raumfeld_power_supplicants[0]); | 759 | power_supply_get_by_name(raumfeld_power_supplicants[0]); |
| 760 | 760 | ||
| 761 | if (psy) | 761 | if (psy) { |
| 762 | power_supply_set_battery_charged(psy); | 762 | power_supply_set_battery_charged(psy); |
| 763 | power_supply_put(psy); | ||
| 764 | } | ||
| 763 | } | 765 | } |
| 764 | 766 | ||
| 765 | static int raumfeld_power_resume(void) | 767 | static int raumfeld_power_resume(void) |
diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c index 9a2e590dd202..7fa8b3b53bc0 100644 --- a/arch/x86/platform/olpc/olpc-xo1-sci.c +++ b/arch/x86/platform/olpc/olpc-xo1-sci.c | |||
| @@ -61,7 +61,7 @@ static void battery_status_changed(void) | |||
| 61 | 61 | ||
| 62 | if (psy) { | 62 | if (psy) { |
| 63 | power_supply_changed(psy); | 63 | power_supply_changed(psy); |
| 64 | put_device(psy->dev); | 64 | power_supply_put(psy); |
| 65 | } | 65 | } |
| 66 | } | 66 | } |
| 67 | 67 | ||
| @@ -71,7 +71,7 @@ static void ac_status_changed(void) | |||
| 71 | 71 | ||
| 72 | if (psy) { | 72 | if (psy) { |
| 73 | power_supply_changed(psy); | 73 | power_supply_changed(psy); |
| 74 | put_device(psy->dev); | 74 | power_supply_put(psy); |
| 75 | } | 75 | } |
| 76 | } | 76 | } |
| 77 | 77 | ||
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 08e350e757dc..55130846ac87 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c | |||
| @@ -83,7 +83,7 @@ static void battery_status_changed(void) | |||
| 83 | 83 | ||
| 84 | if (psy) { | 84 | if (psy) { |
| 85 | power_supply_changed(psy); | 85 | power_supply_changed(psy); |
| 86 | put_device(psy->dev); | 86 | power_supply_put(psy); |
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | 89 | ||
| @@ -93,7 +93,7 @@ static void ac_status_changed(void) | |||
| 93 | 93 | ||
| 94 | if (psy) { | 94 | if (psy) { |
| 95 | power_supply_changed(psy); | 95 | power_supply_changed(psy); |
| 96 | put_device(psy->dev); | 96 | power_supply_put(psy); |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | 99 | ||
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 36b0e61f9c09..bbcc2b5a70d4 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
| @@ -95,13 +95,14 @@ static struct acpi_driver acpi_ac_driver = { | |||
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | struct acpi_ac { | 97 | struct acpi_ac { |
| 98 | struct power_supply charger; | 98 | struct power_supply *charger; |
| 99 | struct power_supply_desc charger_desc; | ||
| 99 | struct acpi_device * device; | 100 | struct acpi_device * device; |
| 100 | unsigned long long state; | 101 | unsigned long long state; |
| 101 | struct notifier_block battery_nb; | 102 | struct notifier_block battery_nb; |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) | 105 | #define to_acpi_ac(x) power_supply_get_drvdata(x) |
| 105 | 106 | ||
| 106 | #ifdef CONFIG_ACPI_PROCFS_POWER | 107 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 107 | static const struct file_operations acpi_ac_fops = { | 108 | static const struct file_operations acpi_ac_fops = { |
| @@ -275,7 +276,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
| 275 | dev_name(&device->dev), event, | 276 | dev_name(&device->dev), event, |
| 276 | (u32) ac->state); | 277 | (u32) ac->state); |
| 277 | acpi_notifier_call_chain(device, event, (u32) ac->state); | 278 | acpi_notifier_call_chain(device, event, (u32) ac->state); |
| 278 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 279 | kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); |
| 279 | } | 280 | } |
| 280 | 281 | ||
| 281 | return; | 282 | return; |
| @@ -321,6 +322,7 @@ static struct dmi_system_id ac_dmi_table[] = { | |||
| 321 | 322 | ||
| 322 | static int acpi_ac_add(struct acpi_device *device) | 323 | static int acpi_ac_add(struct acpi_device *device) |
| 323 | { | 324 | { |
| 325 | struct power_supply_config psy_cfg = {}; | ||
| 324 | int result = 0; | 326 | int result = 0; |
| 325 | struct acpi_ac *ac = NULL; | 327 | struct acpi_ac *ac = NULL; |
| 326 | 328 | ||
| @@ -341,19 +343,24 @@ static int acpi_ac_add(struct acpi_device *device) | |||
| 341 | if (result) | 343 | if (result) |
| 342 | goto end; | 344 | goto end; |
| 343 | 345 | ||
| 344 | ac->charger.name = acpi_device_bid(device); | 346 | psy_cfg.drv_data = ac; |
| 347 | |||
| 348 | ac->charger_desc.name = acpi_device_bid(device); | ||
| 345 | #ifdef CONFIG_ACPI_PROCFS_POWER | 349 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 346 | result = acpi_ac_add_fs(ac); | 350 | result = acpi_ac_add_fs(ac); |
| 347 | if (result) | 351 | if (result) |
| 348 | goto end; | 352 | goto end; |
| 349 | #endif | 353 | #endif |
| 350 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; | 354 | ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS; |
| 351 | ac->charger.properties = ac_props; | 355 | ac->charger_desc.properties = ac_props; |
| 352 | ac->charger.num_properties = ARRAY_SIZE(ac_props); | 356 | ac->charger_desc.num_properties = ARRAY_SIZE(ac_props); |
| 353 | ac->charger.get_property = get_ac_property; | 357 | ac->charger_desc.get_property = get_ac_property; |
| 354 | result = power_supply_register(&ac->device->dev, &ac->charger); | 358 | ac->charger = power_supply_register(&ac->device->dev, |
| 355 | if (result) | 359 | &ac->charger_desc, &psy_cfg); |
| 360 | if (IS_ERR(ac->charger)) { | ||
| 361 | result = PTR_ERR(ac->charger); | ||
| 356 | goto end; | 362 | goto end; |
| 363 | } | ||
| 357 | 364 | ||
| 358 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 365 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
| 359 | acpi_device_name(device), acpi_device_bid(device), | 366 | acpi_device_name(device), acpi_device_bid(device), |
| @@ -390,7 +397,7 @@ static int acpi_ac_resume(struct device *dev) | |||
| 390 | if (acpi_ac_get_state(ac)) | 397 | if (acpi_ac_get_state(ac)) |
| 391 | return 0; | 398 | return 0; |
| 392 | if (old_state != ac->state) | 399 | if (old_state != ac->state) |
| 393 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 400 | kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); |
| 394 | return 0; | 401 | return 0; |
| 395 | } | 402 | } |
| 396 | #else | 403 | #else |
| @@ -407,8 +414,7 @@ static int acpi_ac_remove(struct acpi_device *device) | |||
| 407 | 414 | ||
| 408 | ac = acpi_driver_data(device); | 415 | ac = acpi_driver_data(device); |
| 409 | 416 | ||
| 410 | if (ac->charger.dev) | 417 | power_supply_unregister(ac->charger); |
| 411 | power_supply_unregister(&ac->charger); | ||
| 412 | unregister_acpi_notifier(&ac->battery_nb); | 418 | unregister_acpi_notifier(&ac->battery_nb); |
| 413 | 419 | ||
| 414 | #ifdef CONFIG_ACPI_PROCFS_POWER | 420 | #ifdef CONFIG_ACPI_PROCFS_POWER |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d98ba4355819..fdc16ce9d272 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -117,7 +117,8 @@ enum { | |||
| 117 | struct acpi_battery { | 117 | struct acpi_battery { |
| 118 | struct mutex lock; | 118 | struct mutex lock; |
| 119 | struct mutex sysfs_lock; | 119 | struct mutex sysfs_lock; |
| 120 | struct power_supply bat; | 120 | struct power_supply *bat; |
| 121 | struct power_supply_desc bat_desc; | ||
| 121 | struct acpi_device *device; | 122 | struct acpi_device *device; |
| 122 | struct notifier_block pm_nb; | 123 | struct notifier_block pm_nb; |
| 123 | unsigned long update_time; | 124 | unsigned long update_time; |
| @@ -149,7 +150,7 @@ struct acpi_battery { | |||
| 149 | unsigned long flags; | 150 | unsigned long flags; |
| 150 | }; | 151 | }; |
| 151 | 152 | ||
| 152 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat) | 153 | #define to_acpi_battery(x) power_supply_get_drvdata(x) |
| 153 | 154 | ||
| 154 | static inline int acpi_battery_present(struct acpi_battery *battery) | 155 | static inline int acpi_battery_present(struct acpi_battery *battery) |
| 155 | { | 156 | { |
| @@ -608,40 +609,45 @@ static struct device_attribute alarm_attr = { | |||
| 608 | 609 | ||
| 609 | static int sysfs_add_battery(struct acpi_battery *battery) | 610 | static int sysfs_add_battery(struct acpi_battery *battery) |
| 610 | { | 611 | { |
| 611 | int result; | 612 | struct power_supply_config psy_cfg = { .drv_data = battery, }; |
| 612 | 613 | ||
| 613 | if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { | 614 | if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { |
| 614 | battery->bat.properties = charge_battery_props; | 615 | battery->bat_desc.properties = charge_battery_props; |
| 615 | battery->bat.num_properties = | 616 | battery->bat_desc.num_properties = |
| 616 | ARRAY_SIZE(charge_battery_props); | 617 | ARRAY_SIZE(charge_battery_props); |
| 617 | } else { | 618 | } else { |
| 618 | battery->bat.properties = energy_battery_props; | 619 | battery->bat_desc.properties = energy_battery_props; |
| 619 | battery->bat.num_properties = | 620 | battery->bat_desc.num_properties = |
| 620 | ARRAY_SIZE(energy_battery_props); | 621 | ARRAY_SIZE(energy_battery_props); |
| 621 | } | 622 | } |
| 622 | 623 | ||
| 623 | battery->bat.name = acpi_device_bid(battery->device); | 624 | battery->bat_desc.name = acpi_device_bid(battery->device); |
| 624 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 625 | battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 625 | battery->bat.get_property = acpi_battery_get_property; | 626 | battery->bat_desc.get_property = acpi_battery_get_property; |
| 626 | 627 | ||
| 627 | result = power_supply_register_no_ws(&battery->device->dev, &battery->bat); | 628 | battery->bat = power_supply_register_no_ws(&battery->device->dev, |
| 629 | &battery->bat_desc, &psy_cfg); | ||
| 628 | 630 | ||
| 629 | if (result) | 631 | if (IS_ERR(battery->bat)) { |
| 632 | int result = PTR_ERR(battery->bat); | ||
| 633 | |||
| 634 | battery->bat = NULL; | ||
| 630 | return result; | 635 | return result; |
| 631 | return device_create_file(battery->bat.dev, &alarm_attr); | 636 | } |
| 637 | return device_create_file(&battery->bat->dev, &alarm_attr); | ||
| 632 | } | 638 | } |
| 633 | 639 | ||
| 634 | static void sysfs_remove_battery(struct acpi_battery *battery) | 640 | static void sysfs_remove_battery(struct acpi_battery *battery) |
| 635 | { | 641 | { |
| 636 | mutex_lock(&battery->sysfs_lock); | 642 | mutex_lock(&battery->sysfs_lock); |
| 637 | if (!battery->bat.dev) { | 643 | if (!battery->bat) { |
| 638 | mutex_unlock(&battery->sysfs_lock); | 644 | mutex_unlock(&battery->sysfs_lock); |
| 639 | return; | 645 | return; |
| 640 | } | 646 | } |
| 641 | 647 | ||
| 642 | device_remove_file(battery->bat.dev, &alarm_attr); | 648 | device_remove_file(&battery->bat->dev, &alarm_attr); |
| 643 | power_supply_unregister(&battery->bat); | 649 | power_supply_unregister(battery->bat); |
| 644 | battery->bat.dev = NULL; | 650 | battery->bat = NULL; |
| 645 | mutex_unlock(&battery->sysfs_lock); | 651 | mutex_unlock(&battery->sysfs_lock); |
| 646 | } | 652 | } |
| 647 | 653 | ||
| @@ -738,7 +744,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) | |||
| 738 | return result; | 744 | return result; |
| 739 | acpi_battery_init_alarm(battery); | 745 | acpi_battery_init_alarm(battery); |
| 740 | } | 746 | } |
| 741 | if (!battery->bat.dev) { | 747 | if (!battery->bat) { |
| 742 | result = sysfs_add_battery(battery); | 748 | result = sysfs_add_battery(battery); |
| 743 | if (result) | 749 | if (result) |
| 744 | return result; | 750 | return result; |
| @@ -764,7 +770,7 @@ static void acpi_battery_refresh(struct acpi_battery *battery) | |||
| 764 | { | 770 | { |
| 765 | int power_unit; | 771 | int power_unit; |
| 766 | 772 | ||
| 767 | if (!battery->bat.dev) | 773 | if (!battery->bat) |
| 768 | return; | 774 | return; |
| 769 | 775 | ||
| 770 | power_unit = battery->power_unit; | 776 | power_unit = battery->power_unit; |
| @@ -1062,11 +1068,11 @@ static void acpi_battery_remove_fs(struct acpi_device *device) | |||
| 1062 | static void acpi_battery_notify(struct acpi_device *device, u32 event) | 1068 | static void acpi_battery_notify(struct acpi_device *device, u32 event) |
| 1063 | { | 1069 | { |
| 1064 | struct acpi_battery *battery = acpi_driver_data(device); | 1070 | struct acpi_battery *battery = acpi_driver_data(device); |
| 1065 | struct device *old; | 1071 | struct power_supply *old; |
| 1066 | 1072 | ||
| 1067 | if (!battery) | 1073 | if (!battery) |
| 1068 | return; | 1074 | return; |
| 1069 | old = battery->bat.dev; | 1075 | old = battery->bat; |
| 1070 | /* | 1076 | /* |
| 1071 | * On Acer Aspire V5-573G notifications are sometimes triggered too | 1077 | * On Acer Aspire V5-573G notifications are sometimes triggered too |
| 1072 | * early. For example, when AC is unplugged and notification is | 1078 | * early. For example, when AC is unplugged and notification is |
| @@ -1083,8 +1089,8 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
| 1083 | acpi_battery_present(battery)); | 1089 | acpi_battery_present(battery)); |
| 1084 | acpi_notifier_call_chain(device, event, acpi_battery_present(battery)); | 1090 | acpi_notifier_call_chain(device, event, acpi_battery_present(battery)); |
| 1085 | /* acpi_battery_update could remove power_supply object */ | 1091 | /* acpi_battery_update could remove power_supply object */ |
| 1086 | if (old && battery->bat.dev) | 1092 | if (old && battery->bat) |
| 1087 | power_supply_changed(&battery->bat); | 1093 | power_supply_changed(battery->bat); |
| 1088 | } | 1094 | } |
| 1089 | 1095 | ||
| 1090 | static int battery_notify(struct notifier_block *nb, | 1096 | static int battery_notify(struct notifier_block *nb, |
| @@ -1100,7 +1106,7 @@ static int battery_notify(struct notifier_block *nb, | |||
| 1100 | if (!acpi_battery_present(battery)) | 1106 | if (!acpi_battery_present(battery)) |
| 1101 | return 0; | 1107 | return 0; |
| 1102 | 1108 | ||
| 1103 | if (!battery->bat.dev) { | 1109 | if (battery->bat) { |
| 1104 | result = acpi_battery_get_info(battery); | 1110 | result = acpi_battery_get_info(battery); |
| 1105 | if (result) | 1111 | if (result) |
| 1106 | return result; | 1112 | return result; |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index a7a3edd28beb..cd827625cf07 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
| @@ -74,7 +74,8 @@ static const struct acpi_device_id sbs_device_ids[] = { | |||
| 74 | MODULE_DEVICE_TABLE(acpi, sbs_device_ids); | 74 | MODULE_DEVICE_TABLE(acpi, sbs_device_ids); |
| 75 | 75 | ||
| 76 | struct acpi_battery { | 76 | struct acpi_battery { |
| 77 | struct power_supply bat; | 77 | struct power_supply *bat; |
| 78 | struct power_supply_desc bat_desc; | ||
| 78 | struct acpi_sbs *sbs; | 79 | struct acpi_sbs *sbs; |
| 79 | unsigned long update_time; | 80 | unsigned long update_time; |
| 80 | char name[8]; | 81 | char name[8]; |
| @@ -101,10 +102,10 @@ struct acpi_battery { | |||
| 101 | u8 have_sysfs_alarm:1; | 102 | u8 have_sysfs_alarm:1; |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat) | 105 | #define to_acpi_battery(x) power_supply_get_drvdata(x) |
| 105 | 106 | ||
| 106 | struct acpi_sbs { | 107 | struct acpi_sbs { |
| 107 | struct power_supply charger; | 108 | struct power_supply *charger; |
| 108 | struct acpi_device *device; | 109 | struct acpi_device *device; |
| 109 | struct acpi_smb_hc *hc; | 110 | struct acpi_smb_hc *hc; |
| 110 | struct mutex lock; | 111 | struct mutex lock; |
| @@ -115,7 +116,7 @@ struct acpi_sbs { | |||
| 115 | u8 charger_exists:1; | 116 | u8 charger_exists:1; |
| 116 | }; | 117 | }; |
| 117 | 118 | ||
| 118 | #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) | 119 | #define to_acpi_sbs(x) power_supply_get_drvdata(x) |
| 119 | 120 | ||
| 120 | static int acpi_sbs_remove(struct acpi_device *device); | 121 | static int acpi_sbs_remove(struct acpi_device *device); |
| 121 | static int acpi_battery_get_state(struct acpi_battery *battery); | 122 | static int acpi_battery_get_state(struct acpi_battery *battery); |
| @@ -303,6 +304,13 @@ static enum power_supply_property sbs_energy_battery_props[] = { | |||
| 303 | POWER_SUPPLY_PROP_MANUFACTURER, | 304 | POWER_SUPPLY_PROP_MANUFACTURER, |
| 304 | }; | 305 | }; |
| 305 | 306 | ||
| 307 | static const struct power_supply_desc acpi_sbs_charger_desc = { | ||
| 308 | .name = "sbs-charger", | ||
| 309 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 310 | .properties = sbs_ac_props, | ||
| 311 | .num_properties = ARRAY_SIZE(sbs_ac_props), | ||
| 312 | .get_property = sbs_get_ac_property, | ||
| 313 | }; | ||
| 306 | 314 | ||
| 307 | /* -------------------------------------------------------------------------- | 315 | /* -------------------------------------------------------------------------- |
| 308 | Smart Battery System Management | 316 | Smart Battery System Management |
| @@ -519,6 +527,7 @@ static int acpi_battery_read(struct acpi_battery *battery) | |||
| 519 | static int acpi_battery_add(struct acpi_sbs *sbs, int id) | 527 | static int acpi_battery_add(struct acpi_sbs *sbs, int id) |
| 520 | { | 528 | { |
| 521 | struct acpi_battery *battery = &sbs->battery[id]; | 529 | struct acpi_battery *battery = &sbs->battery[id]; |
| 530 | struct power_supply_config psy_cfg = { .drv_data = battery, }; | ||
| 522 | int result; | 531 | int result; |
| 523 | 532 | ||
| 524 | battery->id = id; | 533 | battery->id = id; |
| @@ -528,23 +537,27 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
| 528 | return result; | 537 | return result; |
| 529 | 538 | ||
| 530 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); | 539 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); |
| 531 | battery->bat.name = battery->name; | 540 | battery->bat_desc.name = battery->name; |
| 532 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 541 | battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 533 | if (!acpi_battery_mode(battery)) { | 542 | if (!acpi_battery_mode(battery)) { |
| 534 | battery->bat.properties = sbs_charge_battery_props; | 543 | battery->bat_desc.properties = sbs_charge_battery_props; |
| 535 | battery->bat.num_properties = | 544 | battery->bat_desc.num_properties = |
| 536 | ARRAY_SIZE(sbs_charge_battery_props); | 545 | ARRAY_SIZE(sbs_charge_battery_props); |
| 537 | } else { | 546 | } else { |
| 538 | battery->bat.properties = sbs_energy_battery_props; | 547 | battery->bat_desc.properties = sbs_energy_battery_props; |
| 539 | battery->bat.num_properties = | 548 | battery->bat_desc.num_properties = |
| 540 | ARRAY_SIZE(sbs_energy_battery_props); | 549 | ARRAY_SIZE(sbs_energy_battery_props); |
| 541 | } | 550 | } |
| 542 | battery->bat.get_property = acpi_sbs_battery_get_property; | 551 | battery->bat_desc.get_property = acpi_sbs_battery_get_property; |
| 543 | result = power_supply_register(&sbs->device->dev, &battery->bat); | 552 | battery->bat = power_supply_register(&sbs->device->dev, |
| 544 | if (result) | 553 | &battery->bat_desc, &psy_cfg); |
| 554 | if (IS_ERR(battery->bat)) { | ||
| 555 | result = PTR_ERR(battery->bat); | ||
| 556 | battery->bat = NULL; | ||
| 545 | goto end; | 557 | goto end; |
| 558 | } | ||
| 546 | 559 | ||
| 547 | result = device_create_file(battery->bat.dev, &alarm_attr); | 560 | result = device_create_file(&battery->bat->dev, &alarm_attr); |
| 548 | if (result) | 561 | if (result) |
| 549 | goto end; | 562 | goto end; |
| 550 | battery->have_sysfs_alarm = 1; | 563 | battery->have_sysfs_alarm = 1; |
| @@ -559,28 +572,29 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) | |||
| 559 | { | 572 | { |
| 560 | struct acpi_battery *battery = &sbs->battery[id]; | 573 | struct acpi_battery *battery = &sbs->battery[id]; |
| 561 | 574 | ||
| 562 | if (battery->bat.dev) { | 575 | if (battery->bat) { |
| 563 | if (battery->have_sysfs_alarm) | 576 | if (battery->have_sysfs_alarm) |
| 564 | device_remove_file(battery->bat.dev, &alarm_attr); | 577 | device_remove_file(&battery->bat->dev, &alarm_attr); |
| 565 | power_supply_unregister(&battery->bat); | 578 | power_supply_unregister(battery->bat); |
| 566 | } | 579 | } |
| 567 | } | 580 | } |
| 568 | 581 | ||
| 569 | static int acpi_charger_add(struct acpi_sbs *sbs) | 582 | static int acpi_charger_add(struct acpi_sbs *sbs) |
| 570 | { | 583 | { |
| 571 | int result; | 584 | int result; |
| 585 | struct power_supply_config psy_cfg = { .drv_data = sbs, }; | ||
| 572 | 586 | ||
| 573 | result = acpi_ac_get_present(sbs); | 587 | result = acpi_ac_get_present(sbs); |
| 574 | if (result) | 588 | if (result) |
| 575 | goto end; | 589 | goto end; |
| 576 | 590 | ||
| 577 | sbs->charger_exists = 1; | 591 | sbs->charger_exists = 1; |
| 578 | sbs->charger.name = "sbs-charger"; | 592 | sbs->charger = power_supply_register(&sbs->device->dev, |
| 579 | sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; | 593 | &acpi_sbs_charger_desc, &psy_cfg); |
| 580 | sbs->charger.properties = sbs_ac_props; | 594 | if (IS_ERR(sbs->charger)) { |
| 581 | sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); | 595 | result = PTR_ERR(sbs->charger); |
| 582 | sbs->charger.get_property = sbs_get_ac_property; | 596 | sbs->charger = NULL; |
| 583 | power_supply_register(&sbs->device->dev, &sbs->charger); | 597 | } |
| 584 | printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", | 598 | printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", |
| 585 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), | 599 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), |
| 586 | ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); | 600 | ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); |
| @@ -590,8 +604,8 @@ static int acpi_charger_add(struct acpi_sbs *sbs) | |||
| 590 | 604 | ||
| 591 | static void acpi_charger_remove(struct acpi_sbs *sbs) | 605 | static void acpi_charger_remove(struct acpi_sbs *sbs) |
| 592 | { | 606 | { |
| 593 | if (sbs->charger.dev) | 607 | if (sbs->charger) |
| 594 | power_supply_unregister(&sbs->charger); | 608 | power_supply_unregister(sbs->charger); |
| 595 | } | 609 | } |
| 596 | 610 | ||
| 597 | static void acpi_sbs_callback(void *context) | 611 | static void acpi_sbs_callback(void *context) |
| @@ -605,7 +619,7 @@ static void acpi_sbs_callback(void *context) | |||
| 605 | if (sbs->charger_exists) { | 619 | if (sbs->charger_exists) { |
| 606 | acpi_ac_get_present(sbs); | 620 | acpi_ac_get_present(sbs); |
| 607 | if (sbs->charger_present != saved_charger_state) | 621 | if (sbs->charger_present != saved_charger_state) |
| 608 | kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); | 622 | kobject_uevent(&sbs->charger->dev.kobj, KOBJ_CHANGE); |
| 609 | } | 623 | } |
| 610 | 624 | ||
| 611 | if (sbs->manager_present) { | 625 | if (sbs->manager_present) { |
| @@ -617,7 +631,7 @@ static void acpi_sbs_callback(void *context) | |||
| 617 | acpi_battery_read(bat); | 631 | acpi_battery_read(bat); |
| 618 | if (saved_battery_state == bat->present) | 632 | if (saved_battery_state == bat->present) |
| 619 | continue; | 633 | continue; |
| 620 | kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); | 634 | kobject_uevent(&bat->bat->dev.kobj, KOBJ_CHANGE); |
| 621 | } | 635 | } |
| 622 | } | 636 | } |
| 623 | } | 637 | } |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 052869d0ab78..32c2da49bd5b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -339,7 +339,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
| 339 | enum power_supply_property prop, | 339 | enum power_supply_property prop, |
| 340 | union power_supply_propval *val) | 340 | union power_supply_propval *val) |
| 341 | { | 341 | { |
| 342 | struct hid_device *dev = container_of(psy, struct hid_device, battery); | 342 | struct hid_device *dev = power_supply_get_drvdata(psy); |
| 343 | int ret = 0; | 343 | int ret = 0; |
| 344 | __u8 *buf; | 344 | __u8 *buf; |
| 345 | 345 | ||
| @@ -397,26 +397,32 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
| 397 | 397 | ||
| 398 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) | 398 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) |
| 399 | { | 399 | { |
| 400 | struct power_supply *battery = &dev->battery; | 400 | struct power_supply_desc *psy_desc = NULL; |
| 401 | int ret; | 401 | struct power_supply_config psy_cfg = { .drv_data = dev, }; |
| 402 | unsigned quirks; | 402 | unsigned quirks; |
| 403 | s32 min, max; | 403 | s32 min, max; |
| 404 | 404 | ||
| 405 | if (field->usage->hid != HID_DC_BATTERYSTRENGTH) | 405 | if (field->usage->hid != HID_DC_BATTERYSTRENGTH) |
| 406 | return false; /* no match */ | 406 | return false; /* no match */ |
| 407 | 407 | ||
| 408 | if (battery->name != NULL) | 408 | if (dev->battery != NULL) |
| 409 | goto out; /* already initialized? */ | 409 | goto out; /* already initialized? */ |
| 410 | 410 | ||
| 411 | battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq); | 411 | psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL); |
| 412 | if (battery->name == NULL) | 412 | if (psy_desc == NULL) |
| 413 | goto out; | 413 | goto out; |
| 414 | 414 | ||
| 415 | battery->type = POWER_SUPPLY_TYPE_BATTERY; | 415 | psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq); |
| 416 | battery->properties = hidinput_battery_props; | 416 | if (psy_desc->name == NULL) { |
| 417 | battery->num_properties = ARRAY_SIZE(hidinput_battery_props); | 417 | kfree(psy_desc); |
| 418 | battery->use_for_apm = 0; | 418 | goto out; |
| 419 | battery->get_property = hidinput_get_battery_property; | 419 | } |
| 420 | |||
| 421 | psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 422 | psy_desc->properties = hidinput_battery_props; | ||
| 423 | psy_desc->num_properties = ARRAY_SIZE(hidinput_battery_props); | ||
| 424 | psy_desc->use_for_apm = 0; | ||
| 425 | psy_desc->get_property = hidinput_get_battery_property; | ||
| 420 | 426 | ||
| 421 | quirks = find_battery_quirk(dev); | 427 | quirks = find_battery_quirk(dev); |
| 422 | 428 | ||
| @@ -439,27 +445,30 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | |||
| 439 | dev->battery_report_type = report_type; | 445 | dev->battery_report_type = report_type; |
| 440 | dev->battery_report_id = field->report->id; | 446 | dev->battery_report_id = field->report->id; |
| 441 | 447 | ||
| 442 | ret = power_supply_register(&dev->dev, battery); | 448 | dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); |
| 443 | if (ret != 0) { | 449 | if (IS_ERR(dev->battery)) { |
| 444 | hid_warn(dev, "can't register power supply: %d\n", ret); | 450 | hid_warn(dev, "can't register power supply: %ld\n", |
| 445 | kfree(battery->name); | 451 | PTR_ERR(dev->battery)); |
| 446 | battery->name = NULL; | 452 | kfree(psy_desc->name); |
| 453 | kfree(psy_desc); | ||
| 454 | dev->battery = NULL; | ||
| 455 | } else { | ||
| 456 | power_supply_powers(dev->battery, &dev->dev); | ||
| 447 | } | 457 | } |
| 448 | 458 | ||
| 449 | power_supply_powers(battery, &dev->dev); | ||
| 450 | |||
| 451 | out: | 459 | out: |
| 452 | return true; | 460 | return true; |
| 453 | } | 461 | } |
| 454 | 462 | ||
| 455 | static void hidinput_cleanup_battery(struct hid_device *dev) | 463 | static void hidinput_cleanup_battery(struct hid_device *dev) |
| 456 | { | 464 | { |
| 457 | if (!dev->battery.name) | 465 | if (!dev->battery) |
| 458 | return; | 466 | return; |
| 459 | 467 | ||
| 460 | power_supply_unregister(&dev->battery); | 468 | power_supply_unregister(dev->battery); |
| 461 | kfree(dev->battery.name); | 469 | kfree(dev->battery->desc->name); |
| 462 | dev->battery.name = NULL; | 470 | kfree(dev->battery->desc); |
| 471 | dev->battery = NULL; | ||
| 463 | } | 472 | } |
| 464 | #else /* !CONFIG_HID_BATTERY_STRENGTH */ | 473 | #else /* !CONFIG_HID_BATTERY_STRENGTH */ |
| 465 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | 474 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 1896c019e302..c906300cf667 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -815,7 +815,8 @@ struct sony_sc { | |||
| 815 | struct led_classdev *leds[MAX_LEDS]; | 815 | struct led_classdev *leds[MAX_LEDS]; |
| 816 | unsigned long quirks; | 816 | unsigned long quirks; |
| 817 | struct work_struct state_worker; | 817 | struct work_struct state_worker; |
| 818 | struct power_supply battery; | 818 | struct power_supply *battery; |
| 819 | struct power_supply_desc battery_desc; | ||
| 819 | int device_id; | 820 | int device_id; |
| 820 | __u8 *output_report_dmabuf; | 821 | __u8 *output_report_dmabuf; |
| 821 | 822 | ||
| @@ -1660,7 +1661,7 @@ static int sony_battery_get_property(struct power_supply *psy, | |||
| 1660 | enum power_supply_property psp, | 1661 | enum power_supply_property psp, |
| 1661 | union power_supply_propval *val) | 1662 | union power_supply_propval *val) |
| 1662 | { | 1663 | { |
| 1663 | struct sony_sc *sc = container_of(psy, struct sony_sc, battery); | 1664 | struct sony_sc *sc = power_supply_get_drvdata(psy); |
| 1664 | unsigned long flags; | 1665 | unsigned long flags; |
| 1665 | int ret = 0; | 1666 | int ret = 0; |
| 1666 | u8 battery_charging, battery_capacity, cable_state; | 1667 | u8 battery_charging, battery_capacity, cable_state; |
| @@ -1699,6 +1700,7 @@ static int sony_battery_get_property(struct power_supply *psy, | |||
| 1699 | 1700 | ||
| 1700 | static int sony_battery_probe(struct sony_sc *sc) | 1701 | static int sony_battery_probe(struct sony_sc *sc) |
| 1701 | { | 1702 | { |
| 1703 | struct power_supply_config psy_cfg = { .drv_data = sc, }; | ||
| 1702 | struct hid_device *hdev = sc->hdev; | 1704 | struct hid_device *hdev = sc->hdev; |
| 1703 | int ret; | 1705 | int ret; |
| 1704 | 1706 | ||
| @@ -1708,39 +1710,42 @@ static int sony_battery_probe(struct sony_sc *sc) | |||
| 1708 | */ | 1710 | */ |
| 1709 | sc->battery_capacity = 100; | 1711 | sc->battery_capacity = 100; |
| 1710 | 1712 | ||
| 1711 | sc->battery.properties = sony_battery_props; | 1713 | sc->battery_desc.properties = sony_battery_props; |
| 1712 | sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); | 1714 | sc->battery_desc.num_properties = ARRAY_SIZE(sony_battery_props); |
| 1713 | sc->battery.get_property = sony_battery_get_property; | 1715 | sc->battery_desc.get_property = sony_battery_get_property; |
| 1714 | sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 1716 | sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 1715 | sc->battery.use_for_apm = 0; | 1717 | sc->battery_desc.use_for_apm = 0; |
| 1716 | sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR", | 1718 | sc->battery_desc.name = kasprintf(GFP_KERNEL, |
| 1717 | sc->mac_address); | 1719 | "sony_controller_battery_%pMR", |
| 1718 | if (!sc->battery.name) | 1720 | sc->mac_address); |
| 1721 | if (!sc->battery_desc.name) | ||
| 1719 | return -ENOMEM; | 1722 | return -ENOMEM; |
| 1720 | 1723 | ||
| 1721 | ret = power_supply_register(&hdev->dev, &sc->battery); | 1724 | sc->battery = power_supply_register(&hdev->dev, &sc->battery_desc, |
| 1722 | if (ret) { | 1725 | &psy_cfg); |
| 1726 | if (IS_ERR(sc->battery)) { | ||
| 1727 | ret = PTR_ERR(sc->battery); | ||
| 1723 | hid_err(hdev, "Unable to register battery device\n"); | 1728 | hid_err(hdev, "Unable to register battery device\n"); |
| 1724 | goto err_free; | 1729 | goto err_free; |
| 1725 | } | 1730 | } |
| 1726 | 1731 | ||
| 1727 | power_supply_powers(&sc->battery, &hdev->dev); | 1732 | power_supply_powers(sc->battery, &hdev->dev); |
| 1728 | return 0; | 1733 | return 0; |
| 1729 | 1734 | ||
| 1730 | err_free: | 1735 | err_free: |
| 1731 | kfree(sc->battery.name); | 1736 | kfree(sc->battery_desc.name); |
| 1732 | sc->battery.name = NULL; | 1737 | sc->battery_desc.name = NULL; |
| 1733 | return ret; | 1738 | return ret; |
| 1734 | } | 1739 | } |
| 1735 | 1740 | ||
| 1736 | static void sony_battery_remove(struct sony_sc *sc) | 1741 | static void sony_battery_remove(struct sony_sc *sc) |
| 1737 | { | 1742 | { |
| 1738 | if (!sc->battery.name) | 1743 | if (!sc->battery_desc.name) |
| 1739 | return; | 1744 | return; |
| 1740 | 1745 | ||
| 1741 | power_supply_unregister(&sc->battery); | 1746 | power_supply_unregister(sc->battery); |
| 1742 | kfree(sc->battery.name); | 1747 | kfree(sc->battery_desc.name); |
| 1743 | sc->battery.name = NULL; | 1748 | sc->battery_desc.name = NULL; |
| 1744 | } | 1749 | } |
| 1745 | 1750 | ||
| 1746 | /* | 1751 | /* |
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 6b61f01e01e7..05e23c417d50 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
| @@ -203,8 +203,7 @@ static int wiimod_battery_get_property(struct power_supply *psy, | |||
| 203 | enum power_supply_property psp, | 203 | enum power_supply_property psp, |
| 204 | union power_supply_propval *val) | 204 | union power_supply_propval *val) |
| 205 | { | 205 | { |
| 206 | struct wiimote_data *wdata = container_of(psy, struct wiimote_data, | 206 | struct wiimote_data *wdata = power_supply_get_drvdata(psy); |
| 207 | battery); | ||
| 208 | int ret = 0, state; | 207 | int ret = 0, state; |
| 209 | unsigned long flags; | 208 | unsigned long flags; |
| 210 | 209 | ||
| @@ -238,42 +237,46 @@ static int wiimod_battery_get_property(struct power_supply *psy, | |||
| 238 | static int wiimod_battery_probe(const struct wiimod_ops *ops, | 237 | static int wiimod_battery_probe(const struct wiimod_ops *ops, |
| 239 | struct wiimote_data *wdata) | 238 | struct wiimote_data *wdata) |
| 240 | { | 239 | { |
| 240 | struct power_supply_config psy_cfg = { .drv_data = wdata, }; | ||
| 241 | int ret; | 241 | int ret; |
| 242 | 242 | ||
| 243 | wdata->battery.properties = wiimod_battery_props; | 243 | wdata->battery_desc.properties = wiimod_battery_props; |
| 244 | wdata->battery.num_properties = ARRAY_SIZE(wiimod_battery_props); | 244 | wdata->battery_desc.num_properties = ARRAY_SIZE(wiimod_battery_props); |
| 245 | wdata->battery.get_property = wiimod_battery_get_property; | 245 | wdata->battery_desc.get_property = wiimod_battery_get_property; |
| 246 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 246 | wdata->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 247 | wdata->battery.use_for_apm = 0; | 247 | wdata->battery_desc.use_for_apm = 0; |
| 248 | wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", | 248 | wdata->battery_desc.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", |
| 249 | wdata->hdev->uniq); | 249 | wdata->hdev->uniq); |
| 250 | if (!wdata->battery.name) | 250 | if (!wdata->battery_desc.name) |
| 251 | return -ENOMEM; | 251 | return -ENOMEM; |
| 252 | 252 | ||
| 253 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); | 253 | wdata->battery = power_supply_register(&wdata->hdev->dev, |
| 254 | if (ret) { | 254 | &wdata->battery_desc, |
| 255 | &psy_cfg); | ||
| 256 | if (IS_ERR(wdata->battery)) { | ||
| 255 | hid_err(wdata->hdev, "cannot register battery device\n"); | 257 | hid_err(wdata->hdev, "cannot register battery device\n"); |
| 258 | ret = PTR_ERR(wdata->battery); | ||
| 256 | goto err_free; | 259 | goto err_free; |
| 257 | } | 260 | } |
| 258 | 261 | ||
| 259 | power_supply_powers(&wdata->battery, &wdata->hdev->dev); | 262 | power_supply_powers(wdata->battery, &wdata->hdev->dev); |
| 260 | return 0; | 263 | return 0; |
| 261 | 264 | ||
| 262 | err_free: | 265 | err_free: |
| 263 | kfree(wdata->battery.name); | 266 | kfree(wdata->battery_desc.name); |
| 264 | wdata->battery.name = NULL; | 267 | wdata->battery_desc.name = NULL; |
| 265 | return ret; | 268 | return ret; |
| 266 | } | 269 | } |
| 267 | 270 | ||
| 268 | static void wiimod_battery_remove(const struct wiimod_ops *ops, | 271 | static void wiimod_battery_remove(const struct wiimod_ops *ops, |
| 269 | struct wiimote_data *wdata) | 272 | struct wiimote_data *wdata) |
| 270 | { | 273 | { |
| 271 | if (!wdata->battery.name) | 274 | if (!wdata->battery_desc.name) |
| 272 | return; | 275 | return; |
| 273 | 276 | ||
| 274 | power_supply_unregister(&wdata->battery); | 277 | power_supply_unregister(wdata->battery); |
| 275 | kfree(wdata->battery.name); | 278 | kfree(wdata->battery_desc.name); |
| 276 | wdata->battery.name = NULL; | 279 | wdata->battery_desc.name = NULL; |
| 277 | } | 280 | } |
| 278 | 281 | ||
| 279 | static const struct wiimod_ops wiimod_battery = { | 282 | static const struct wiimod_ops wiimod_battery = { |
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 10934aa129fb..875694d43e4d 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
| @@ -147,7 +147,8 @@ struct wiimote_data { | |||
| 147 | struct led_classdev *leds[4]; | 147 | struct led_classdev *leds[4]; |
| 148 | struct input_dev *accel; | 148 | struct input_dev *accel; |
| 149 | struct input_dev *ir; | 149 | struct input_dev *ir; |
| 150 | struct power_supply battery; | 150 | struct power_supply *battery; |
| 151 | struct power_supply_desc battery_desc; | ||
| 151 | struct input_dev *mp; | 152 | struct input_dev *mp; |
| 152 | struct timer_list timer; | 153 | struct timer_list timer; |
| 153 | struct wiimote_debug *debug; | 154 | struct wiimote_debug *debug; |
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 7db432809e9e..0d0d0dd89d17 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
| @@ -119,8 +119,10 @@ struct wacom { | |||
| 119 | u8 img_lum; /* OLED matrix display brightness */ | 119 | u8 img_lum; /* OLED matrix display brightness */ |
| 120 | } led; | 120 | } led; |
| 121 | bool led_initialized; | 121 | bool led_initialized; |
| 122 | struct power_supply battery; | 122 | struct power_supply *battery; |
| 123 | struct power_supply ac; | 123 | struct power_supply *ac; |
| 124 | struct power_supply_desc battery_desc; | ||
| 125 | struct power_supply_desc ac_desc; | ||
| 124 | }; | 126 | }; |
| 125 | 127 | ||
| 126 | static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) | 128 | static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) |
| @@ -133,7 +135,7 @@ static inline void wacom_notify_battery(struct wacom_wac *wacom_wac) | |||
| 133 | { | 135 | { |
| 134 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | 136 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); |
| 135 | 137 | ||
| 136 | power_supply_changed(&wacom->battery); | 138 | power_supply_changed(wacom->battery); |
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | extern const struct hid_device_id wacom_ids[]; | 141 | extern const struct hid_device_id wacom_ids[]; |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index f0568a7e6de9..ba9af470bea0 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -944,7 +944,7 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
| 944 | enum power_supply_property psp, | 944 | enum power_supply_property psp, |
| 945 | union power_supply_propval *val) | 945 | union power_supply_propval *val) |
| 946 | { | 946 | { |
| 947 | struct wacom *wacom = container_of(psy, struct wacom, battery); | 947 | struct wacom *wacom = power_supply_get_drvdata(psy); |
| 948 | int ret = 0; | 948 | int ret = 0; |
| 949 | 949 | ||
| 950 | switch (psp) { | 950 | switch (psp) { |
| @@ -976,7 +976,7 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
| 976 | enum power_supply_property psp, | 976 | enum power_supply_property psp, |
| 977 | union power_supply_propval *val) | 977 | union power_supply_propval *val) |
| 978 | { | 978 | { |
| 979 | struct wacom *wacom = container_of(psy, struct wacom, ac); | 979 | struct wacom *wacom = power_supply_get_drvdata(psy); |
| 980 | int ret = 0; | 980 | int ret = 0; |
| 981 | 981 | ||
| 982 | switch (psp) { | 982 | switch (psp) { |
| @@ -998,42 +998,46 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
| 998 | static int wacom_initialize_battery(struct wacom *wacom) | 998 | static int wacom_initialize_battery(struct wacom *wacom) |
| 999 | { | 999 | { |
| 1000 | static atomic_t battery_no = ATOMIC_INIT(0); | 1000 | static atomic_t battery_no = ATOMIC_INIT(0); |
| 1001 | int error; | 1001 | struct power_supply_config psy_cfg = { .drv_data = wacom, }; |
| 1002 | unsigned long n; | 1002 | unsigned long n; |
| 1003 | 1003 | ||
| 1004 | if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) { | 1004 | if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) { |
| 1005 | struct power_supply_desc *bat_desc = &wacom->battery_desc; | ||
| 1006 | struct power_supply_desc *ac_desc = &wacom->ac_desc; | ||
| 1005 | n = atomic_inc_return(&battery_no) - 1; | 1007 | n = atomic_inc_return(&battery_no) - 1; |
| 1006 | 1008 | ||
| 1007 | wacom->battery.properties = wacom_battery_props; | 1009 | bat_desc->properties = wacom_battery_props; |
| 1008 | wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props); | 1010 | bat_desc->num_properties = ARRAY_SIZE(wacom_battery_props); |
| 1009 | wacom->battery.get_property = wacom_battery_get_property; | 1011 | bat_desc->get_property = wacom_battery_get_property; |
| 1010 | sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n); | 1012 | sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", n); |
| 1011 | wacom->battery.name = wacom->wacom_wac.bat_name; | 1013 | bat_desc->name = wacom->wacom_wac.bat_name; |
| 1012 | wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 1014 | bat_desc->type = POWER_SUPPLY_TYPE_BATTERY; |
| 1013 | wacom->battery.use_for_apm = 0; | 1015 | bat_desc->use_for_apm = 0; |
| 1014 | 1016 | ||
| 1015 | wacom->ac.properties = wacom_ac_props; | 1017 | ac_desc->properties = wacom_ac_props; |
| 1016 | wacom->ac.num_properties = ARRAY_SIZE(wacom_ac_props); | 1018 | ac_desc->num_properties = ARRAY_SIZE(wacom_ac_props); |
| 1017 | wacom->ac.get_property = wacom_ac_get_property; | 1019 | ac_desc->get_property = wacom_ac_get_property; |
| 1018 | sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n); | 1020 | sprintf(wacom->wacom_wac.ac_name, "wacom_ac_%ld", n); |
| 1019 | wacom->ac.name = wacom->wacom_wac.ac_name; | 1021 | ac_desc->name = wacom->wacom_wac.ac_name; |
| 1020 | wacom->ac.type = POWER_SUPPLY_TYPE_MAINS; | 1022 | ac_desc->type = POWER_SUPPLY_TYPE_MAINS; |
| 1021 | wacom->ac.use_for_apm = 0; | 1023 | ac_desc->use_for_apm = 0; |
| 1022 | 1024 | ||
| 1023 | error = power_supply_register(&wacom->hdev->dev, | 1025 | wacom->battery = power_supply_register(&wacom->hdev->dev, |
| 1024 | &wacom->battery); | 1026 | &wacom->battery_desc, &psy_cfg); |
| 1025 | if (error) | 1027 | if (IS_ERR(wacom->battery)) |
| 1026 | return error; | 1028 | return PTR_ERR(wacom->battery); |
| 1027 | 1029 | ||
| 1028 | power_supply_powers(&wacom->battery, &wacom->hdev->dev); | 1030 | power_supply_powers(wacom->battery, &wacom->hdev->dev); |
| 1029 | 1031 | ||
| 1030 | error = power_supply_register(&wacom->hdev->dev, &wacom->ac); | 1032 | wacom->ac = power_supply_register(&wacom->hdev->dev, |
| 1031 | if (error) { | 1033 | &wacom->ac_desc, |
| 1032 | power_supply_unregister(&wacom->battery); | 1034 | &psy_cfg); |
| 1033 | return error; | 1035 | if (IS_ERR(wacom->ac)) { |
| 1036 | power_supply_unregister(wacom->battery); | ||
| 1037 | return PTR_ERR(wacom->ac); | ||
| 1034 | } | 1038 | } |
| 1035 | 1039 | ||
| 1036 | power_supply_powers(&wacom->ac, &wacom->hdev->dev); | 1040 | power_supply_powers(wacom->ac, &wacom->hdev->dev); |
| 1037 | } | 1041 | } |
| 1038 | 1042 | ||
| 1039 | return 0; | 1043 | return 0; |
| @@ -1042,11 +1046,11 @@ static int wacom_initialize_battery(struct wacom *wacom) | |||
| 1042 | static void wacom_destroy_battery(struct wacom *wacom) | 1046 | static void wacom_destroy_battery(struct wacom *wacom) |
| 1043 | { | 1047 | { |
| 1044 | if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && | 1048 | if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && |
| 1045 | wacom->battery.dev) { | 1049 | wacom->battery) { |
| 1046 | power_supply_unregister(&wacom->battery); | 1050 | power_supply_unregister(wacom->battery); |
| 1047 | wacom->battery.dev = NULL; | 1051 | wacom->battery = NULL; |
| 1048 | power_supply_unregister(&wacom->ac); | 1052 | power_supply_unregister(wacom->ac); |
| 1049 | wacom->ac.dev = NULL; | 1053 | wacom->ac = NULL; |
| 1050 | } | 1054 | } |
| 1051 | } | 1055 | } |
| 1052 | 1056 | ||
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 46379b1fb25b..d82af14986ba 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
| @@ -135,6 +135,15 @@ config AXP288_ADC | |||
| 135 | device. Depending on platform configuration, this general purpose ADC can | 135 | device. Depending on platform configuration, this general purpose ADC can |
| 136 | be used for sampling sensors such as thermal resistors. | 136 | be used for sampling sensors such as thermal resistors. |
| 137 | 137 | ||
| 138 | config DA9150_GPADC | ||
| 139 | tristate "Dialog DA9150 GPADC driver support" | ||
| 140 | depends on MFD_DA9150 | ||
| 141 | help | ||
| 142 | Say yes here to build support for Dialog DA9150 GPADC. | ||
| 143 | |||
| 144 | This driver can also be built as a module. If chosen, the module name | ||
| 145 | will be da9150-gpadc. | ||
| 146 | |||
| 138 | config CC10001_ADC | 147 | config CC10001_ADC |
| 139 | tristate "Cosmic Circuits 10001 ADC driver" | 148 | tristate "Cosmic Circuits 10001 ADC driver" |
| 140 | depends on HAVE_CLK || REGULATOR | 149 | depends on HAVE_CLK || REGULATOR |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 0315af640866..3930e63e84bc 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o | |||
| 15 | obj-$(CONFIG_AD799X) += ad799x.o | 15 | obj-$(CONFIG_AD799X) += ad799x.o |
| 16 | obj-$(CONFIG_AT91_ADC) += at91_adc.o | 16 | obj-$(CONFIG_AT91_ADC) += at91_adc.o |
| 17 | obj-$(CONFIG_AXP288_ADC) += axp288_adc.o | 17 | obj-$(CONFIG_AXP288_ADC) += axp288_adc.o |
| 18 | obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o | ||
| 18 | obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o | 19 | obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o |
| 19 | obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o | 20 | obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o |
| 20 | obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o | 21 | obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o |
diff --git a/drivers/iio/adc/da9150-gpadc.c b/drivers/iio/adc/da9150-gpadc.c new file mode 100644 index 000000000000..3445107e10b7 --- /dev/null +++ b/drivers/iio/adc/da9150-gpadc.c | |||
| @@ -0,0 +1,407 @@ | |||
| 1 | /* | ||
| 2 | * DA9150 GPADC Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Dialog Semiconductor | ||
| 5 | * | ||
| 6 | * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/mutex.h> | ||
| 20 | #include <linux/completion.h> | ||
| 21 | #include <linux/iio/iio.h> | ||
| 22 | #include <linux/iio/machine.h> | ||
| 23 | #include <linux/iio/driver.h> | ||
| 24 | #include <linux/mfd/da9150/core.h> | ||
| 25 | #include <linux/mfd/da9150/registers.h> | ||
| 26 | |||
| 27 | /* Channels */ | ||
| 28 | enum da9150_gpadc_hw_channel { | ||
| 29 | DA9150_GPADC_HW_CHAN_GPIOA_2V = 0, | ||
| 30 | DA9150_GPADC_HW_CHAN_GPIOA_2V_, | ||
| 31 | DA9150_GPADC_HW_CHAN_GPIOB_2V, | ||
| 32 | DA9150_GPADC_HW_CHAN_GPIOB_2V_, | ||
| 33 | DA9150_GPADC_HW_CHAN_GPIOC_2V, | ||
| 34 | DA9150_GPADC_HW_CHAN_GPIOC_2V_, | ||
| 35 | DA9150_GPADC_HW_CHAN_GPIOD_2V, | ||
| 36 | DA9150_GPADC_HW_CHAN_GPIOD_2V_, | ||
| 37 | DA9150_GPADC_HW_CHAN_IBUS_SENSE, | ||
| 38 | DA9150_GPADC_HW_CHAN_IBUS_SENSE_, | ||
| 39 | DA9150_GPADC_HW_CHAN_VBUS_DIV, | ||
| 40 | DA9150_GPADC_HW_CHAN_VBUS_DIV_, | ||
| 41 | DA9150_GPADC_HW_CHAN_ID, | ||
| 42 | DA9150_GPADC_HW_CHAN_ID_, | ||
| 43 | DA9150_GPADC_HW_CHAN_VSYS, | ||
| 44 | DA9150_GPADC_HW_CHAN_VSYS_, | ||
| 45 | DA9150_GPADC_HW_CHAN_GPIOA_6V, | ||
| 46 | DA9150_GPADC_HW_CHAN_GPIOA_6V_, | ||
| 47 | DA9150_GPADC_HW_CHAN_GPIOB_6V, | ||
| 48 | DA9150_GPADC_HW_CHAN_GPIOB_6V_, | ||
| 49 | DA9150_GPADC_HW_CHAN_GPIOC_6V, | ||
| 50 | DA9150_GPADC_HW_CHAN_GPIOC_6V_, | ||
| 51 | DA9150_GPADC_HW_CHAN_GPIOD_6V, | ||
| 52 | DA9150_GPADC_HW_CHAN_GPIOD_6V_, | ||
| 53 | DA9150_GPADC_HW_CHAN_VBAT, | ||
| 54 | DA9150_GPADC_HW_CHAN_VBAT_, | ||
| 55 | DA9150_GPADC_HW_CHAN_TBAT, | ||
| 56 | DA9150_GPADC_HW_CHAN_TBAT_, | ||
| 57 | DA9150_GPADC_HW_CHAN_TJUNC_CORE, | ||
| 58 | DA9150_GPADC_HW_CHAN_TJUNC_CORE_, | ||
| 59 | DA9150_GPADC_HW_CHAN_TJUNC_OVP, | ||
| 60 | DA9150_GPADC_HW_CHAN_TJUNC_OVP_, | ||
| 61 | }; | ||
| 62 | |||
| 63 | enum da9150_gpadc_channel { | ||
| 64 | DA9150_GPADC_CHAN_GPIOA = 0, | ||
| 65 | DA9150_GPADC_CHAN_GPIOB, | ||
| 66 | DA9150_GPADC_CHAN_GPIOC, | ||
| 67 | DA9150_GPADC_CHAN_GPIOD, | ||
| 68 | DA9150_GPADC_CHAN_IBUS, | ||
| 69 | DA9150_GPADC_CHAN_VBUS, | ||
| 70 | DA9150_GPADC_CHAN_VSYS, | ||
| 71 | DA9150_GPADC_CHAN_VBAT, | ||
| 72 | DA9150_GPADC_CHAN_TBAT, | ||
| 73 | DA9150_GPADC_CHAN_TJUNC_CORE, | ||
| 74 | DA9150_GPADC_CHAN_TJUNC_OVP, | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* Private data */ | ||
| 78 | struct da9150_gpadc { | ||
| 79 | struct da9150 *da9150; | ||
| 80 | struct device *dev; | ||
| 81 | |||
| 82 | struct mutex lock; | ||
| 83 | struct completion complete; | ||
| 84 | }; | ||
| 85 | |||
| 86 | |||
| 87 | static irqreturn_t da9150_gpadc_irq(int irq, void *data) | ||
| 88 | { | ||
| 89 | |||
| 90 | struct da9150_gpadc *gpadc = data; | ||
| 91 | |||
| 92 | complete(&gpadc->complete); | ||
| 93 | |||
| 94 | return IRQ_HANDLED; | ||
| 95 | } | ||
| 96 | |||
| 97 | static int da9150_gpadc_read_adc(struct da9150_gpadc *gpadc, int hw_chan) | ||
| 98 | { | ||
| 99 | u8 result_regs[2]; | ||
| 100 | int result; | ||
| 101 | |||
| 102 | mutex_lock(&gpadc->lock); | ||
| 103 | |||
| 104 | /* Set channel & enable measurement */ | ||
| 105 | da9150_reg_write(gpadc->da9150, DA9150_GPADC_MAN, | ||
| 106 | (DA9150_GPADC_EN_MASK | | ||
| 107 | hw_chan << DA9150_GPADC_MUX_SHIFT)); | ||
| 108 | |||
| 109 | /* Consume left-over completion from a previous timeout */ | ||
| 110 | try_wait_for_completion(&gpadc->complete); | ||
| 111 | |||
| 112 | /* Check for actual completion */ | ||
| 113 | wait_for_completion_timeout(&gpadc->complete, msecs_to_jiffies(5)); | ||
| 114 | |||
| 115 | /* Read result and status from device */ | ||
| 116 | da9150_bulk_read(gpadc->da9150, DA9150_GPADC_RES_A, 2, result_regs); | ||
| 117 | |||
| 118 | mutex_unlock(&gpadc->lock); | ||
| 119 | |||
| 120 | /* Check to make sure device really has completed reading */ | ||
| 121 | if (result_regs[1] & DA9150_GPADC_RUN_MASK) { | ||
| 122 | dev_err(gpadc->dev, "Timeout on channel %d of GPADC\n", | ||
| 123 | hw_chan); | ||
| 124 | return -ETIMEDOUT; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* LSBs - 2 bits */ | ||
| 128 | result = (result_regs[1] & DA9150_GPADC_RES_L_MASK) >> | ||
| 129 | DA9150_GPADC_RES_L_SHIFT; | ||
| 130 | /* MSBs - 8 bits */ | ||
| 131 | result |= result_regs[0] << DA9150_GPADC_RES_L_BITS; | ||
| 132 | |||
| 133 | return result; | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline int da9150_gpadc_gpio_6v_voltage_now(int raw_val) | ||
| 137 | { | ||
| 138 | /* Convert to mV */ | ||
| 139 | return (6 * ((raw_val * 1000) + 500)) / 1024; | ||
| 140 | } | ||
| 141 | |||
| 142 | static inline int da9150_gpadc_ibus_current_avg(int raw_val) | ||
| 143 | { | ||
| 144 | /* Convert to mA */ | ||
| 145 | return (4 * ((raw_val * 1000) + 500)) / 2048; | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline int da9150_gpadc_vbus_21v_voltage_now(int raw_val) | ||
| 149 | { | ||
| 150 | /* Convert to mV */ | ||
| 151 | return (21 * ((raw_val * 1000) + 500)) / 1024; | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline int da9150_gpadc_vsys_6v_voltage_now(int raw_val) | ||
| 155 | { | ||
| 156 | /* Convert to mV */ | ||
| 157 | return (3 * ((raw_val * 1000) + 500)) / 512; | ||
| 158 | } | ||
| 159 | |||
| 160 | static int da9150_gpadc_read_processed(struct da9150_gpadc *gpadc, int channel, | ||
| 161 | int hw_chan, int *val) | ||
| 162 | { | ||
| 163 | int raw_val; | ||
| 164 | |||
| 165 | raw_val = da9150_gpadc_read_adc(gpadc, hw_chan); | ||
| 166 | if (raw_val < 0) | ||
| 167 | return raw_val; | ||
| 168 | |||
| 169 | switch (channel) { | ||
| 170 | case DA9150_GPADC_CHAN_GPIOA: | ||
| 171 | case DA9150_GPADC_CHAN_GPIOB: | ||
| 172 | case DA9150_GPADC_CHAN_GPIOC: | ||
| 173 | case DA9150_GPADC_CHAN_GPIOD: | ||
| 174 | *val = da9150_gpadc_gpio_6v_voltage_now(raw_val); | ||
| 175 | break; | ||
| 176 | case DA9150_GPADC_CHAN_IBUS: | ||
| 177 | *val = da9150_gpadc_ibus_current_avg(raw_val); | ||
| 178 | break; | ||
| 179 | case DA9150_GPADC_CHAN_VBUS: | ||
| 180 | *val = da9150_gpadc_vbus_21v_voltage_now(raw_val); | ||
| 181 | break; | ||
| 182 | case DA9150_GPADC_CHAN_VSYS: | ||
| 183 | *val = da9150_gpadc_vsys_6v_voltage_now(raw_val); | ||
| 184 | break; | ||
| 185 | default: | ||
| 186 | /* No processing for other channels so return raw value */ | ||
| 187 | *val = raw_val; | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | |||
| 191 | return IIO_VAL_INT; | ||
| 192 | } | ||
| 193 | |||
| 194 | static int da9150_gpadc_read_scale(int channel, int *val, int *val2) | ||
| 195 | { | ||
| 196 | switch (channel) { | ||
| 197 | case DA9150_GPADC_CHAN_VBAT: | ||
| 198 | *val = 2932; | ||
| 199 | *val2 = 1000; | ||
| 200 | return IIO_VAL_FRACTIONAL; | ||
| 201 | case DA9150_GPADC_CHAN_TJUNC_CORE: | ||
| 202 | case DA9150_GPADC_CHAN_TJUNC_OVP: | ||
| 203 | *val = 1000000; | ||
| 204 | *val2 = 4420; | ||
| 205 | return IIO_VAL_FRACTIONAL; | ||
| 206 | default: | ||
| 207 | return -EINVAL; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | static int da9150_gpadc_read_offset(int channel, int *val) | ||
| 212 | { | ||
| 213 | switch (channel) { | ||
| 214 | case DA9150_GPADC_CHAN_VBAT: | ||
| 215 | *val = 1500000 / 2932; | ||
| 216 | return IIO_VAL_INT; | ||
| 217 | case DA9150_GPADC_CHAN_TJUNC_CORE: | ||
| 218 | case DA9150_GPADC_CHAN_TJUNC_OVP: | ||
| 219 | *val = -144; | ||
| 220 | return IIO_VAL_INT; | ||
| 221 | default: | ||
| 222 | return -EINVAL; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | static int da9150_gpadc_read_raw(struct iio_dev *indio_dev, | ||
| 227 | struct iio_chan_spec const *chan, | ||
| 228 | int *val, int *val2, long mask) | ||
| 229 | { | ||
| 230 | struct da9150_gpadc *gpadc = iio_priv(indio_dev); | ||
| 231 | |||
| 232 | if ((chan->channel < DA9150_GPADC_CHAN_GPIOA) || | ||
| 233 | (chan->channel > DA9150_GPADC_CHAN_TJUNC_OVP)) | ||
| 234 | return -EINVAL; | ||
| 235 | |||
| 236 | switch (mask) { | ||
| 237 | case IIO_CHAN_INFO_RAW: | ||
| 238 | case IIO_CHAN_INFO_PROCESSED: | ||
| 239 | return da9150_gpadc_read_processed(gpadc, chan->channel, | ||
| 240 | chan->address, val); | ||
| 241 | case IIO_CHAN_INFO_SCALE: | ||
| 242 | return da9150_gpadc_read_scale(chan->channel, val, val2); | ||
| 243 | case IIO_CHAN_INFO_OFFSET: | ||
| 244 | return da9150_gpadc_read_offset(chan->channel, val); | ||
| 245 | default: | ||
| 246 | return -EINVAL; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | static const struct iio_info da9150_gpadc_info = { | ||
| 251 | .read_raw = &da9150_gpadc_read_raw, | ||
| 252 | .driver_module = THIS_MODULE, | ||
| 253 | }; | ||
| 254 | |||
| 255 | #define DA9150_GPADC_CHANNEL(_id, _hw_id, _type, chan_info, \ | ||
| 256 | _ext_name) { \ | ||
| 257 | .type = _type, \ | ||
| 258 | .indexed = 1, \ | ||
| 259 | .channel = DA9150_GPADC_CHAN_##_id, \ | ||
| 260 | .address = DA9150_GPADC_HW_CHAN_##_hw_id, \ | ||
| 261 | .info_mask_separate = chan_info, \ | ||
| 262 | .extend_name = _ext_name, \ | ||
| 263 | .datasheet_name = #_id, \ | ||
| 264 | } | ||
| 265 | |||
| 266 | #define DA9150_GPADC_CHANNEL_RAW(_id, _hw_id, _type, _ext_name) \ | ||
| 267 | DA9150_GPADC_CHANNEL(_id, _hw_id, _type, \ | ||
| 268 | BIT(IIO_CHAN_INFO_RAW), _ext_name) | ||
| 269 | |||
| 270 | #define DA9150_GPADC_CHANNEL_SCALED(_id, _hw_id, _type, _ext_name) \ | ||
| 271 | DA9150_GPADC_CHANNEL(_id, _hw_id, _type, \ | ||
| 272 | BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 273 | BIT(IIO_CHAN_INFO_SCALE) | \ | ||
| 274 | BIT(IIO_CHAN_INFO_OFFSET), \ | ||
| 275 | _ext_name) | ||
| 276 | |||
| 277 | #define DA9150_GPADC_CHANNEL_PROCESSED(_id, _hw_id, _type, _ext_name) \ | ||
| 278 | DA9150_GPADC_CHANNEL(_id, _hw_id, _type, \ | ||
| 279 | BIT(IIO_CHAN_INFO_PROCESSED), _ext_name) | ||
| 280 | |||
| 281 | /* Supported channels */ | ||
| 282 | static const struct iio_chan_spec da9150_gpadc_channels[] = { | ||
| 283 | DA9150_GPADC_CHANNEL_PROCESSED(GPIOA, GPIOA_6V, IIO_VOLTAGE, NULL), | ||
| 284 | DA9150_GPADC_CHANNEL_PROCESSED(GPIOB, GPIOB_6V, IIO_VOLTAGE, NULL), | ||
| 285 | DA9150_GPADC_CHANNEL_PROCESSED(GPIOC, GPIOC_6V, IIO_VOLTAGE, NULL), | ||
| 286 | DA9150_GPADC_CHANNEL_PROCESSED(GPIOD, GPIOD_6V, IIO_VOLTAGE, NULL), | ||
| 287 | DA9150_GPADC_CHANNEL_PROCESSED(IBUS, IBUS_SENSE, IIO_CURRENT, "ibus"), | ||
| 288 | DA9150_GPADC_CHANNEL_PROCESSED(VBUS, VBUS_DIV_, IIO_VOLTAGE, "vbus"), | ||
| 289 | DA9150_GPADC_CHANNEL_PROCESSED(VSYS, VSYS, IIO_VOLTAGE, "vsys"), | ||
| 290 | DA9150_GPADC_CHANNEL_SCALED(VBAT, VBAT, IIO_VOLTAGE, "vbat"), | ||
| 291 | DA9150_GPADC_CHANNEL_RAW(TBAT, TBAT, IIO_VOLTAGE, "tbat"), | ||
| 292 | DA9150_GPADC_CHANNEL_SCALED(TJUNC_CORE, TJUNC_CORE, IIO_TEMP, | ||
| 293 | "tjunc_core"), | ||
| 294 | DA9150_GPADC_CHANNEL_SCALED(TJUNC_OVP, TJUNC_OVP, IIO_TEMP, | ||
| 295 | "tjunc_ovp"), | ||
| 296 | }; | ||
| 297 | |||
| 298 | /* Default maps used by da9150-charger */ | ||
| 299 | static struct iio_map da9150_gpadc_default_maps[] = { | ||
| 300 | { | ||
| 301 | .consumer_dev_name = "da9150-charger", | ||
| 302 | .consumer_channel = "CHAN_IBUS", | ||
| 303 | .adc_channel_label = "IBUS", | ||
| 304 | }, | ||
| 305 | { | ||
| 306 | .consumer_dev_name = "da9150-charger", | ||
| 307 | .consumer_channel = "CHAN_VBUS", | ||
| 308 | .adc_channel_label = "VBUS", | ||
| 309 | }, | ||
| 310 | { | ||
| 311 | .consumer_dev_name = "da9150-charger", | ||
| 312 | .consumer_channel = "CHAN_TJUNC", | ||
| 313 | .adc_channel_label = "TJUNC_CORE", | ||
| 314 | }, | ||
| 315 | { | ||
| 316 | .consumer_dev_name = "da9150-charger", | ||
| 317 | .consumer_channel = "CHAN_VBAT", | ||
| 318 | .adc_channel_label = "VBAT", | ||
| 319 | }, | ||
| 320 | {}, | ||
| 321 | }; | ||
| 322 | |||
| 323 | static int da9150_gpadc_probe(struct platform_device *pdev) | ||
| 324 | { | ||
| 325 | struct device *dev = &pdev->dev; | ||
| 326 | struct da9150 *da9150 = dev_get_drvdata(dev->parent); | ||
| 327 | struct da9150_gpadc *gpadc; | ||
| 328 | struct iio_dev *indio_dev; | ||
| 329 | int irq, ret; | ||
| 330 | |||
| 331 | indio_dev = devm_iio_device_alloc(dev, sizeof(*gpadc)); | ||
| 332 | if (!indio_dev) { | ||
| 333 | dev_err(&pdev->dev, "Failed to allocate IIO device\n"); | ||
| 334 | return -ENOMEM; | ||
| 335 | } | ||
| 336 | gpadc = iio_priv(indio_dev); | ||
| 337 | |||
| 338 | platform_set_drvdata(pdev, indio_dev); | ||
| 339 | gpadc->da9150 = da9150; | ||
| 340 | gpadc->dev = dev; | ||
| 341 | mutex_init(&gpadc->lock); | ||
| 342 | init_completion(&gpadc->complete); | ||
| 343 | |||
| 344 | irq = platform_get_irq_byname(pdev, "GPADC"); | ||
| 345 | if (irq < 0) { | ||
| 346 | dev_err(dev, "Failed to get IRQ: %d\n", irq); | ||
| 347 | return irq; | ||
| 348 | } | ||
| 349 | |||
| 350 | ret = devm_request_threaded_irq(dev, irq, NULL, da9150_gpadc_irq, | ||
| 351 | IRQF_ONESHOT, "GPADC", gpadc); | ||
| 352 | if (ret) { | ||
| 353 | dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret); | ||
| 354 | return ret; | ||
| 355 | } | ||
| 356 | |||
| 357 | ret = iio_map_array_register(indio_dev, da9150_gpadc_default_maps); | ||
| 358 | if (ret) { | ||
| 359 | dev_err(dev, "Failed to register IIO maps: %d\n", ret); | ||
| 360 | return ret; | ||
| 361 | } | ||
| 362 | |||
| 363 | indio_dev->name = dev_name(dev); | ||
| 364 | indio_dev->dev.parent = dev; | ||
| 365 | indio_dev->dev.of_node = pdev->dev.of_node; | ||
| 366 | indio_dev->info = &da9150_gpadc_info; | ||
| 367 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 368 | indio_dev->channels = da9150_gpadc_channels; | ||
| 369 | indio_dev->num_channels = ARRAY_SIZE(da9150_gpadc_channels); | ||
| 370 | |||
| 371 | ret = iio_device_register(indio_dev); | ||
| 372 | if (ret) { | ||
| 373 | dev_err(dev, "Failed to register IIO device: %d\n", ret); | ||
| 374 | goto iio_map_unreg; | ||
| 375 | } | ||
| 376 | |||
| 377 | return 0; | ||
| 378 | |||
| 379 | iio_map_unreg: | ||
| 380 | iio_map_array_unregister(indio_dev); | ||
| 381 | |||
| 382 | return ret; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int da9150_gpadc_remove(struct platform_device *pdev) | ||
| 386 | { | ||
| 387 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | ||
| 388 | |||
| 389 | iio_device_unregister(indio_dev); | ||
| 390 | iio_map_array_unregister(indio_dev); | ||
| 391 | |||
| 392 | return 0; | ||
| 393 | } | ||
| 394 | |||
| 395 | static struct platform_driver da9150_gpadc_driver = { | ||
| 396 | .driver = { | ||
| 397 | .name = "da9150-gpadc", | ||
| 398 | }, | ||
| 399 | .probe = da9150_gpadc_probe, | ||
| 400 | .remove = da9150_gpadc_remove, | ||
| 401 | }; | ||
| 402 | |||
| 403 | module_platform_driver(da9150_gpadc_driver); | ||
| 404 | |||
| 405 | MODULE_DESCRIPTION("GPADC Driver for DA9150"); | ||
| 406 | MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); | ||
| 407 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index cfff0b643f1b..0d1825696153 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
| @@ -49,7 +49,9 @@ static void ab8500_power_off(void) | |||
| 49 | if (!psy) | 49 | if (!psy) |
| 50 | continue; | 50 | continue; |
| 51 | 51 | ||
| 52 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); | 52 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, |
| 53 | &val); | ||
| 54 | power_supply_put(psy); | ||
| 53 | 55 | ||
| 54 | if (!ret && val.intval) { | 56 | if (!ret && val.intval) { |
| 55 | charger_present = true; | 57 | charger_present = true; |
| @@ -63,8 +65,8 @@ static void ab8500_power_off(void) | |||
| 63 | /* Check if battery is known */ | 65 | /* Check if battery is known */ |
| 64 | psy = power_supply_get_by_name("ab8500_btemp"); | 66 | psy = power_supply_get_by_name("ab8500_btemp"); |
| 65 | if (psy) { | 67 | if (psy) { |
| 66 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_TECHNOLOGY, | 68 | ret = power_supply_get_property(psy, |
| 67 | &val); | 69 | POWER_SUPPLY_PROP_TECHNOLOGY, &val); |
| 68 | if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) { | 70 | if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) { |
| 69 | printk(KERN_INFO | 71 | printk(KERN_INFO |
| 70 | "Charger \"%s\" is connected with known battery." | 72 | "Charger \"%s\" is connected with known battery." |
| @@ -72,6 +74,7 @@ static void ab8500_power_off(void) | |||
| 72 | pss[i]); | 74 | pss[i]); |
| 73 | machine_restart("charging"); | 75 | machine_restart("charging"); |
| 74 | } | 76 | } |
| 77 | power_supply_put(psy); | ||
| 75 | } | 78 | } |
| 76 | 79 | ||
| 77 | shutdown: | 80 | shutdown: |
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index b1b580a88654..0acbe52b2411 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c | |||
| @@ -87,7 +87,7 @@ static struct resource axp20x_pek_resources[] = { | |||
| 87 | }, | 87 | }, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | static struct resource axp288_battery_resources[] = { | 90 | static struct resource axp288_fuel_gauge_resources[] = { |
| 91 | { | 91 | { |
| 92 | .start = AXP288_IRQ_QWBTU, | 92 | .start = AXP288_IRQ_QWBTU, |
| 93 | .end = AXP288_IRQ_QWBTU, | 93 | .end = AXP288_IRQ_QWBTU, |
| @@ -350,9 +350,9 @@ static struct mfd_cell axp288_cells[] = { | |||
| 350 | .resources = axp288_charger_resources, | 350 | .resources = axp288_charger_resources, |
| 351 | }, | 351 | }, |
| 352 | { | 352 | { |
| 353 | .name = "axp288_battery", | 353 | .name = "axp288_fuel_gauge", |
| 354 | .num_resources = ARRAY_SIZE(axp288_battery_resources), | 354 | .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), |
| 355 | .resources = axp288_battery_resources, | 355 | .resources = axp288_fuel_gauge_resources, |
| 356 | }, | 356 | }, |
| 357 | { | 357 | { |
| 358 | .name = "axp288_pmic_acpi", | 358 | .name = "axp288_pmic_acpi", |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 15c0fab2bfa1..b4e94471f3d5 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
| @@ -177,7 +177,7 @@ struct compal_data{ | |||
| 177 | unsigned char curr_pwm; | 177 | unsigned char curr_pwm; |
| 178 | 178 | ||
| 179 | /* Power supply */ | 179 | /* Power supply */ |
| 180 | struct power_supply psy; | 180 | struct power_supply *psy; |
| 181 | struct power_supply_info psy_info; | 181 | struct power_supply_info psy_info; |
| 182 | char bat_model_name[BAT_MODEL_NAME_LEN + 1]; | 182 | char bat_model_name[BAT_MODEL_NAME_LEN + 1]; |
| 183 | char bat_manufacturer_name[BAT_MANUFACTURER_NAME_LEN + 1]; | 183 | char bat_manufacturer_name[BAT_MANUFACTURER_NAME_LEN + 1]; |
| @@ -565,8 +565,7 @@ static int bat_get_property(struct power_supply *psy, | |||
| 565 | enum power_supply_property psp, | 565 | enum power_supply_property psp, |
| 566 | union power_supply_propval *val) | 566 | union power_supply_propval *val) |
| 567 | { | 567 | { |
| 568 | struct compal_data *data; | 568 | struct compal_data *data = power_supply_get_drvdata(psy); |
| 569 | data = container_of(psy, struct compal_data, psy); | ||
| 570 | 569 | ||
| 571 | switch (psp) { | 570 | switch (psp) { |
| 572 | case POWER_SUPPLY_PROP_STATUS: | 571 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -875,13 +874,16 @@ static struct dmi_system_id __initdata compal_dmi_table[] = { | |||
| 875 | }; | 874 | }; |
| 876 | MODULE_DEVICE_TABLE(dmi, compal_dmi_table); | 875 | MODULE_DEVICE_TABLE(dmi, compal_dmi_table); |
| 877 | 876 | ||
| 877 | static const struct power_supply_desc psy_bat_desc = { | ||
| 878 | .name = DRIVER_NAME, | ||
| 879 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 880 | .properties = compal_bat_properties, | ||
| 881 | .num_properties = ARRAY_SIZE(compal_bat_properties), | ||
| 882 | .get_property = bat_get_property, | ||
| 883 | }; | ||
| 884 | |||
| 878 | static void initialize_power_supply_data(struct compal_data *data) | 885 | static void initialize_power_supply_data(struct compal_data *data) |
| 879 | { | 886 | { |
| 880 | data->psy.name = DRIVER_NAME; | ||
| 881 | data->psy.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 882 | data->psy.properties = compal_bat_properties; | ||
| 883 | data->psy.num_properties = ARRAY_SIZE(compal_bat_properties); | ||
| 884 | data->psy.get_property = bat_get_property; | ||
| 885 | 887 | ||
| 886 | ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR, | 888 | ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR, |
| 887 | data->bat_manufacturer_name, | 889 | data->bat_manufacturer_name, |
| @@ -1011,6 +1013,7 @@ static int compal_probe(struct platform_device *pdev) | |||
| 1011 | int err; | 1013 | int err; |
| 1012 | struct compal_data *data; | 1014 | struct compal_data *data; |
| 1013 | struct device *hwmon_dev; | 1015 | struct device *hwmon_dev; |
| 1016 | struct power_supply_config psy_cfg = {}; | ||
| 1014 | 1017 | ||
| 1015 | if (!extra_features) | 1018 | if (!extra_features) |
| 1016 | return 0; | 1019 | return 0; |
| @@ -1026,9 +1029,9 @@ static int compal_probe(struct platform_device *pdev) | |||
| 1026 | if (err) | 1029 | if (err) |
| 1027 | return err; | 1030 | return err; |
| 1028 | 1031 | ||
| 1029 | hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, | 1032 | hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, |
| 1030 | "compal", data, | 1033 | "compal", data, |
| 1031 | compal_hwmon_groups); | 1034 | compal_hwmon_groups); |
| 1032 | if (IS_ERR(hwmon_dev)) { | 1035 | if (IS_ERR(hwmon_dev)) { |
| 1033 | err = PTR_ERR(hwmon_dev); | 1036 | err = PTR_ERR(hwmon_dev); |
| 1034 | goto remove; | 1037 | goto remove; |
| @@ -1036,7 +1039,13 @@ static int compal_probe(struct platform_device *pdev) | |||
| 1036 | 1039 | ||
| 1037 | /* Power supply */ | 1040 | /* Power supply */ |
| 1038 | initialize_power_supply_data(data); | 1041 | initialize_power_supply_data(data); |
| 1039 | power_supply_register(&compal_device->dev, &data->psy); | 1042 | psy_cfg.drv_data = data; |
| 1043 | data->psy = power_supply_register(&compal_device->dev, &psy_bat_desc, | ||
| 1044 | &psy_cfg); | ||
| 1045 | if (IS_ERR(data->psy)) { | ||
| 1046 | err = PTR_ERR(data->psy); | ||
| 1047 | goto remove; | ||
| 1048 | } | ||
| 1040 | 1049 | ||
| 1041 | platform_set_drvdata(pdev, data); | 1050 | platform_set_drvdata(pdev, data); |
| 1042 | 1051 | ||
| @@ -1071,7 +1080,7 @@ static int compal_remove(struct platform_device *pdev) | |||
| 1071 | pwm_disable_control(); | 1080 | pwm_disable_control(); |
| 1072 | 1081 | ||
| 1073 | data = platform_get_drvdata(pdev); | 1082 | data = platform_get_drvdata(pdev); |
| 1074 | power_supply_unregister(&data->psy); | 1083 | power_supply_unregister(data->psy); |
| 1075 | 1084 | ||
| 1076 | sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group); | 1085 | sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group); |
| 1077 | 1086 | ||
diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c index bd3c997f4fee..d49579b227ec 100644 --- a/drivers/power/88pm860x_battery.c +++ b/drivers/power/88pm860x_battery.c | |||
| @@ -98,7 +98,7 @@ struct pm860x_battery_info { | |||
| 98 | struct i2c_client *i2c; | 98 | struct i2c_client *i2c; |
| 99 | struct device *dev; | 99 | struct device *dev; |
| 100 | 100 | ||
| 101 | struct power_supply battery; | 101 | struct power_supply *battery; |
| 102 | struct mutex lock; | 102 | struct mutex lock; |
| 103 | int status; | 103 | int status; |
| 104 | int irq_cc; | 104 | int irq_cc; |
| @@ -798,9 +798,8 @@ out: | |||
| 798 | 798 | ||
| 799 | static void pm860x_external_power_changed(struct power_supply *psy) | 799 | static void pm860x_external_power_changed(struct power_supply *psy) |
| 800 | { | 800 | { |
| 801 | struct pm860x_battery_info *info; | 801 | struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); |
| 802 | 802 | ||
| 803 | info = container_of(psy, struct pm860x_battery_info, battery); | ||
| 804 | calc_resistor(info); | 803 | calc_resistor(info); |
| 805 | } | 804 | } |
| 806 | 805 | ||
| @@ -808,7 +807,7 @@ static int pm860x_batt_get_prop(struct power_supply *psy, | |||
| 808 | enum power_supply_property psp, | 807 | enum power_supply_property psp, |
| 809 | union power_supply_propval *val) | 808 | union power_supply_propval *val) |
| 810 | { | 809 | { |
| 811 | struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent); | 810 | struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); |
| 812 | int data; | 811 | int data; |
| 813 | int ret; | 812 | int ret; |
| 814 | 813 | ||
| @@ -874,7 +873,7 @@ static int pm860x_batt_set_prop(struct power_supply *psy, | |||
| 874 | enum power_supply_property psp, | 873 | enum power_supply_property psp, |
| 875 | const union power_supply_propval *val) | 874 | const union power_supply_propval *val) |
| 876 | { | 875 | { |
| 877 | struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent); | 876 | struct pm860x_battery_info *info = dev_get_drvdata(psy->dev.parent); |
| 878 | 877 | ||
| 879 | switch (psp) { | 878 | switch (psp) { |
| 880 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 879 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
| @@ -901,6 +900,16 @@ static enum power_supply_property pm860x_batt_props[] = { | |||
| 901 | POWER_SUPPLY_PROP_TEMP, | 900 | POWER_SUPPLY_PROP_TEMP, |
| 902 | }; | 901 | }; |
| 903 | 902 | ||
| 903 | static const struct power_supply_desc pm860x_battery_desc = { | ||
| 904 | .name = "battery-monitor", | ||
| 905 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 906 | .properties = pm860x_batt_props, | ||
| 907 | .num_properties = ARRAY_SIZE(pm860x_batt_props), | ||
| 908 | .get_property = pm860x_batt_get_prop, | ||
| 909 | .set_property = pm860x_batt_set_prop, | ||
| 910 | .external_power_changed = pm860x_external_power_changed, | ||
| 911 | }; | ||
| 912 | |||
| 904 | static int pm860x_battery_probe(struct platform_device *pdev) | 913 | static int pm860x_battery_probe(struct platform_device *pdev) |
| 905 | { | 914 | { |
| 906 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 915 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| @@ -936,14 +945,6 @@ static int pm860x_battery_probe(struct platform_device *pdev) | |||
| 936 | 945 | ||
| 937 | pm860x_init_battery(info); | 946 | pm860x_init_battery(info); |
| 938 | 947 | ||
| 939 | info->battery.name = "battery-monitor"; | ||
| 940 | info->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 941 | info->battery.properties = pm860x_batt_props; | ||
| 942 | info->battery.num_properties = ARRAY_SIZE(pm860x_batt_props); | ||
| 943 | info->battery.get_property = pm860x_batt_get_prop; | ||
| 944 | info->battery.set_property = pm860x_batt_set_prop; | ||
| 945 | info->battery.external_power_changed = pm860x_external_power_changed; | ||
| 946 | |||
| 947 | if (pdata && pdata->max_capacity) | 948 | if (pdata && pdata->max_capacity) |
| 948 | info->max_capacity = pdata->max_capacity; | 949 | info->max_capacity = pdata->max_capacity; |
| 949 | else | 950 | else |
| @@ -953,10 +954,11 @@ static int pm860x_battery_probe(struct platform_device *pdev) | |||
| 953 | else | 954 | else |
| 954 | info->resistor = 300; /* set default internal resistor */ | 955 | info->resistor = 300; /* set default internal resistor */ |
| 955 | 956 | ||
| 956 | ret = power_supply_register(&pdev->dev, &info->battery); | 957 | info->battery = power_supply_register(&pdev->dev, &pm860x_battery_desc, |
| 957 | if (ret) | 958 | NULL); |
| 958 | return ret; | 959 | if (IS_ERR(info->battery)) |
| 959 | info->battery.dev->parent = &pdev->dev; | 960 | return PTR_ERR(info->battery); |
| 961 | info->battery->dev.parent = &pdev->dev; | ||
| 960 | 962 | ||
| 961 | ret = request_threaded_irq(info->irq_cc, NULL, | 963 | ret = request_threaded_irq(info->irq_cc, NULL, |
| 962 | pm860x_coulomb_handler, IRQF_ONESHOT, | 964 | pm860x_coulomb_handler, IRQF_ONESHOT, |
| @@ -981,7 +983,7 @@ static int pm860x_battery_probe(struct platform_device *pdev) | |||
| 981 | out_coulomb: | 983 | out_coulomb: |
| 982 | free_irq(info->irq_cc, info); | 984 | free_irq(info->irq_cc, info); |
| 983 | out_reg: | 985 | out_reg: |
| 984 | power_supply_unregister(&info->battery); | 986 | power_supply_unregister(info->battery); |
| 985 | return ret; | 987 | return ret; |
| 986 | } | 988 | } |
| 987 | 989 | ||
| @@ -991,7 +993,7 @@ static int pm860x_battery_remove(struct platform_device *pdev) | |||
| 991 | 993 | ||
| 992 | free_irq(info->irq_batt, info); | 994 | free_irq(info->irq_batt, info); |
| 993 | free_irq(info->irq_cc, info); | 995 | free_irq(info->irq_cc, info); |
| 994 | power_supply_unregister(&info->battery); | 996 | power_supply_unregister(info->battery); |
| 995 | return 0; | 997 | return 0; |
| 996 | } | 998 | } |
| 997 | 999 | ||
diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c index 734ec4afa14d..0e448c68c02b 100644 --- a/drivers/power/88pm860x_charger.c +++ b/drivers/power/88pm860x_charger.c | |||
| @@ -102,7 +102,7 @@ struct pm860x_charger_info { | |||
| 102 | struct i2c_client *i2c_8606; | 102 | struct i2c_client *i2c_8606; |
| 103 | struct device *dev; | 103 | struct device *dev; |
| 104 | 104 | ||
| 105 | struct power_supply usb; | 105 | struct power_supply *usb; |
| 106 | struct mutex lock; | 106 | struct mutex lock; |
| 107 | int irq_nums; | 107 | int irq_nums; |
| 108 | int irq[7]; | 108 | int irq[7]; |
| @@ -296,14 +296,20 @@ static int set_charging_fsm(struct pm860x_charger_info *info) | |||
| 296 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); | 296 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); |
| 297 | if (!psy) | 297 | if (!psy) |
| 298 | return -EINVAL; | 298 | return -EINVAL; |
| 299 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &data); | 299 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, |
| 300 | if (ret) | 300 | &data); |
| 301 | if (ret) { | ||
| 302 | power_supply_put(psy); | ||
| 301 | return ret; | 303 | return ret; |
| 304 | } | ||
| 302 | vbatt = data.intval / 1000; | 305 | vbatt = data.intval / 1000; |
| 303 | 306 | ||
| 304 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, &data); | 307 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, &data); |
| 305 | if (ret) | 308 | if (ret) { |
| 309 | power_supply_put(psy); | ||
| 306 | return ret; | 310 | return ret; |
| 311 | } | ||
| 312 | power_supply_put(psy); | ||
| 307 | 313 | ||
| 308 | mutex_lock(&info->lock); | 314 | mutex_lock(&info->lock); |
| 309 | info->present = data.intval; | 315 | info->present = data.intval; |
| @@ -414,7 +420,7 @@ static irqreturn_t pm860x_charger_handler(int irq, void *data) | |||
| 414 | 420 | ||
| 415 | set_charging_fsm(info); | 421 | set_charging_fsm(info); |
| 416 | 422 | ||
| 417 | power_supply_changed(&info->usb); | 423 | power_supply_changed(info->usb); |
| 418 | out: | 424 | out: |
| 419 | return IRQ_HANDLED; | 425 | return IRQ_HANDLED; |
| 420 | } | 426 | } |
| @@ -430,7 +436,7 @@ static irqreturn_t pm860x_temp_handler(int irq, void *data) | |||
| 430 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); | 436 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); |
| 431 | if (!psy) | 437 | if (!psy) |
| 432 | goto out; | 438 | goto out; |
| 433 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp); | 439 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp); |
| 434 | if (ret) | 440 | if (ret) |
| 435 | goto out; | 441 | goto out; |
| 436 | value = temp.intval / 10; | 442 | value = temp.intval / 10; |
| @@ -446,6 +452,7 @@ static irqreturn_t pm860x_temp_handler(int irq, void *data) | |||
| 446 | 452 | ||
| 447 | set_charging_fsm(info); | 453 | set_charging_fsm(info); |
| 448 | out: | 454 | out: |
| 455 | power_supply_put(psy); | ||
| 449 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
| 450 | } | 457 | } |
| 451 | 458 | ||
| @@ -485,9 +492,10 @@ static irqreturn_t pm860x_done_handler(int irq, void *data) | |||
| 485 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); | 492 | psy = power_supply_get_by_name(pm860x_supplied_to[0]); |
| 486 | if (!psy) | 493 | if (!psy) |
| 487 | goto out; | 494 | goto out; |
| 488 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); | 495 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, |
| 496 | &val); | ||
| 489 | if (ret) | 497 | if (ret) |
| 490 | goto out; | 498 | goto out_psy_put; |
| 491 | vbatt = val.intval / 1000; | 499 | vbatt = val.intval / 1000; |
| 492 | /* | 500 | /* |
| 493 | * CHG_DONE interrupt is faster than CHG_DET interrupt when | 501 | * CHG_DONE interrupt is faster than CHG_DET interrupt when |
| @@ -498,10 +506,13 @@ static irqreturn_t pm860x_done_handler(int irq, void *data) | |||
| 498 | */ | 506 | */ |
| 499 | ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); | 507 | ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); |
| 500 | if (ret < 0) | 508 | if (ret < 0) |
| 501 | goto out; | 509 | goto out_psy_put; |
| 502 | if (vbatt > CHARGE_THRESHOLD && ret & STATUS2_CHG) | 510 | if (vbatt > CHARGE_THRESHOLD && ret & STATUS2_CHG) |
| 503 | psy->set_property(psy, POWER_SUPPLY_PROP_CHARGE_FULL, &val); | 511 | power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_FULL, |
| 512 | &val); | ||
| 504 | 513 | ||
| 514 | out_psy_put: | ||
| 515 | power_supply_put(psy); | ||
| 505 | out: | 516 | out: |
| 506 | mutex_unlock(&info->lock); | 517 | mutex_unlock(&info->lock); |
| 507 | dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); | 518 | dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); |
| @@ -584,8 +595,7 @@ static int pm860x_usb_get_prop(struct power_supply *psy, | |||
| 584 | enum power_supply_property psp, | 595 | enum power_supply_property psp, |
| 585 | union power_supply_propval *val) | 596 | union power_supply_propval *val) |
| 586 | { | 597 | { |
| 587 | struct pm860x_charger_info *info = | 598 | struct pm860x_charger_info *info = power_supply_get_drvdata(psy); |
| 588 | dev_get_drvdata(psy->dev->parent); | ||
| 589 | 599 | ||
| 590 | switch (psp) { | 600 | switch (psp) { |
| 591 | case POWER_SUPPLY_PROP_STATUS: | 601 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -645,9 +655,18 @@ static struct pm860x_irq_desc { | |||
| 645 | { "vchg", pm860x_vchg_handler }, | 655 | { "vchg", pm860x_vchg_handler }, |
| 646 | }; | 656 | }; |
| 647 | 657 | ||
| 658 | static const struct power_supply_desc pm860x_charger_desc = { | ||
| 659 | .name = "usb", | ||
| 660 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 661 | .properties = pm860x_usb_props, | ||
| 662 | .num_properties = ARRAY_SIZE(pm860x_usb_props), | ||
| 663 | .get_property = pm860x_usb_get_prop, | ||
| 664 | }; | ||
| 665 | |||
| 648 | static int pm860x_charger_probe(struct platform_device *pdev) | 666 | static int pm860x_charger_probe(struct platform_device *pdev) |
| 649 | { | 667 | { |
| 650 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 668 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| 669 | struct power_supply_config psy_cfg = {}; | ||
| 651 | struct pm860x_charger_info *info; | 670 | struct pm860x_charger_info *info; |
| 652 | int ret; | 671 | int ret; |
| 653 | int count; | 672 | int count; |
| @@ -685,16 +704,15 @@ static int pm860x_charger_probe(struct platform_device *pdev) | |||
| 685 | mutex_init(&info->lock); | 704 | mutex_init(&info->lock); |
| 686 | platform_set_drvdata(pdev, info); | 705 | platform_set_drvdata(pdev, info); |
| 687 | 706 | ||
| 688 | info->usb.name = "usb"; | 707 | psy_cfg.drv_data = info; |
| 689 | info->usb.type = POWER_SUPPLY_TYPE_USB; | 708 | psy_cfg.supplied_to = pm860x_supplied_to; |
| 690 | info->usb.supplied_to = pm860x_supplied_to; | 709 | psy_cfg.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); |
| 691 | info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); | 710 | info->usb = power_supply_register(&pdev->dev, &pm860x_charger_desc, |
| 692 | info->usb.properties = pm860x_usb_props; | 711 | &psy_cfg); |
| 693 | info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props); | 712 | if (IS_ERR(info->usb)) { |
| 694 | info->usb.get_property = pm860x_usb_get_prop; | 713 | ret = PTR_ERR(info->usb); |
| 695 | ret = power_supply_register(&pdev->dev, &info->usb); | ||
| 696 | if (ret) | ||
| 697 | goto out; | 714 | goto out; |
| 715 | } | ||
| 698 | 716 | ||
| 699 | pm860x_init_charger(info); | 717 | pm860x_init_charger(info); |
| 700 | 718 | ||
| @@ -711,7 +729,7 @@ static int pm860x_charger_probe(struct platform_device *pdev) | |||
| 711 | return 0; | 729 | return 0; |
| 712 | 730 | ||
| 713 | out_irq: | 731 | out_irq: |
| 714 | power_supply_unregister(&info->usb); | 732 | power_supply_unregister(info->usb); |
| 715 | while (--i >= 0) | 733 | while (--i >= 0) |
| 716 | free_irq(info->irq[i], info); | 734 | free_irq(info->irq[i], info); |
| 717 | out: | 735 | out: |
| @@ -723,7 +741,7 @@ static int pm860x_charger_remove(struct platform_device *pdev) | |||
| 723 | struct pm860x_charger_info *info = platform_get_drvdata(pdev); | 741 | struct pm860x_charger_info *info = platform_get_drvdata(pdev); |
| 724 | int i; | 742 | int i; |
| 725 | 743 | ||
| 726 | power_supply_unregister(&info->usb); | 744 | power_supply_unregister(info->usb); |
| 727 | free_irq(info->irq[0], info); | 745 | free_irq(info->irq[0], info); |
| 728 | for (i = 0; i < info->irq_nums; i++) | 746 | for (i = 0; i < info->irq_nums; i++) |
| 729 | free_irq(info->irq[i], info); | 747 | free_irq(info->irq[i], info); |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 27b751b995fb..4091fb092d06 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
| @@ -192,6 +192,27 @@ config BATTERY_DA9052 | |||
| 192 | Say Y here to enable support for batteries charger integrated into | 192 | Say Y here to enable support for batteries charger integrated into |
| 193 | DA9052 PMIC. | 193 | DA9052 PMIC. |
| 194 | 194 | ||
| 195 | config CHARGER_DA9150 | ||
| 196 | tristate "Dialog Semiconductor DA9150 Charger support" | ||
| 197 | depends on MFD_DA9150 | ||
| 198 | depends on DA9150_GPADC | ||
| 199 | depends on IIO | ||
| 200 | help | ||
| 201 | Say Y here to enable support for charger unit of the DA9150 | ||
| 202 | Integrated Charger & Fuel-Gauge IC. | ||
| 203 | |||
| 204 | This driver can also be built as a module. If so, the module will be | ||
| 205 | called da9150-charger. | ||
| 206 | |||
| 207 | config AXP288_FUEL_GAUGE | ||
| 208 | tristate "X-Powers AXP288 Fuel Gauge" | ||
| 209 | depends on MFD_AXP20X && IIO | ||
| 210 | help | ||
| 211 | Say yes here to have support for X-Power power management IC (PMIC) | ||
| 212 | Fuel Gauge. The device provides battery statistics and status | ||
| 213 | monitoring as well as alerts for battery over/under voltage and | ||
| 214 | over/under temperature. | ||
| 215 | |||
| 195 | config BATTERY_MAX17040 | 216 | config BATTERY_MAX17040 |
| 196 | tristate "Maxim MAX17040 Fuel Gauge" | 217 | tristate "Maxim MAX17040 Fuel Gauge" |
| 197 | depends on I2C | 218 | depends on I2C |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 36f9e0d10111..b7b0181c95e5 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ccflags-$(CONFIG_POWER_SUPPLY_DEBUG) := -DDEBUG | 1 | subdir-ccflags-$(CONFIG_POWER_SUPPLY_DEBUG) := -DDEBUG |
| 2 | 2 | ||
| 3 | power_supply-y := power_supply_core.o | 3 | power_supply-y := power_supply_core.o |
| 4 | power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o | 4 | power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o |
| @@ -32,6 +32,7 @@ obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o | |||
| 32 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o | 32 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o |
| 33 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o | 33 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o |
| 34 | obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o | 34 | obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o |
| 35 | obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o | ||
| 35 | obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o | 36 | obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o |
| 36 | obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o | 37 | obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o |
| 37 | obj-$(CONFIG_BATTERY_Z2) += z2_battery.o | 38 | obj-$(CONFIG_BATTERY_Z2) += z2_battery.o |
| @@ -62,3 +63,4 @@ obj-$(CONFIG_POWER_AVS) += avs/ | |||
| 62 | obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o | 63 | obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o |
| 63 | obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o | 64 | obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o |
| 64 | obj-$(CONFIG_POWER_RESET) += reset/ | 65 | obj-$(CONFIG_POWER_RESET) += reset/ |
| 66 | obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o | ||
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 4ebf7b0819f7..8f8044e1acf3 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c | |||
| @@ -45,9 +45,6 @@ | |||
| 45 | #define BTEMP_BATCTRL_CURR_SRC_60UA 60 | 45 | #define BTEMP_BATCTRL_CURR_SRC_60UA 60 |
| 46 | #define BTEMP_BATCTRL_CURR_SRC_120UA 120 | 46 | #define BTEMP_BATCTRL_CURR_SRC_120UA 120 |
| 47 | 47 | ||
| 48 | #define to_ab8500_btemp_device_info(x) container_of((x), \ | ||
| 49 | struct ab8500_btemp, btemp_psy); | ||
| 50 | |||
| 51 | /** | 48 | /** |
| 52 | * struct ab8500_btemp_interrupts - ab8500 interrupts | 49 | * struct ab8500_btemp_interrupts - ab8500 interrupts |
| 53 | * @name: name of the interrupt | 50 | * @name: name of the interrupt |
| @@ -102,7 +99,7 @@ struct ab8500_btemp { | |||
| 102 | struct ab8500_gpadc *gpadc; | 99 | struct ab8500_gpadc *gpadc; |
| 103 | struct ab8500_fg *fg; | 100 | struct ab8500_fg *fg; |
| 104 | struct abx500_bm_data *bm; | 101 | struct abx500_bm_data *bm; |
| 105 | struct power_supply btemp_psy; | 102 | struct power_supply *btemp_psy; |
| 106 | struct ab8500_btemp_events events; | 103 | struct ab8500_btemp_events events; |
| 107 | struct ab8500_btemp_ranges btemp_ranges; | 104 | struct ab8500_btemp_ranges btemp_ranges; |
| 108 | struct workqueue_struct *btemp_wq; | 105 | struct workqueue_struct *btemp_wq; |
| @@ -654,14 +651,14 @@ static void ab8500_btemp_periodic_work(struct work_struct *work) | |||
| 654 | if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { | 651 | if ((di->bat_temp != di->prev_bat_temp) || !di->initialized) { |
| 655 | di->initialized = true; | 652 | di->initialized = true; |
| 656 | di->bat_temp = bat_temp; | 653 | di->bat_temp = bat_temp; |
| 657 | power_supply_changed(&di->btemp_psy); | 654 | power_supply_changed(di->btemp_psy); |
| 658 | } | 655 | } |
| 659 | } else if (bat_temp < di->prev_bat_temp) { | 656 | } else if (bat_temp < di->prev_bat_temp) { |
| 660 | di->bat_temp--; | 657 | di->bat_temp--; |
| 661 | power_supply_changed(&di->btemp_psy); | 658 | power_supply_changed(di->btemp_psy); |
| 662 | } else if (bat_temp > di->prev_bat_temp) { | 659 | } else if (bat_temp > di->prev_bat_temp) { |
| 663 | di->bat_temp++; | 660 | di->bat_temp++; |
| 664 | power_supply_changed(&di->btemp_psy); | 661 | power_supply_changed(di->btemp_psy); |
| 665 | } | 662 | } |
| 666 | di->prev_bat_temp = bat_temp; | 663 | di->prev_bat_temp = bat_temp; |
| 667 | 664 | ||
| @@ -689,7 +686,7 @@ static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di) | |||
| 689 | dev_err(di->dev, "Battery removal detected!\n"); | 686 | dev_err(di->dev, "Battery removal detected!\n"); |
| 690 | 687 | ||
| 691 | di->events.batt_rem = true; | 688 | di->events.batt_rem = true; |
| 692 | power_supply_changed(&di->btemp_psy); | 689 | power_supply_changed(di->btemp_psy); |
| 693 | 690 | ||
| 694 | return IRQ_HANDLED; | 691 | return IRQ_HANDLED; |
| 695 | } | 692 | } |
| @@ -715,7 +712,7 @@ static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di) | |||
| 715 | di->events.btemp_high = false; | 712 | di->events.btemp_high = false; |
| 716 | di->events.btemp_medhigh = false; | 713 | di->events.btemp_medhigh = false; |
| 717 | di->events.btemp_lowmed = false; | 714 | di->events.btemp_lowmed = false; |
| 718 | power_supply_changed(&di->btemp_psy); | 715 | power_supply_changed(di->btemp_psy); |
| 719 | } | 716 | } |
| 720 | 717 | ||
| 721 | return IRQ_HANDLED; | 718 | return IRQ_HANDLED; |
| @@ -738,7 +735,7 @@ static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di) | |||
| 738 | di->events.btemp_medhigh = false; | 735 | di->events.btemp_medhigh = false; |
| 739 | di->events.btemp_lowmed = false; | 736 | di->events.btemp_lowmed = false; |
| 740 | di->events.btemp_low = false; | 737 | di->events.btemp_low = false; |
| 741 | power_supply_changed(&di->btemp_psy); | 738 | power_supply_changed(di->btemp_psy); |
| 742 | 739 | ||
| 743 | return IRQ_HANDLED; | 740 | return IRQ_HANDLED; |
| 744 | } | 741 | } |
| @@ -760,7 +757,7 @@ static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di) | |||
| 760 | di->events.btemp_medhigh = false; | 757 | di->events.btemp_medhigh = false; |
| 761 | di->events.btemp_high = false; | 758 | di->events.btemp_high = false; |
| 762 | di->events.btemp_low = false; | 759 | di->events.btemp_low = false; |
| 763 | power_supply_changed(&di->btemp_psy); | 760 | power_supply_changed(di->btemp_psy); |
| 764 | 761 | ||
| 765 | return IRQ_HANDLED; | 762 | return IRQ_HANDLED; |
| 766 | } | 763 | } |
| @@ -782,7 +779,7 @@ static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di) | |||
| 782 | di->events.btemp_lowmed = false; | 779 | di->events.btemp_lowmed = false; |
| 783 | di->events.btemp_high = false; | 780 | di->events.btemp_high = false; |
| 784 | di->events.btemp_low = false; | 781 | di->events.btemp_low = false; |
| 785 | power_supply_changed(&di->btemp_psy); | 782 | power_supply_changed(di->btemp_psy); |
| 786 | 783 | ||
| 787 | return IRQ_HANDLED; | 784 | return IRQ_HANDLED; |
| 788 | } | 785 | } |
| @@ -884,9 +881,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy, | |||
| 884 | enum power_supply_property psp, | 881 | enum power_supply_property psp, |
| 885 | union power_supply_propval *val) | 882 | union power_supply_propval *val) |
| 886 | { | 883 | { |
| 887 | struct ab8500_btemp *di; | 884 | struct ab8500_btemp *di = power_supply_get_drvdata(psy); |
| 888 | |||
| 889 | di = to_ab8500_btemp_device_info(psy); | ||
| 890 | 885 | ||
| 891 | switch (psp) { | 886 | switch (psp) { |
| 892 | case POWER_SUPPLY_PROP_PRESENT: | 887 | case POWER_SUPPLY_PROP_PRESENT: |
| @@ -919,14 +914,14 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) | |||
| 919 | 914 | ||
| 920 | psy = (struct power_supply *)data; | 915 | psy = (struct power_supply *)data; |
| 921 | ext = dev_get_drvdata(dev); | 916 | ext = dev_get_drvdata(dev); |
| 922 | di = to_ab8500_btemp_device_info(psy); | 917 | di = power_supply_get_drvdata(psy); |
| 923 | 918 | ||
| 924 | /* | 919 | /* |
| 925 | * For all psy where the name of your driver | 920 | * For all psy where the name of your driver |
| 926 | * appears in any supplied_to | 921 | * appears in any supplied_to |
| 927 | */ | 922 | */ |
| 928 | for (i = 0; i < ext->num_supplicants; i++) { | 923 | for (i = 0; i < ext->num_supplicants; i++) { |
| 929 | if (!strcmp(ext->supplied_to[i], psy->name)) | 924 | if (!strcmp(ext->supplied_to[i], psy->desc->name)) |
| 930 | psy_found = true; | 925 | psy_found = true; |
| 931 | } | 926 | } |
| 932 | 927 | ||
| @@ -934,16 +929,16 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) | |||
| 934 | return 0; | 929 | return 0; |
| 935 | 930 | ||
| 936 | /* Go through all properties for the psy */ | 931 | /* Go through all properties for the psy */ |
| 937 | for (j = 0; j < ext->num_properties; j++) { | 932 | for (j = 0; j < ext->desc->num_properties; j++) { |
| 938 | enum power_supply_property prop; | 933 | enum power_supply_property prop; |
| 939 | prop = ext->properties[j]; | 934 | prop = ext->desc->properties[j]; |
| 940 | 935 | ||
| 941 | if (ext->get_property(ext, prop, &ret)) | 936 | if (power_supply_get_property(ext, prop, &ret)) |
| 942 | continue; | 937 | continue; |
| 943 | 938 | ||
| 944 | switch (prop) { | 939 | switch (prop) { |
| 945 | case POWER_SUPPLY_PROP_PRESENT: | 940 | case POWER_SUPPLY_PROP_PRESENT: |
| 946 | switch (ext->type) { | 941 | switch (ext->desc->type) { |
| 947 | case POWER_SUPPLY_TYPE_MAINS: | 942 | case POWER_SUPPLY_TYPE_MAINS: |
| 948 | /* AC disconnected */ | 943 | /* AC disconnected */ |
| 949 | if (!ret.intval && di->events.ac_conn) { | 944 | if (!ret.intval && di->events.ac_conn) { |
| @@ -990,10 +985,10 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) | |||
| 990 | */ | 985 | */ |
| 991 | static void ab8500_btemp_external_power_changed(struct power_supply *psy) | 986 | static void ab8500_btemp_external_power_changed(struct power_supply *psy) |
| 992 | { | 987 | { |
| 993 | struct ab8500_btemp *di = to_ab8500_btemp_device_info(psy); | 988 | struct ab8500_btemp *di = power_supply_get_drvdata(psy); |
| 994 | 989 | ||
| 995 | class_for_each_device(power_supply_class, NULL, | 990 | class_for_each_device(power_supply_class, NULL, |
| 996 | &di->btemp_psy, ab8500_btemp_get_ext_psy_data); | 991 | di->btemp_psy, ab8500_btemp_get_ext_psy_data); |
| 997 | } | 992 | } |
| 998 | 993 | ||
| 999 | /* ab8500 btemp driver interrupts and their respective isr */ | 994 | /* ab8500 btemp driver interrupts and their respective isr */ |
| @@ -1044,7 +1039,7 @@ static int ab8500_btemp_remove(struct platform_device *pdev) | |||
| 1044 | destroy_workqueue(di->btemp_wq); | 1039 | destroy_workqueue(di->btemp_wq); |
| 1045 | 1040 | ||
| 1046 | flush_scheduled_work(); | 1041 | flush_scheduled_work(); |
| 1047 | power_supply_unregister(&di->btemp_psy); | 1042 | power_supply_unregister(di->btemp_psy); |
| 1048 | 1043 | ||
| 1049 | return 0; | 1044 | return 0; |
| 1050 | } | 1045 | } |
| @@ -1054,10 +1049,20 @@ static char *supply_interface[] = { | |||
| 1054 | "ab8500_fg", | 1049 | "ab8500_fg", |
| 1055 | }; | 1050 | }; |
| 1056 | 1051 | ||
| 1052 | static const struct power_supply_desc ab8500_btemp_desc = { | ||
| 1053 | .name = "ab8500_btemp", | ||
| 1054 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 1055 | .properties = ab8500_btemp_props, | ||
| 1056 | .num_properties = ARRAY_SIZE(ab8500_btemp_props), | ||
| 1057 | .get_property = ab8500_btemp_get_property, | ||
| 1058 | .external_power_changed = ab8500_btemp_external_power_changed, | ||
| 1059 | }; | ||
| 1060 | |||
| 1057 | static int ab8500_btemp_probe(struct platform_device *pdev) | 1061 | static int ab8500_btemp_probe(struct platform_device *pdev) |
| 1058 | { | 1062 | { |
| 1059 | struct device_node *np = pdev->dev.of_node; | 1063 | struct device_node *np = pdev->dev.of_node; |
| 1060 | struct abx500_bm_data *plat = pdev->dev.platform_data; | 1064 | struct abx500_bm_data *plat = pdev->dev.platform_data; |
| 1065 | struct power_supply_config psy_cfg = {}; | ||
| 1061 | struct ab8500_btemp *di; | 1066 | struct ab8500_btemp *di; |
| 1062 | int irq, i, ret = 0; | 1067 | int irq, i, ret = 0; |
| 1063 | u8 val; | 1068 | u8 val; |
| @@ -1089,17 +1094,9 @@ static int ab8500_btemp_probe(struct platform_device *pdev) | |||
| 1089 | 1094 | ||
| 1090 | di->initialized = false; | 1095 | di->initialized = false; |
| 1091 | 1096 | ||
| 1092 | /* BTEMP supply */ | 1097 | psy_cfg.supplied_to = supply_interface; |
| 1093 | di->btemp_psy.name = "ab8500_btemp"; | 1098 | psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); |
| 1094 | di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY; | 1099 | psy_cfg.drv_data = di; |
| 1095 | di->btemp_psy.properties = ab8500_btemp_props; | ||
| 1096 | di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props); | ||
| 1097 | di->btemp_psy.get_property = ab8500_btemp_get_property; | ||
| 1098 | di->btemp_psy.supplied_to = supply_interface; | ||
| 1099 | di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface); | ||
| 1100 | di->btemp_psy.external_power_changed = | ||
| 1101 | ab8500_btemp_external_power_changed; | ||
| 1102 | |||
| 1103 | 1100 | ||
| 1104 | /* Create a work queue for the btemp */ | 1101 | /* Create a work queue for the btemp */ |
| 1105 | di->btemp_wq = | 1102 | di->btemp_wq = |
| @@ -1140,9 +1137,11 @@ static int ab8500_btemp_probe(struct platform_device *pdev) | |||
| 1140 | } | 1137 | } |
| 1141 | 1138 | ||
| 1142 | /* Register BTEMP power supply class */ | 1139 | /* Register BTEMP power supply class */ |
| 1143 | ret = power_supply_register(di->dev, &di->btemp_psy); | 1140 | di->btemp_psy = power_supply_register(di->dev, &ab8500_btemp_desc, |
| 1144 | if (ret) { | 1141 | &psy_cfg); |
| 1142 | if (IS_ERR(di->btemp_psy)) { | ||
| 1145 | dev_err(di->dev, "failed to register BTEMP psy\n"); | 1143 | dev_err(di->dev, "failed to register BTEMP psy\n"); |
| 1144 | ret = PTR_ERR(di->btemp_psy); | ||
| 1146 | goto free_btemp_wq; | 1145 | goto free_btemp_wq; |
| 1147 | } | 1146 | } |
| 1148 | 1147 | ||
| @@ -1171,7 +1170,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev) | |||
| 1171 | return ret; | 1170 | return ret; |
| 1172 | 1171 | ||
| 1173 | free_irq: | 1172 | free_irq: |
| 1174 | power_supply_unregister(&di->btemp_psy); | 1173 | power_supply_unregister(di->btemp_psy); |
| 1175 | 1174 | ||
| 1176 | /* We also have to free all successfully registered irqs */ | 1175 | /* We also have to free all successfully registered irqs */ |
| 1177 | for (i = i - 1; i >= 0; i--) { | 1176 | for (i = i - 1; i >= 0; i--) { |
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 8c8d170ff0f8..e388171f4e58 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c | |||
| @@ -435,7 +435,7 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, | |||
| 435 | if (!connected) | 435 | if (!connected) |
| 436 | di->flags.vbus_drop_end = false; | 436 | di->flags.vbus_drop_end = false; |
| 437 | 437 | ||
| 438 | sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); | 438 | sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present"); |
| 439 | 439 | ||
| 440 | if (connected) { | 440 | if (connected) { |
| 441 | mutex_lock(&di->charger_attached_mutex); | 441 | mutex_lock(&di->charger_attached_mutex); |
| @@ -1516,7 +1516,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, | |||
| 1516 | 1516 | ||
| 1517 | dev_dbg(di->dev, "%s Disabled AC charging\n", __func__); | 1517 | dev_dbg(di->dev, "%s Disabled AC charging\n", __func__); |
| 1518 | } | 1518 | } |
| 1519 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 1519 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 1520 | 1520 | ||
| 1521 | return ret; | 1521 | return ret; |
| 1522 | } | 1522 | } |
| @@ -1672,7 +1672,7 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
| 1672 | cancel_delayed_work(&di->check_vbat_work); | 1672 | cancel_delayed_work(&di->check_vbat_work); |
| 1673 | 1673 | ||
| 1674 | } | 1674 | } |
| 1675 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 1675 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 1676 | 1676 | ||
| 1677 | return ret; | 1677 | return ret; |
| 1678 | } | 1678 | } |
| @@ -1811,9 +1811,9 @@ static int ab8500_charger_watchdog_kick(struct ux500_charger *charger) | |||
| 1811 | int ret; | 1811 | int ret; |
| 1812 | struct ab8500_charger *di; | 1812 | struct ab8500_charger *di; |
| 1813 | 1813 | ||
| 1814 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | 1814 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 1815 | di = to_ab8500_charger_ac_device_info(charger); | 1815 | di = to_ab8500_charger_ac_device_info(charger); |
| 1816 | else if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | 1816 | else if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) |
| 1817 | di = to_ab8500_charger_usb_device_info(charger); | 1817 | di = to_ab8500_charger_usb_device_info(charger); |
| 1818 | else | 1818 | else |
| 1819 | return -ENXIO; | 1819 | return -ENXIO; |
| @@ -1839,9 +1839,9 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, | |||
| 1839 | int ret; | 1839 | int ret; |
| 1840 | struct ab8500_charger *di; | 1840 | struct ab8500_charger *di; |
| 1841 | 1841 | ||
| 1842 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | 1842 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 1843 | di = to_ab8500_charger_ac_device_info(charger); | 1843 | di = to_ab8500_charger_ac_device_info(charger); |
| 1844 | else if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | 1844 | else if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) |
| 1845 | di = to_ab8500_charger_usb_device_info(charger); | 1845 | di = to_ab8500_charger_usb_device_info(charger); |
| 1846 | else | 1846 | else |
| 1847 | return -ENXIO; | 1847 | return -ENXIO; |
| @@ -1879,7 +1879,7 @@ static int ab8540_charger_power_path_enable(struct ux500_charger *charger, | |||
| 1879 | int ret; | 1879 | int ret; |
| 1880 | struct ab8500_charger *di; | 1880 | struct ab8500_charger *di; |
| 1881 | 1881 | ||
| 1882 | if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | 1882 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) |
| 1883 | di = to_ab8500_charger_usb_device_info(charger); | 1883 | di = to_ab8500_charger_usb_device_info(charger); |
| 1884 | else | 1884 | else |
| 1885 | return -ENXIO; | 1885 | return -ENXIO; |
| @@ -1910,7 +1910,7 @@ static int ab8540_charger_usb_pre_chg_enable(struct ux500_charger *charger, | |||
| 1910 | int ret; | 1910 | int ret; |
| 1911 | struct ab8500_charger *di; | 1911 | struct ab8500_charger *di; |
| 1912 | 1912 | ||
| 1913 | if (charger->psy.type == POWER_SUPPLY_TYPE_USB) | 1913 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB) |
| 1914 | di = to_ab8500_charger_usb_device_info(charger); | 1914 | di = to_ab8500_charger_usb_device_info(charger); |
| 1915 | else | 1915 | else |
| 1916 | return -ENXIO; | 1916 | return -ENXIO; |
| @@ -1937,7 +1937,7 @@ static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) | |||
| 1937 | struct ux500_charger *usb_chg; | 1937 | struct ux500_charger *usb_chg; |
| 1938 | 1938 | ||
| 1939 | usb_chg = (struct ux500_charger *)data; | 1939 | usb_chg = (struct ux500_charger *)data; |
| 1940 | psy = &usb_chg->psy; | 1940 | psy = usb_chg->psy; |
| 1941 | 1941 | ||
| 1942 | di = to_ab8500_charger_usb_device_info(usb_chg); | 1942 | di = to_ab8500_charger_usb_device_info(usb_chg); |
| 1943 | 1943 | ||
| @@ -1945,7 +1945,7 @@ static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) | |||
| 1945 | 1945 | ||
| 1946 | /* For all psy where the driver name appears in any supplied_to */ | 1946 | /* For all psy where the driver name appears in any supplied_to */ |
| 1947 | for (i = 0; i < ext->num_supplicants; i++) { | 1947 | for (i = 0; i < ext->num_supplicants; i++) { |
| 1948 | if (!strcmp(ext->supplied_to[i], psy->name)) | 1948 | if (!strcmp(ext->supplied_to[i], psy->desc->name)) |
| 1949 | psy_found = true; | 1949 | psy_found = true; |
| 1950 | } | 1950 | } |
| 1951 | 1951 | ||
| @@ -1953,16 +1953,16 @@ static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) | |||
| 1953 | return 0; | 1953 | return 0; |
| 1954 | 1954 | ||
| 1955 | /* Go through all properties for the psy */ | 1955 | /* Go through all properties for the psy */ |
| 1956 | for (j = 0; j < ext->num_properties; j++) { | 1956 | for (j = 0; j < ext->desc->num_properties; j++) { |
| 1957 | enum power_supply_property prop; | 1957 | enum power_supply_property prop; |
| 1958 | prop = ext->properties[j]; | 1958 | prop = ext->desc->properties[j]; |
| 1959 | 1959 | ||
| 1960 | if (ext->get_property(ext, prop, &ret)) | 1960 | if (power_supply_get_property(ext, prop, &ret)) |
| 1961 | continue; | 1961 | continue; |
| 1962 | 1962 | ||
| 1963 | switch (prop) { | 1963 | switch (prop) { |
| 1964 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 1964 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
| 1965 | switch (ext->type) { | 1965 | switch (ext->desc->type) { |
| 1966 | case POWER_SUPPLY_TYPE_BATTERY: | 1966 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1967 | di->vbat = ret.intval / 1000; | 1967 | di->vbat = ret.intval / 1000; |
| 1968 | break; | 1968 | break; |
| @@ -1993,7 +1993,7 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) | |||
| 1993 | struct ab8500_charger, check_vbat_work.work); | 1993 | struct ab8500_charger, check_vbat_work.work); |
| 1994 | 1994 | ||
| 1995 | class_for_each_device(power_supply_class, NULL, | 1995 | class_for_each_device(power_supply_class, NULL, |
| 1996 | &di->usb_chg.psy, ab8500_charger_get_ext_psy_data); | 1996 | di->usb_chg.psy, ab8500_charger_get_ext_psy_data); |
| 1997 | 1997 | ||
| 1998 | /* First run old_vbat is 0. */ | 1998 | /* First run old_vbat is 0. */ |
| 1999 | if (di->old_vbat == 0) | 1999 | if (di->old_vbat == 0) |
| @@ -2009,7 +2009,7 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) | |||
| 2009 | di->vbat, di->old_vbat); | 2009 | di->vbat, di->old_vbat); |
| 2010 | ab8500_charger_set_vbus_in_curr(di, | 2010 | ab8500_charger_set_vbus_in_curr(di, |
| 2011 | di->max_usb_in_curr.usb_type_max); | 2011 | di->max_usb_in_curr.usb_type_max); |
| 2012 | power_supply_changed(&di->usb_chg.psy); | 2012 | power_supply_changed(di->usb_chg.psy); |
| 2013 | } | 2013 | } |
| 2014 | 2014 | ||
| 2015 | di->old_vbat = di->vbat; | 2015 | di->old_vbat = di->vbat; |
| @@ -2049,7 +2049,7 @@ static void ab8500_charger_check_hw_failure_work(struct work_struct *work) | |||
| 2049 | } | 2049 | } |
| 2050 | if (!(reg_value & MAIN_CH_NOK)) { | 2050 | if (!(reg_value & MAIN_CH_NOK)) { |
| 2051 | di->flags.mainextchnotok = false; | 2051 | di->flags.mainextchnotok = false; |
| 2052 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 2052 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 2053 | } | 2053 | } |
| 2054 | } | 2054 | } |
| 2055 | if (di->flags.vbus_ovv) { | 2055 | if (di->flags.vbus_ovv) { |
| @@ -2062,7 +2062,7 @@ static void ab8500_charger_check_hw_failure_work(struct work_struct *work) | |||
| 2062 | } | 2062 | } |
| 2063 | if (!(reg_value & VBUS_OVV_TH)) { | 2063 | if (!(reg_value & VBUS_OVV_TH)) { |
| 2064 | di->flags.vbus_ovv = false; | 2064 | di->flags.vbus_ovv = false; |
| 2065 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2065 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2066 | } | 2066 | } |
| 2067 | } | 2067 | } |
| 2068 | /* If we still have a failure, schedule a new check */ | 2068 | /* If we still have a failure, schedule a new check */ |
| @@ -2132,8 +2132,8 @@ static void ab8500_charger_ac_work(struct work_struct *work) | |||
| 2132 | di->ac.charger_connected = 0; | 2132 | di->ac.charger_connected = 0; |
| 2133 | } | 2133 | } |
| 2134 | 2134 | ||
| 2135 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 2135 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 2136 | sysfs_notify(&di->ac_chg.psy.dev->kobj, NULL, "present"); | 2136 | sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present"); |
| 2137 | } | 2137 | } |
| 2138 | 2138 | ||
| 2139 | static void ab8500_charger_usb_attached_work(struct work_struct *work) | 2139 | static void ab8500_charger_usb_attached_work(struct work_struct *work) |
| @@ -2240,7 +2240,7 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
| 2240 | dev_dbg(di->dev, "%s di->vbus_detected = false\n", __func__); | 2240 | dev_dbg(di->dev, "%s di->vbus_detected = false\n", __func__); |
| 2241 | di->vbus_detected = false; | 2241 | di->vbus_detected = false; |
| 2242 | ab8500_charger_set_usb_connected(di, false); | 2242 | ab8500_charger_set_usb_connected(di, false); |
| 2243 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2243 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2244 | } else { | 2244 | } else { |
| 2245 | dev_dbg(di->dev, "%s di->vbus_detected = true\n", __func__); | 2245 | dev_dbg(di->dev, "%s di->vbus_detected = true\n", __func__); |
| 2246 | di->vbus_detected = true; | 2246 | di->vbus_detected = true; |
| @@ -2250,7 +2250,7 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
| 2250 | if (!ret) { | 2250 | if (!ret) { |
| 2251 | ab8500_charger_set_usb_connected(di, true); | 2251 | ab8500_charger_set_usb_connected(di, true); |
| 2252 | ab8500_power_supply_changed(di, | 2252 | ab8500_power_supply_changed(di, |
| 2253 | &di->usb_chg.psy); | 2253 | di->usb_chg.psy); |
| 2254 | } | 2254 | } |
| 2255 | } else { | 2255 | } else { |
| 2256 | /* | 2256 | /* |
| @@ -2267,7 +2267,7 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
| 2267 | ab8500_charger_set_usb_connected(di, | 2267 | ab8500_charger_set_usb_connected(di, |
| 2268 | true); | 2268 | true); |
| 2269 | ab8500_power_supply_changed(di, | 2269 | ab8500_power_supply_changed(di, |
| 2270 | &di->usb_chg.psy); | 2270 | di->usb_chg.psy); |
| 2271 | } | 2271 | } |
| 2272 | } | 2272 | } |
| 2273 | } | 2273 | } |
| @@ -2295,7 +2295,7 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) | |||
| 2295 | } | 2295 | } |
| 2296 | 2296 | ||
| 2297 | ab8500_charger_set_usb_connected(di, true); | 2297 | ab8500_charger_set_usb_connected(di, true); |
| 2298 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2298 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2299 | } | 2299 | } |
| 2300 | 2300 | ||
| 2301 | /** | 2301 | /** |
| @@ -2393,7 +2393,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
| 2393 | if (!(detected_chargers & USB_PW_CONN)) { | 2393 | if (!(detected_chargers & USB_PW_CONN)) { |
| 2394 | di->vbus_detected = false; | 2394 | di->vbus_detected = false; |
| 2395 | ab8500_charger_set_usb_connected(di, false); | 2395 | ab8500_charger_set_usb_connected(di, false); |
| 2396 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2396 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2397 | return; | 2397 | return; |
| 2398 | } | 2398 | } |
| 2399 | 2399 | ||
| @@ -2404,7 +2404,7 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
| 2404 | if (ret == -ENXIO) { | 2404 | if (ret == -ENXIO) { |
| 2405 | /* No valid charger type detected */ | 2405 | /* No valid charger type detected */ |
| 2406 | ab8500_charger_set_usb_connected(di, false); | 2406 | ab8500_charger_set_usb_connected(di, false); |
| 2407 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2407 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2408 | } | 2408 | } |
| 2409 | return; | 2409 | return; |
| 2410 | } | 2410 | } |
| @@ -2463,7 +2463,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) | |||
| 2463 | case AB8500_BM_USB_STATE_SUSPEND: | 2463 | case AB8500_BM_USB_STATE_SUSPEND: |
| 2464 | case AB8500_BM_USB_STATE_MAX: | 2464 | case AB8500_BM_USB_STATE_MAX: |
| 2465 | ab8500_charger_set_usb_connected(di, false); | 2465 | ab8500_charger_set_usb_connected(di, false); |
| 2466 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2466 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2467 | break; | 2467 | break; |
| 2468 | 2468 | ||
| 2469 | case AB8500_BM_USB_STATE_RESUME: | 2469 | case AB8500_BM_USB_STATE_RESUME: |
| @@ -2486,7 +2486,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) | |||
| 2486 | return; | 2486 | return; |
| 2487 | 2487 | ||
| 2488 | ab8500_charger_set_usb_connected(di, true); | 2488 | ab8500_charger_set_usb_connected(di, true); |
| 2489 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2489 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2490 | } | 2490 | } |
| 2491 | break; | 2491 | break; |
| 2492 | 2492 | ||
| @@ -2530,7 +2530,7 @@ static void ab8500_charger_check_usbchargernotok_work(struct work_struct *work) | |||
| 2530 | } | 2530 | } |
| 2531 | 2531 | ||
| 2532 | if (prev_status != di->flags.usbchargernotok) | 2532 | if (prev_status != di->flags.usbchargernotok) |
| 2533 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2533 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2534 | } | 2534 | } |
| 2535 | 2535 | ||
| 2536 | /** | 2536 | /** |
| @@ -2560,7 +2560,7 @@ static void ab8500_charger_check_main_thermal_prot_work( | |||
| 2560 | else | 2560 | else |
| 2561 | di->flags.main_thermal_prot = false; | 2561 | di->flags.main_thermal_prot = false; |
| 2562 | 2562 | ||
| 2563 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 2563 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 2564 | } | 2564 | } |
| 2565 | 2565 | ||
| 2566 | /** | 2566 | /** |
| @@ -2590,7 +2590,7 @@ static void ab8500_charger_check_usb_thermal_prot_work( | |||
| 2590 | else | 2590 | else |
| 2591 | di->flags.usb_thermal_prot = false; | 2591 | di->flags.usb_thermal_prot = false; |
| 2592 | 2592 | ||
| 2593 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2593 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2594 | } | 2594 | } |
| 2595 | 2595 | ||
| 2596 | /** | 2596 | /** |
| @@ -2651,7 +2651,7 @@ static irqreturn_t ab8500_charger_mainextchnotok_handler(int irq, void *_di) | |||
| 2651 | 2651 | ||
| 2652 | dev_dbg(di->dev, "Main charger not ok\n"); | 2652 | dev_dbg(di->dev, "Main charger not ok\n"); |
| 2653 | di->flags.mainextchnotok = true; | 2653 | di->flags.mainextchnotok = true; |
| 2654 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 2654 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 2655 | 2655 | ||
| 2656 | /* Schedule a new HW failure check */ | 2656 | /* Schedule a new HW failure check */ |
| 2657 | queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); | 2657 | queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); |
| @@ -2880,11 +2880,11 @@ static irqreturn_t ab8500_charger_chwdexp_handler(int irq, void *_di) | |||
| 2880 | */ | 2880 | */ |
| 2881 | if (di->ac.charger_online) { | 2881 | if (di->ac.charger_online) { |
| 2882 | di->ac.wd_expired = true; | 2882 | di->ac.wd_expired = true; |
| 2883 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 2883 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 2884 | } | 2884 | } |
| 2885 | if (di->usb.charger_online) { | 2885 | if (di->usb.charger_online) { |
| 2886 | di->usb.wd_expired = true; | 2886 | di->usb.wd_expired = true; |
| 2887 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2887 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2888 | } | 2888 | } |
| 2889 | 2889 | ||
| 2890 | return IRQ_HANDLED; | 2890 | return IRQ_HANDLED; |
| @@ -2927,7 +2927,7 @@ static irqreturn_t ab8500_charger_vbusovv_handler(int irq, void *_di) | |||
| 2927 | 2927 | ||
| 2928 | dev_dbg(di->dev, "VBUS overvoltage detected\n"); | 2928 | dev_dbg(di->dev, "VBUS overvoltage detected\n"); |
| 2929 | di->flags.vbus_ovv = true; | 2929 | di->flags.vbus_ovv = true; |
| 2930 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2930 | ab8500_power_supply_changed(di, di->usb_chg.psy); |
| 2931 | 2931 | ||
| 2932 | /* Schedule a new HW failure check */ | 2932 | /* Schedule a new HW failure check */ |
| 2933 | queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); | 2933 | queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); |
| @@ -3428,10 +3428,10 @@ static int ab8500_charger_remove(struct platform_device *pdev) | |||
| 3428 | 3428 | ||
| 3429 | flush_scheduled_work(); | 3429 | flush_scheduled_work(); |
| 3430 | if (di->usb_chg.enabled) | 3430 | if (di->usb_chg.enabled) |
| 3431 | power_supply_unregister(&di->usb_chg.psy); | 3431 | power_supply_unregister(di->usb_chg.psy); |
| 3432 | 3432 | ||
| 3433 | if (di->ac_chg.enabled && !di->ac_chg.external) | 3433 | if (di->ac_chg.enabled && !di->ac_chg.external) |
| 3434 | power_supply_unregister(&di->ac_chg.psy); | 3434 | power_supply_unregister(di->ac_chg.psy); |
| 3435 | 3435 | ||
| 3436 | return 0; | 3436 | return 0; |
| 3437 | } | 3437 | } |
| @@ -3442,10 +3442,27 @@ static char *supply_interface[] = { | |||
| 3442 | "ab8500_btemp", | 3442 | "ab8500_btemp", |
| 3443 | }; | 3443 | }; |
| 3444 | 3444 | ||
| 3445 | static const struct power_supply_desc ab8500_ac_chg_desc = { | ||
| 3446 | .name = "ab8500_ac", | ||
| 3447 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 3448 | .properties = ab8500_charger_ac_props, | ||
| 3449 | .num_properties = ARRAY_SIZE(ab8500_charger_ac_props), | ||
| 3450 | .get_property = ab8500_charger_ac_get_property, | ||
| 3451 | }; | ||
| 3452 | |||
| 3453 | static const struct power_supply_desc ab8500_usb_chg_desc = { | ||
| 3454 | .name = "ab8500_usb", | ||
| 3455 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 3456 | .properties = ab8500_charger_usb_props, | ||
| 3457 | .num_properties = ARRAY_SIZE(ab8500_charger_usb_props), | ||
| 3458 | .get_property = ab8500_charger_usb_get_property, | ||
| 3459 | }; | ||
| 3460 | |||
| 3445 | static int ab8500_charger_probe(struct platform_device *pdev) | 3461 | static int ab8500_charger_probe(struct platform_device *pdev) |
| 3446 | { | 3462 | { |
| 3447 | struct device_node *np = pdev->dev.of_node; | 3463 | struct device_node *np = pdev->dev.of_node; |
| 3448 | struct abx500_bm_data *plat = pdev->dev.platform_data; | 3464 | struct abx500_bm_data *plat = pdev->dev.platform_data; |
| 3465 | struct power_supply_config ac_psy_cfg = {}, usb_psy_cfg = {}; | ||
| 3449 | struct ab8500_charger *di; | 3466 | struct ab8500_charger *di; |
| 3450 | int irq, i, charger_status, ret = 0, ch_stat; | 3467 | int irq, i, charger_status, ret = 0, ch_stat; |
| 3451 | 3468 | ||
| @@ -3483,15 +3500,15 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
| 3483 | di->autopower = false; | 3500 | di->autopower = false; |
| 3484 | di->invalid_charger_detect_state = 0; | 3501 | di->invalid_charger_detect_state = 0; |
| 3485 | 3502 | ||
| 3503 | /* AC and USB supply config */ | ||
| 3504 | ac_psy_cfg.supplied_to = supply_interface; | ||
| 3505 | ac_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); | ||
| 3506 | ac_psy_cfg.drv_data = &di->ac_chg; | ||
| 3507 | usb_psy_cfg.supplied_to = supply_interface; | ||
| 3508 | usb_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); | ||
| 3509 | usb_psy_cfg.drv_data = &di->usb_chg; | ||
| 3510 | |||
| 3486 | /* AC supply */ | 3511 | /* AC supply */ |
| 3487 | /* power_supply base class */ | ||
| 3488 | di->ac_chg.psy.name = "ab8500_ac"; | ||
| 3489 | di->ac_chg.psy.type = POWER_SUPPLY_TYPE_MAINS; | ||
| 3490 | di->ac_chg.psy.properties = ab8500_charger_ac_props; | ||
| 3491 | di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props); | ||
| 3492 | di->ac_chg.psy.get_property = ab8500_charger_ac_get_property; | ||
| 3493 | di->ac_chg.psy.supplied_to = supply_interface; | ||
| 3494 | di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), | ||
| 3495 | /* ux500_charger sub-class */ | 3512 | /* ux500_charger sub-class */ |
| 3496 | di->ac_chg.ops.enable = &ab8500_charger_ac_en; | 3513 | di->ac_chg.ops.enable = &ab8500_charger_ac_en; |
| 3497 | di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable; | 3514 | di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable; |
| @@ -3511,14 +3528,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
| 3511 | &charger_notifier_list, &charger_nb); | 3528 | &charger_notifier_list, &charger_nb); |
| 3512 | 3529 | ||
| 3513 | /* USB supply */ | 3530 | /* USB supply */ |
| 3514 | /* power_supply base class */ | ||
| 3515 | di->usb_chg.psy.name = "ab8500_usb"; | ||
| 3516 | di->usb_chg.psy.type = POWER_SUPPLY_TYPE_USB; | ||
| 3517 | di->usb_chg.psy.properties = ab8500_charger_usb_props; | ||
| 3518 | di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props); | ||
| 3519 | di->usb_chg.psy.get_property = ab8500_charger_usb_get_property; | ||
| 3520 | di->usb_chg.psy.supplied_to = supply_interface; | ||
| 3521 | di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), | ||
| 3522 | /* ux500_charger sub-class */ | 3531 | /* ux500_charger sub-class */ |
| 3523 | di->usb_chg.ops.enable = &ab8500_charger_usb_en; | 3532 | di->usb_chg.ops.enable = &ab8500_charger_usb_en; |
| 3524 | di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; | 3533 | di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; |
| @@ -3616,18 +3625,24 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
| 3616 | 3625 | ||
| 3617 | /* Register AC charger class */ | 3626 | /* Register AC charger class */ |
| 3618 | if (di->ac_chg.enabled) { | 3627 | if (di->ac_chg.enabled) { |
| 3619 | ret = power_supply_register(di->dev, &di->ac_chg.psy); | 3628 | di->ac_chg.psy = power_supply_register(di->dev, |
| 3620 | if (ret) { | 3629 | &ab8500_ac_chg_desc, |
| 3630 | &ac_psy_cfg); | ||
| 3631 | if (IS_ERR(di->ac_chg.psy)) { | ||
| 3621 | dev_err(di->dev, "failed to register AC charger\n"); | 3632 | dev_err(di->dev, "failed to register AC charger\n"); |
| 3633 | ret = PTR_ERR(di->ac_chg.psy); | ||
| 3622 | goto free_charger_wq; | 3634 | goto free_charger_wq; |
| 3623 | } | 3635 | } |
| 3624 | } | 3636 | } |
| 3625 | 3637 | ||
| 3626 | /* Register USB charger class */ | 3638 | /* Register USB charger class */ |
| 3627 | if (di->usb_chg.enabled) { | 3639 | if (di->usb_chg.enabled) { |
| 3628 | ret = power_supply_register(di->dev, &di->usb_chg.psy); | 3640 | di->usb_chg.psy = power_supply_register(di->dev, |
| 3629 | if (ret) { | 3641 | &ab8500_usb_chg_desc, |
| 3642 | &usb_psy_cfg); | ||
| 3643 | if (IS_ERR(di->usb_chg.psy)) { | ||
| 3630 | dev_err(di->dev, "failed to register USB charger\n"); | 3644 | dev_err(di->dev, "failed to register USB charger\n"); |
| 3645 | ret = PTR_ERR(di->usb_chg.psy); | ||
| 3631 | goto free_ac; | 3646 | goto free_ac; |
| 3632 | } | 3647 | } |
| 3633 | } | 3648 | } |
| @@ -3650,8 +3665,8 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
| 3650 | if (charger_status & AC_PW_CONN) { | 3665 | if (charger_status & AC_PW_CONN) { |
| 3651 | di->ac.charger_connected = 1; | 3666 | di->ac.charger_connected = 1; |
| 3652 | di->ac_conn = true; | 3667 | di->ac_conn = true; |
| 3653 | ab8500_power_supply_changed(di, &di->ac_chg.psy); | 3668 | ab8500_power_supply_changed(di, di->ac_chg.psy); |
| 3654 | sysfs_notify(&di->ac_chg.psy.dev->kobj, NULL, "present"); | 3669 | sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present"); |
| 3655 | } | 3670 | } |
| 3656 | 3671 | ||
| 3657 | if (charger_status & USB_PW_CONN) { | 3672 | if (charger_status & USB_PW_CONN) { |
| @@ -3712,10 +3727,10 @@ put_usb_phy: | |||
| 3712 | usb_put_phy(di->usb_phy); | 3727 | usb_put_phy(di->usb_phy); |
| 3713 | free_usb: | 3728 | free_usb: |
| 3714 | if (di->usb_chg.enabled) | 3729 | if (di->usb_chg.enabled) |
| 3715 | power_supply_unregister(&di->usb_chg.psy); | 3730 | power_supply_unregister(di->usb_chg.psy); |
| 3716 | free_ac: | 3731 | free_ac: |
| 3717 | if (di->ac_chg.enabled) | 3732 | if (di->ac_chg.enabled) |
| 3718 | power_supply_unregister(&di->ac_chg.psy); | 3733 | power_supply_unregister(di->ac_chg.psy); |
| 3719 | free_charger_wq: | 3734 | free_charger_wq: |
| 3720 | destroy_workqueue(di->charger_wq); | 3735 | destroy_workqueue(di->charger_wq); |
| 3721 | return ret; | 3736 | return ret; |
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index c908658aa31a..3830dade5d69 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c | |||
| @@ -57,9 +57,6 @@ | |||
| 57 | #define interpolate(x, x1, y1, x2, y2) \ | 57 | #define interpolate(x, x1, y1, x2, y2) \ |
| 58 | ((y1) + ((((y2) - (y1)) * ((x) - (x1))) / ((x2) - (x1)))); | 58 | ((y1) + ((((y2) - (y1)) * ((x) - (x1))) / ((x2) - (x1)))); |
| 59 | 59 | ||
| 60 | #define to_ab8500_fg_device_info(x) container_of((x), \ | ||
| 61 | struct ab8500_fg, fg_psy); | ||
| 62 | |||
| 63 | /** | 60 | /** |
| 64 | * struct ab8500_fg_interrupts - ab8500 fg interupts | 61 | * struct ab8500_fg_interrupts - ab8500 fg interupts |
| 65 | * @name: name of the interrupt | 62 | * @name: name of the interrupt |
| @@ -229,7 +226,7 @@ struct ab8500_fg { | |||
| 229 | struct ab8500 *parent; | 226 | struct ab8500 *parent; |
| 230 | struct ab8500_gpadc *gpadc; | 227 | struct ab8500_gpadc *gpadc; |
| 231 | struct abx500_bm_data *bm; | 228 | struct abx500_bm_data *bm; |
| 232 | struct power_supply fg_psy; | 229 | struct power_supply *fg_psy; |
| 233 | struct workqueue_struct *fg_wq; | 230 | struct workqueue_struct *fg_wq; |
| 234 | struct delayed_work fg_periodic_work; | 231 | struct delayed_work fg_periodic_work; |
| 235 | struct delayed_work fg_low_bat_work; | 232 | struct delayed_work fg_low_bat_work; |
| @@ -622,14 +619,14 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) | |||
| 622 | u8 low, high; | 619 | u8 low, high; |
| 623 | int val; | 620 | int val; |
| 624 | int ret; | 621 | int ret; |
| 625 | int timeout; | 622 | unsigned long timeout; |
| 626 | 623 | ||
| 627 | if (!completion_done(&di->ab8500_fg_complete)) { | 624 | if (!completion_done(&di->ab8500_fg_complete)) { |
| 628 | timeout = wait_for_completion_timeout( | 625 | timeout = wait_for_completion_timeout( |
| 629 | &di->ab8500_fg_complete, | 626 | &di->ab8500_fg_complete, |
| 630 | INS_CURR_TIMEOUT); | 627 | INS_CURR_TIMEOUT); |
| 631 | dev_dbg(di->dev, "Finalize time: %d ms\n", | 628 | dev_dbg(di->dev, "Finalize time: %d ms\n", |
| 632 | ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ); | 629 | jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); |
| 633 | if (!timeout) { | 630 | if (!timeout) { |
| 634 | ret = -ETIME; | 631 | ret = -ETIME; |
| 635 | disable_irq(di->irq); | 632 | disable_irq(di->irq); |
| @@ -716,7 +713,7 @@ fail: | |||
| 716 | int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) | 713 | int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) |
| 717 | { | 714 | { |
| 718 | int ret; | 715 | int ret; |
| 719 | int timeout; | 716 | unsigned long timeout; |
| 720 | int res = 0; | 717 | int res = 0; |
| 721 | 718 | ||
| 722 | ret = ab8500_fg_inst_curr_start(di); | 719 | ret = ab8500_fg_inst_curr_start(di); |
| @@ -731,7 +728,7 @@ int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) | |||
| 731 | &di->ab8500_fg_started, | 728 | &di->ab8500_fg_started, |
| 732 | INS_CURR_TIMEOUT); | 729 | INS_CURR_TIMEOUT); |
| 733 | dev_dbg(di->dev, "Start time: %d ms\n", | 730 | dev_dbg(di->dev, "Start time: %d ms\n", |
| 734 | ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ); | 731 | jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); |
| 735 | if (!timeout) { | 732 | if (!timeout) { |
| 736 | ret = -ETIME; | 733 | ret = -ETIME; |
| 737 | dev_err(di->dev, "completion timed out [%d]\n", | 734 | dev_err(di->dev, "completion timed out [%d]\n", |
| @@ -1391,7 +1388,7 @@ static void ab8500_fg_check_capacity_limits(struct ab8500_fg *di, bool init) | |||
| 1391 | di->bat_cap.prev_percent, | 1388 | di->bat_cap.prev_percent, |
| 1392 | di->bat_cap.cap_scale.scaled_cap); | 1389 | di->bat_cap.cap_scale.scaled_cap); |
| 1393 | } | 1390 | } |
| 1394 | power_supply_changed(&di->fg_psy); | 1391 | power_supply_changed(di->fg_psy); |
| 1395 | if (di->flags.fully_charged && di->flags.force_full) { | 1392 | if (di->flags.fully_charged && di->flags.force_full) { |
| 1396 | dev_dbg(di->dev, "Battery full, notifying.\n"); | 1393 | dev_dbg(di->dev, "Battery full, notifying.\n"); |
| 1397 | di->flags.force_full = false; | 1394 | di->flags.force_full = false; |
| @@ -1850,7 +1847,7 @@ static void ab8500_fg_check_hw_failure_work(struct work_struct *work) | |||
| 1850 | if (!di->flags.bat_ovv) { | 1847 | if (!di->flags.bat_ovv) { |
| 1851 | dev_dbg(di->dev, "Battery OVV\n"); | 1848 | dev_dbg(di->dev, "Battery OVV\n"); |
| 1852 | di->flags.bat_ovv = true; | 1849 | di->flags.bat_ovv = true; |
| 1853 | power_supply_changed(&di->fg_psy); | 1850 | power_supply_changed(di->fg_psy); |
| 1854 | } | 1851 | } |
| 1855 | /* Not yet recovered from ovv, reschedule this test */ | 1852 | /* Not yet recovered from ovv, reschedule this test */ |
| 1856 | queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, | 1853 | queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, |
| @@ -1858,7 +1855,7 @@ static void ab8500_fg_check_hw_failure_work(struct work_struct *work) | |||
| 1858 | } else { | 1855 | } else { |
| 1859 | dev_dbg(di->dev, "Battery recovered from OVV\n"); | 1856 | dev_dbg(di->dev, "Battery recovered from OVV\n"); |
| 1860 | di->flags.bat_ovv = false; | 1857 | di->flags.bat_ovv = false; |
| 1861 | power_supply_changed(&di->fg_psy); | 1858 | power_supply_changed(di->fg_psy); |
| 1862 | } | 1859 | } |
| 1863 | } | 1860 | } |
| 1864 | 1861 | ||
| @@ -2096,9 +2093,7 @@ static int ab8500_fg_get_property(struct power_supply *psy, | |||
| 2096 | enum power_supply_property psp, | 2093 | enum power_supply_property psp, |
| 2097 | union power_supply_propval *val) | 2094 | union power_supply_propval *val) |
| 2098 | { | 2095 | { |
| 2099 | struct ab8500_fg *di; | 2096 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2100 | |||
| 2101 | di = to_ab8500_fg_device_info(psy); | ||
| 2102 | 2097 | ||
| 2103 | /* | 2098 | /* |
| 2104 | * If battery is identified as unknown and charging of unknown | 2099 | * If battery is identified as unknown and charging of unknown |
| @@ -2181,14 +2176,14 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) | |||
| 2181 | 2176 | ||
| 2182 | psy = (struct power_supply *)data; | 2177 | psy = (struct power_supply *)data; |
| 2183 | ext = dev_get_drvdata(dev); | 2178 | ext = dev_get_drvdata(dev); |
| 2184 | di = to_ab8500_fg_device_info(psy); | 2179 | di = power_supply_get_drvdata(psy); |
| 2185 | 2180 | ||
| 2186 | /* | 2181 | /* |
| 2187 | * For all psy where the name of your driver | 2182 | * For all psy where the name of your driver |
| 2188 | * appears in any supplied_to | 2183 | * appears in any supplied_to |
| 2189 | */ | 2184 | */ |
| 2190 | for (i = 0; i < ext->num_supplicants; i++) { | 2185 | for (i = 0; i < ext->num_supplicants; i++) { |
| 2191 | if (!strcmp(ext->supplied_to[i], psy->name)) | 2186 | if (!strcmp(ext->supplied_to[i], psy->desc->name)) |
| 2192 | psy_found = true; | 2187 | psy_found = true; |
| 2193 | } | 2188 | } |
| 2194 | 2189 | ||
| @@ -2196,16 +2191,16 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) | |||
| 2196 | return 0; | 2191 | return 0; |
| 2197 | 2192 | ||
| 2198 | /* Go through all properties for the psy */ | 2193 | /* Go through all properties for the psy */ |
| 2199 | for (j = 0; j < ext->num_properties; j++) { | 2194 | for (j = 0; j < ext->desc->num_properties; j++) { |
| 2200 | enum power_supply_property prop; | 2195 | enum power_supply_property prop; |
| 2201 | prop = ext->properties[j]; | 2196 | prop = ext->desc->properties[j]; |
| 2202 | 2197 | ||
| 2203 | if (ext->get_property(ext, prop, &ret)) | 2198 | if (power_supply_get_property(ext, prop, &ret)) |
| 2204 | continue; | 2199 | continue; |
| 2205 | 2200 | ||
| 2206 | switch (prop) { | 2201 | switch (prop) { |
| 2207 | case POWER_SUPPLY_PROP_STATUS: | 2202 | case POWER_SUPPLY_PROP_STATUS: |
| 2208 | switch (ext->type) { | 2203 | switch (ext->desc->type) { |
| 2209 | case POWER_SUPPLY_TYPE_BATTERY: | 2204 | case POWER_SUPPLY_TYPE_BATTERY: |
| 2210 | switch (ret.intval) { | 2205 | switch (ret.intval) { |
| 2211 | case POWER_SUPPLY_STATUS_UNKNOWN: | 2206 | case POWER_SUPPLY_STATUS_UNKNOWN: |
| @@ -2244,7 +2239,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) | |||
| 2244 | }; | 2239 | }; |
| 2245 | break; | 2240 | break; |
| 2246 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 2241 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| 2247 | switch (ext->type) { | 2242 | switch (ext->desc->type) { |
| 2248 | case POWER_SUPPLY_TYPE_BATTERY: | 2243 | case POWER_SUPPLY_TYPE_BATTERY: |
| 2249 | if (!di->flags.batt_id_received && | 2244 | if (!di->flags.batt_id_received && |
| 2250 | di->bm->batt_id != BATTERY_UNKNOWN) { | 2245 | di->bm->batt_id != BATTERY_UNKNOWN) { |
| @@ -2274,7 +2269,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) | |||
| 2274 | } | 2269 | } |
| 2275 | break; | 2270 | break; |
| 2276 | case POWER_SUPPLY_PROP_TEMP: | 2271 | case POWER_SUPPLY_PROP_TEMP: |
| 2277 | switch (ext->type) { | 2272 | switch (ext->desc->type) { |
| 2278 | case POWER_SUPPLY_TYPE_BATTERY: | 2273 | case POWER_SUPPLY_TYPE_BATTERY: |
| 2279 | if (di->flags.batt_id_received) | 2274 | if (di->flags.batt_id_received) |
| 2280 | di->bat_temp = ret.intval; | 2275 | di->bat_temp = ret.intval; |
| @@ -2399,10 +2394,10 @@ out: | |||
| 2399 | */ | 2394 | */ |
| 2400 | static void ab8500_fg_external_power_changed(struct power_supply *psy) | 2395 | static void ab8500_fg_external_power_changed(struct power_supply *psy) |
| 2401 | { | 2396 | { |
| 2402 | struct ab8500_fg *di = to_ab8500_fg_device_info(psy); | 2397 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2403 | 2398 | ||
| 2404 | class_for_each_device(power_supply_class, NULL, | 2399 | class_for_each_device(power_supply_class, NULL, |
| 2405 | &di->fg_psy, ab8500_fg_get_ext_psy_data); | 2400 | di->fg_psy, ab8500_fg_get_ext_psy_data); |
| 2406 | } | 2401 | } |
| 2407 | 2402 | ||
| 2408 | /** | 2403 | /** |
| @@ -2580,9 +2575,7 @@ static ssize_t ab8505_powercut_flagtime_read(struct device *dev, | |||
| 2580 | int ret; | 2575 | int ret; |
| 2581 | u8 reg_value; | 2576 | u8 reg_value; |
| 2582 | struct power_supply *psy = dev_get_drvdata(dev); | 2577 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2583 | struct ab8500_fg *di; | 2578 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2584 | |||
| 2585 | di = to_ab8500_fg_device_info(psy); | ||
| 2586 | 2579 | ||
| 2587 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2580 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2588 | AB8505_RTC_PCUT_FLAG_TIME_REG, ®_value); | 2581 | AB8505_RTC_PCUT_FLAG_TIME_REG, ®_value); |
| @@ -2605,9 +2598,7 @@ static ssize_t ab8505_powercut_flagtime_write(struct device *dev, | |||
| 2605 | int ret; | 2598 | int ret; |
| 2606 | long unsigned reg_value; | 2599 | long unsigned reg_value; |
| 2607 | struct power_supply *psy = dev_get_drvdata(dev); | 2600 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2608 | struct ab8500_fg *di; | 2601 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2609 | |||
| 2610 | di = to_ab8500_fg_device_info(psy); | ||
| 2611 | 2602 | ||
| 2612 | reg_value = simple_strtoul(buf, NULL, 10); | 2603 | reg_value = simple_strtoul(buf, NULL, 10); |
| 2613 | 2604 | ||
| @@ -2633,9 +2624,7 @@ static ssize_t ab8505_powercut_maxtime_read(struct device *dev, | |||
| 2633 | int ret; | 2624 | int ret; |
| 2634 | u8 reg_value; | 2625 | u8 reg_value; |
| 2635 | struct power_supply *psy = dev_get_drvdata(dev); | 2626 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2636 | struct ab8500_fg *di; | 2627 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2637 | |||
| 2638 | di = to_ab8500_fg_device_info(psy); | ||
| 2639 | 2628 | ||
| 2640 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2629 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2641 | AB8505_RTC_PCUT_MAX_TIME_REG, ®_value); | 2630 | AB8505_RTC_PCUT_MAX_TIME_REG, ®_value); |
| @@ -2659,9 +2648,7 @@ static ssize_t ab8505_powercut_maxtime_write(struct device *dev, | |||
| 2659 | int ret; | 2648 | int ret; |
| 2660 | int reg_value; | 2649 | int reg_value; |
| 2661 | struct power_supply *psy = dev_get_drvdata(dev); | 2650 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2662 | struct ab8500_fg *di; | 2651 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2663 | |||
| 2664 | di = to_ab8500_fg_device_info(psy); | ||
| 2665 | 2652 | ||
| 2666 | reg_value = simple_strtoul(buf, NULL, 10); | 2653 | reg_value = simple_strtoul(buf, NULL, 10); |
| 2667 | if (reg_value > 0x7F) { | 2654 | if (reg_value > 0x7F) { |
| @@ -2686,9 +2673,7 @@ static ssize_t ab8505_powercut_restart_read(struct device *dev, | |||
| 2686 | int ret; | 2673 | int ret; |
| 2687 | u8 reg_value; | 2674 | u8 reg_value; |
| 2688 | struct power_supply *psy = dev_get_drvdata(dev); | 2675 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2689 | struct ab8500_fg *di; | 2676 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2690 | |||
| 2691 | di = to_ab8500_fg_device_info(psy); | ||
| 2692 | 2677 | ||
| 2693 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2678 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2694 | AB8505_RTC_PCUT_RESTART_REG, ®_value); | 2679 | AB8505_RTC_PCUT_RESTART_REG, ®_value); |
| @@ -2711,9 +2696,7 @@ static ssize_t ab8505_powercut_restart_write(struct device *dev, | |||
| 2711 | int ret; | 2696 | int ret; |
| 2712 | int reg_value; | 2697 | int reg_value; |
| 2713 | struct power_supply *psy = dev_get_drvdata(dev); | 2698 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2714 | struct ab8500_fg *di; | 2699 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2715 | |||
| 2716 | di = to_ab8500_fg_device_info(psy); | ||
| 2717 | 2700 | ||
| 2718 | reg_value = simple_strtoul(buf, NULL, 10); | 2701 | reg_value = simple_strtoul(buf, NULL, 10); |
| 2719 | if (reg_value > 0xF) { | 2702 | if (reg_value > 0xF) { |
| @@ -2739,9 +2722,7 @@ static ssize_t ab8505_powercut_timer_read(struct device *dev, | |||
| 2739 | int ret; | 2722 | int ret; |
| 2740 | u8 reg_value; | 2723 | u8 reg_value; |
| 2741 | struct power_supply *psy = dev_get_drvdata(dev); | 2724 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2742 | struct ab8500_fg *di; | 2725 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2743 | |||
| 2744 | di = to_ab8500_fg_device_info(psy); | ||
| 2745 | 2726 | ||
| 2746 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2727 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2747 | AB8505_RTC_PCUT_TIME_REG, ®_value); | 2728 | AB8505_RTC_PCUT_TIME_REG, ®_value); |
| @@ -2764,9 +2745,7 @@ static ssize_t ab8505_powercut_restart_counter_read(struct device *dev, | |||
| 2764 | int ret; | 2745 | int ret; |
| 2765 | u8 reg_value; | 2746 | u8 reg_value; |
| 2766 | struct power_supply *psy = dev_get_drvdata(dev); | 2747 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2767 | struct ab8500_fg *di; | 2748 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2768 | |||
| 2769 | di = to_ab8500_fg_device_info(psy); | ||
| 2770 | 2749 | ||
| 2771 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2750 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2772 | AB8505_RTC_PCUT_RESTART_REG, ®_value); | 2751 | AB8505_RTC_PCUT_RESTART_REG, ®_value); |
| @@ -2789,9 +2768,7 @@ static ssize_t ab8505_powercut_read(struct device *dev, | |||
| 2789 | int ret; | 2768 | int ret; |
| 2790 | u8 reg_value; | 2769 | u8 reg_value; |
| 2791 | struct power_supply *psy = dev_get_drvdata(dev); | 2770 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2792 | struct ab8500_fg *di; | 2771 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2793 | |||
| 2794 | di = to_ab8500_fg_device_info(psy); | ||
| 2795 | 2772 | ||
| 2796 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2773 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2797 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); | 2774 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); |
| @@ -2812,9 +2789,7 @@ static ssize_t ab8505_powercut_write(struct device *dev, | |||
| 2812 | int ret; | 2789 | int ret; |
| 2813 | int reg_value; | 2790 | int reg_value; |
| 2814 | struct power_supply *psy = dev_get_drvdata(dev); | 2791 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2815 | struct ab8500_fg *di; | 2792 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2816 | |||
| 2817 | di = to_ab8500_fg_device_info(psy); | ||
| 2818 | 2793 | ||
| 2819 | reg_value = simple_strtoul(buf, NULL, 10); | 2794 | reg_value = simple_strtoul(buf, NULL, 10); |
| 2820 | if (reg_value > 0x1) { | 2795 | if (reg_value > 0x1) { |
| @@ -2840,9 +2815,7 @@ static ssize_t ab8505_powercut_flag_read(struct device *dev, | |||
| 2840 | int ret; | 2815 | int ret; |
| 2841 | u8 reg_value; | 2816 | u8 reg_value; |
| 2842 | struct power_supply *psy = dev_get_drvdata(dev); | 2817 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2843 | struct ab8500_fg *di; | 2818 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2844 | |||
| 2845 | di = to_ab8500_fg_device_info(psy); | ||
| 2846 | 2819 | ||
| 2847 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2820 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2848 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); | 2821 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); |
| @@ -2865,9 +2838,7 @@ static ssize_t ab8505_powercut_debounce_read(struct device *dev, | |||
| 2865 | int ret; | 2838 | int ret; |
| 2866 | u8 reg_value; | 2839 | u8 reg_value; |
| 2867 | struct power_supply *psy = dev_get_drvdata(dev); | 2840 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2868 | struct ab8500_fg *di; | 2841 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2869 | |||
| 2870 | di = to_ab8500_fg_device_info(psy); | ||
| 2871 | 2842 | ||
| 2872 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2843 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2873 | AB8505_RTC_PCUT_DEBOUNCE_REG, ®_value); | 2844 | AB8505_RTC_PCUT_DEBOUNCE_REG, ®_value); |
| @@ -2890,9 +2861,7 @@ static ssize_t ab8505_powercut_debounce_write(struct device *dev, | |||
| 2890 | int ret; | 2861 | int ret; |
| 2891 | int reg_value; | 2862 | int reg_value; |
| 2892 | struct power_supply *psy = dev_get_drvdata(dev); | 2863 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2893 | struct ab8500_fg *di; | 2864 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2894 | |||
| 2895 | di = to_ab8500_fg_device_info(psy); | ||
| 2896 | 2865 | ||
| 2897 | reg_value = simple_strtoul(buf, NULL, 10); | 2866 | reg_value = simple_strtoul(buf, NULL, 10); |
| 2898 | if (reg_value > 0x7) { | 2867 | if (reg_value > 0x7) { |
| @@ -2917,9 +2886,7 @@ static ssize_t ab8505_powercut_enable_status_read(struct device *dev, | |||
| 2917 | int ret; | 2886 | int ret; |
| 2918 | u8 reg_value; | 2887 | u8 reg_value; |
| 2919 | struct power_supply *psy = dev_get_drvdata(dev); | 2888 | struct power_supply *psy = dev_get_drvdata(dev); |
| 2920 | struct ab8500_fg *di; | 2889 | struct ab8500_fg *di = power_supply_get_drvdata(psy); |
| 2921 | |||
| 2922 | di = to_ab8500_fg_device_info(psy); | ||
| 2923 | 2890 | ||
| 2924 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, | 2891 | ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, |
| 2925 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); | 2892 | AB8505_RTC_PCUT_CTL_STATUS_REG, ®_value); |
| @@ -2954,44 +2921,38 @@ static struct device_attribute ab8505_fg_sysfs_psy_attrs[] = { | |||
| 2954 | ab8505_powercut_enable_status_read, NULL), | 2921 | ab8505_powercut_enable_status_read, NULL), |
| 2955 | }; | 2922 | }; |
| 2956 | 2923 | ||
| 2957 | static int ab8500_fg_sysfs_psy_create_attrs(struct device *dev) | 2924 | static int ab8500_fg_sysfs_psy_create_attrs(struct ab8500_fg *di) |
| 2958 | { | 2925 | { |
| 2959 | unsigned int i; | 2926 | unsigned int i; |
| 2960 | struct power_supply *psy = dev_get_drvdata(dev); | ||
| 2961 | struct ab8500_fg *di; | ||
| 2962 | |||
| 2963 | di = to_ab8500_fg_device_info(psy); | ||
| 2964 | 2927 | ||
| 2965 | if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && | 2928 | if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && |
| 2966 | abx500_get_chip_id(dev->parent) >= AB8500_CUT2P0) | 2929 | abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) |
| 2967 | || is_ab8540(di->parent)) { | 2930 | || is_ab8540(di->parent)) { |
| 2968 | for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) | 2931 | for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) |
| 2969 | if (device_create_file(dev, | 2932 | if (device_create_file(&di->fg_psy->dev, |
| 2970 | &ab8505_fg_sysfs_psy_attrs[i])) | 2933 | &ab8505_fg_sysfs_psy_attrs[i])) |
| 2971 | goto sysfs_psy_create_attrs_failed_ab8505; | 2934 | goto sysfs_psy_create_attrs_failed_ab8505; |
| 2972 | } | 2935 | } |
| 2973 | return 0; | 2936 | return 0; |
| 2974 | sysfs_psy_create_attrs_failed_ab8505: | 2937 | sysfs_psy_create_attrs_failed_ab8505: |
| 2975 | dev_err(dev, "Failed creating sysfs psy attrs for ab8505.\n"); | 2938 | dev_err(&di->fg_psy->dev, "Failed creating sysfs psy attrs for ab8505.\n"); |
| 2976 | while (i--) | 2939 | while (i--) |
| 2977 | device_remove_file(dev, &ab8505_fg_sysfs_psy_attrs[i]); | 2940 | device_remove_file(&di->fg_psy->dev, |
| 2941 | &ab8505_fg_sysfs_psy_attrs[i]); | ||
| 2978 | 2942 | ||
| 2979 | return -EIO; | 2943 | return -EIO; |
| 2980 | } | 2944 | } |
| 2981 | 2945 | ||
| 2982 | static void ab8500_fg_sysfs_psy_remove_attrs(struct device *dev) | 2946 | static void ab8500_fg_sysfs_psy_remove_attrs(struct ab8500_fg *di) |
| 2983 | { | 2947 | { |
| 2984 | unsigned int i; | 2948 | unsigned int i; |
| 2985 | struct power_supply *psy = dev_get_drvdata(dev); | ||
| 2986 | struct ab8500_fg *di; | ||
| 2987 | |||
| 2988 | di = to_ab8500_fg_device_info(psy); | ||
| 2989 | 2949 | ||
| 2990 | if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && | 2950 | if (((is_ab8505(di->parent) || is_ab9540(di->parent)) && |
| 2991 | abx500_get_chip_id(dev->parent) >= AB8500_CUT2P0) | 2951 | abx500_get_chip_id(di->dev) >= AB8500_CUT2P0) |
| 2992 | || is_ab8540(di->parent)) { | 2952 | || is_ab8540(di->parent)) { |
| 2993 | for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) | 2953 | for (i = 0; i < ARRAY_SIZE(ab8505_fg_sysfs_psy_attrs); i++) |
| 2994 | (void)device_remove_file(dev, &ab8505_fg_sysfs_psy_attrs[i]); | 2954 | (void)device_remove_file(&di->fg_psy->dev, |
| 2955 | &ab8505_fg_sysfs_psy_attrs[i]); | ||
| 2995 | } | 2956 | } |
| 2996 | } | 2957 | } |
| 2997 | 2958 | ||
| @@ -3056,17 +3017,20 @@ static int ab8500_fg_remove(struct platform_device *pdev) | |||
| 3056 | ab8500_fg_sysfs_exit(di); | 3017 | ab8500_fg_sysfs_exit(di); |
| 3057 | 3018 | ||
| 3058 | flush_scheduled_work(); | 3019 | flush_scheduled_work(); |
| 3059 | ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev); | 3020 | ab8500_fg_sysfs_psy_remove_attrs(di); |
| 3060 | power_supply_unregister(&di->fg_psy); | 3021 | power_supply_unregister(di->fg_psy); |
| 3061 | return ret; | 3022 | return ret; |
| 3062 | } | 3023 | } |
| 3063 | 3024 | ||
| 3064 | /* ab8500 fg driver interrupts and their respective isr */ | 3025 | /* ab8500 fg driver interrupts and their respective isr */ |
| 3065 | static struct ab8500_fg_interrupts ab8500_fg_irq[] = { | 3026 | static struct ab8500_fg_interrupts ab8500_fg_irq_th[] = { |
| 3066 | {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, | 3027 | {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, |
| 3067 | {"BATT_OVV", ab8500_fg_batt_ovv_handler}, | 3028 | {"BATT_OVV", ab8500_fg_batt_ovv_handler}, |
| 3068 | {"LOW_BAT_F", ab8500_fg_lowbatf_handler}, | 3029 | {"LOW_BAT_F", ab8500_fg_lowbatf_handler}, |
| 3069 | {"CC_INT_CALIB", ab8500_fg_cc_int_calib_handler}, | 3030 | {"CC_INT_CALIB", ab8500_fg_cc_int_calib_handler}, |
| 3031 | }; | ||
| 3032 | |||
| 3033 | static struct ab8500_fg_interrupts ab8500_fg_irq_bh[] = { | ||
| 3070 | {"CCEOC", ab8500_fg_cc_data_end_handler}, | 3034 | {"CCEOC", ab8500_fg_cc_data_end_handler}, |
| 3071 | }; | 3035 | }; |
| 3072 | 3036 | ||
| @@ -3075,10 +3039,20 @@ static char *supply_interface[] = { | |||
| 3075 | "ab8500_usb", | 3039 | "ab8500_usb", |
| 3076 | }; | 3040 | }; |
| 3077 | 3041 | ||
| 3042 | static const struct power_supply_desc ab8500_fg_desc = { | ||
| 3043 | .name = "ab8500_fg", | ||
| 3044 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 3045 | .properties = ab8500_fg_props, | ||
| 3046 | .num_properties = ARRAY_SIZE(ab8500_fg_props), | ||
| 3047 | .get_property = ab8500_fg_get_property, | ||
| 3048 | .external_power_changed = ab8500_fg_external_power_changed, | ||
| 3049 | }; | ||
| 3050 | |||
| 3078 | static int ab8500_fg_probe(struct platform_device *pdev) | 3051 | static int ab8500_fg_probe(struct platform_device *pdev) |
| 3079 | { | 3052 | { |
| 3080 | struct device_node *np = pdev->dev.of_node; | 3053 | struct device_node *np = pdev->dev.of_node; |
| 3081 | struct abx500_bm_data *plat = pdev->dev.platform_data; | 3054 | struct abx500_bm_data *plat = pdev->dev.platform_data; |
| 3055 | struct power_supply_config psy_cfg = {}; | ||
| 3082 | struct ab8500_fg *di; | 3056 | struct ab8500_fg *di; |
| 3083 | int i, irq; | 3057 | int i, irq; |
| 3084 | int ret = 0; | 3058 | int ret = 0; |
| @@ -3110,14 +3084,9 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
| 3110 | di->parent = dev_get_drvdata(pdev->dev.parent); | 3084 | di->parent = dev_get_drvdata(pdev->dev.parent); |
| 3111 | di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); | 3085 | di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); |
| 3112 | 3086 | ||
| 3113 | di->fg_psy.name = "ab8500_fg"; | 3087 | psy_cfg.supplied_to = supply_interface; |
| 3114 | di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY; | 3088 | psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); |
| 3115 | di->fg_psy.properties = ab8500_fg_props; | 3089 | psy_cfg.drv_data = di; |
| 3116 | di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props); | ||
| 3117 | di->fg_psy.get_property = ab8500_fg_get_property; | ||
| 3118 | di->fg_psy.supplied_to = supply_interface; | ||
| 3119 | di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface), | ||
| 3120 | di->fg_psy.external_power_changed = ab8500_fg_external_power_changed; | ||
| 3121 | 3090 | ||
| 3122 | di->bat_cap.max_mah_design = MILLI_TO_MICRO * | 3091 | di->bat_cap.max_mah_design = MILLI_TO_MICRO * |
| 3123 | di->bm->bat_type[di->bm->batt_id].charge_full_design; | 3092 | di->bm->bat_type[di->bm->batt_id].charge_full_design; |
| @@ -3178,9 +3147,10 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
| 3178 | di->flags.batt_id_received = false; | 3147 | di->flags.batt_id_received = false; |
| 3179 | 3148 | ||
| 3180 | /* Register FG power supply class */ | 3149 | /* Register FG power supply class */ |
| 3181 | ret = power_supply_register(di->dev, &di->fg_psy); | 3150 | di->fg_psy = power_supply_register(di->dev, &ab8500_fg_desc, &psy_cfg); |
| 3182 | if (ret) { | 3151 | if (IS_ERR(di->fg_psy)) { |
| 3183 | dev_err(di->dev, "failed to register FG psy\n"); | 3152 | dev_err(di->dev, "failed to register FG psy\n"); |
| 3153 | ret = PTR_ERR(di->fg_psy); | ||
| 3184 | goto free_inst_curr_wq; | 3154 | goto free_inst_curr_wq; |
| 3185 | } | 3155 | } |
| 3186 | 3156 | ||
| @@ -3194,21 +3164,36 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
| 3194 | init_completion(&di->ab8500_fg_started); | 3164 | init_completion(&di->ab8500_fg_started); |
| 3195 | init_completion(&di->ab8500_fg_complete); | 3165 | init_completion(&di->ab8500_fg_complete); |
| 3196 | 3166 | ||
| 3197 | /* Register interrupts */ | 3167 | /* Register primary interrupt handlers */ |
| 3198 | for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) { | 3168 | for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) { |
| 3199 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); | 3169 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name); |
| 3200 | ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr, | 3170 | ret = request_irq(irq, ab8500_fg_irq_th[i].isr, |
| 3201 | IRQF_SHARED | IRQF_NO_SUSPEND, | 3171 | IRQF_SHARED | IRQF_NO_SUSPEND, |
| 3202 | ab8500_fg_irq[i].name, di); | 3172 | ab8500_fg_irq_th[i].name, di); |
| 3203 | 3173 | ||
| 3204 | if (ret != 0) { | 3174 | if (ret != 0) { |
| 3205 | dev_err(di->dev, "failed to request %s IRQ %d: %d\n" | 3175 | dev_err(di->dev, "failed to request %s IRQ %d: %d\n", |
| 3206 | , ab8500_fg_irq[i].name, irq, ret); | 3176 | ab8500_fg_irq_th[i].name, irq, ret); |
| 3207 | goto free_irq; | 3177 | goto free_irq; |
| 3208 | } | 3178 | } |
| 3209 | dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", | 3179 | dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", |
| 3210 | ab8500_fg_irq[i].name, irq, ret); | 3180 | ab8500_fg_irq_th[i].name, irq, ret); |
| 3211 | } | 3181 | } |
| 3182 | |||
| 3183 | /* Register threaded interrupt handler */ | ||
| 3184 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name); | ||
| 3185 | ret = request_threaded_irq(irq, NULL, ab8500_fg_irq_bh[0].isr, | ||
| 3186 | IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, | ||
| 3187 | ab8500_fg_irq_bh[0].name, di); | ||
| 3188 | |||
| 3189 | if (ret != 0) { | ||
| 3190 | dev_err(di->dev, "failed to request %s IRQ %d: %d\n", | ||
| 3191 | ab8500_fg_irq_bh[0].name, irq, ret); | ||
| 3192 | goto free_irq; | ||
| 3193 | } | ||
| 3194 | dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", | ||
| 3195 | ab8500_fg_irq_bh[0].name, irq, ret); | ||
| 3196 | |||
| 3212 | di->irq = platform_get_irq_byname(pdev, "CCEOC"); | 3197 | di->irq = platform_get_irq_byname(pdev, "CCEOC"); |
| 3213 | disable_irq(di->irq); | 3198 | disable_irq(di->irq); |
| 3214 | di->nbr_cceoc_irq_cnt = 0; | 3199 | di->nbr_cceoc_irq_cnt = 0; |
| @@ -3221,7 +3206,7 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
| 3221 | goto free_irq; | 3206 | goto free_irq; |
| 3222 | } | 3207 | } |
| 3223 | 3208 | ||
| 3224 | ret = ab8500_fg_sysfs_psy_create_attrs(di->fg_psy.dev); | 3209 | ret = ab8500_fg_sysfs_psy_create_attrs(di); |
| 3225 | if (ret) { | 3210 | if (ret) { |
| 3226 | dev_err(di->dev, "failed to create FG psy\n"); | 3211 | dev_err(di->dev, "failed to create FG psy\n"); |
| 3227 | ab8500_fg_sysfs_exit(di); | 3212 | ab8500_fg_sysfs_exit(di); |
| @@ -3243,13 +3228,15 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
| 3243 | return ret; | 3228 | return ret; |
| 3244 | 3229 | ||
| 3245 | free_irq: | 3230 | free_irq: |
| 3246 | power_supply_unregister(&di->fg_psy); | 3231 | power_supply_unregister(di->fg_psy); |
| 3247 | 3232 | ||
| 3248 | /* We also have to free all successfully registered irqs */ | 3233 | /* We also have to free all registered irqs */ |
| 3249 | for (i = i - 1; i >= 0; i--) { | 3234 | for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq_th); i++) { |
| 3250 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); | 3235 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq_th[i].name); |
| 3251 | free_irq(irq, di); | 3236 | free_irq(irq, di); |
| 3252 | } | 3237 | } |
| 3238 | irq = platform_get_irq_byname(pdev, ab8500_fg_irq_bh[0].name); | ||
| 3239 | free_irq(irq, di); | ||
| 3253 | free_inst_curr_wq: | 3240 | free_inst_curr_wq: |
| 3254 | destroy_workqueue(di->fg_wq); | 3241 | destroy_workqueue(di->fg_wq); |
| 3255 | return ret; | 3242 | return ret; |
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index ab54b8dea670..541f702e0451 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c | |||
| @@ -50,9 +50,6 @@ | |||
| 50 | #define CHARGALG_CURR_STEP_LOW 0 | 50 | #define CHARGALG_CURR_STEP_LOW 0 |
| 51 | #define CHARGALG_CURR_STEP_HIGH 100 | 51 | #define CHARGALG_CURR_STEP_HIGH 100 |
| 52 | 52 | ||
| 53 | #define to_abx500_chargalg_device_info(x) container_of((x), \ | ||
| 54 | struct abx500_chargalg, chargalg_psy); | ||
| 55 | |||
| 56 | enum abx500_chargers { | 53 | enum abx500_chargers { |
| 57 | NO_CHG, | 54 | NO_CHG, |
| 58 | AC_CHG, | 55 | AC_CHG, |
| @@ -256,7 +253,7 @@ struct abx500_chargalg { | |||
| 256 | struct ab8500 *parent; | 253 | struct ab8500 *parent; |
| 257 | struct abx500_chargalg_current_step_status curr_status; | 254 | struct abx500_chargalg_current_step_status curr_status; |
| 258 | struct abx500_bm_data *bm; | 255 | struct abx500_bm_data *bm; |
| 259 | struct power_supply chargalg_psy; | 256 | struct power_supply *chargalg_psy; |
| 260 | struct ux500_charger *ac_chg; | 257 | struct ux500_charger *ac_chg; |
| 261 | struct ux500_charger *usb_chg; | 258 | struct ux500_charger *usb_chg; |
| 262 | struct abx500_chargalg_events events; | 259 | struct abx500_chargalg_events events; |
| @@ -695,7 +692,7 @@ static void abx500_chargalg_stop_charging(struct abx500_chargalg *di) | |||
| 695 | di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 692 | di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| 696 | di->maintenance_chg = false; | 693 | di->maintenance_chg = false; |
| 697 | cancel_delayed_work(&di->chargalg_wd_work); | 694 | cancel_delayed_work(&di->chargalg_wd_work); |
| 698 | power_supply_changed(&di->chargalg_psy); | 695 | power_supply_changed(di->chargalg_psy); |
| 699 | } | 696 | } |
| 700 | 697 | ||
| 701 | /** | 698 | /** |
| @@ -715,7 +712,7 @@ static void abx500_chargalg_hold_charging(struct abx500_chargalg *di) | |||
| 715 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; | 712 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; |
| 716 | di->maintenance_chg = false; | 713 | di->maintenance_chg = false; |
| 717 | cancel_delayed_work(&di->chargalg_wd_work); | 714 | cancel_delayed_work(&di->chargalg_wd_work); |
| 718 | power_supply_changed(&di->chargalg_psy); | 715 | power_supply_changed(di->chargalg_psy); |
| 719 | } | 716 | } |
| 720 | 717 | ||
| 721 | /** | 718 | /** |
| @@ -842,7 +839,7 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di) | |||
| 842 | di->charge_status = POWER_SUPPLY_STATUS_FULL; | 839 | di->charge_status = POWER_SUPPLY_STATUS_FULL; |
| 843 | di->maintenance_chg = true; | 840 | di->maintenance_chg = true; |
| 844 | dev_dbg(di->dev, "EOC reached!\n"); | 841 | dev_dbg(di->dev, "EOC reached!\n"); |
| 845 | power_supply_changed(&di->chargalg_psy); | 842 | power_supply_changed(di->chargalg_psy); |
| 846 | } else { | 843 | } else { |
| 847 | dev_dbg(di->dev, | 844 | dev_dbg(di->dev, |
| 848 | " EOC limit reached for the %d" | 845 | " EOC limit reached for the %d" |
| @@ -987,10 +984,10 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 987 | 984 | ||
| 988 | psy = (struct power_supply *)data; | 985 | psy = (struct power_supply *)data; |
| 989 | ext = dev_get_drvdata(dev); | 986 | ext = dev_get_drvdata(dev); |
| 990 | di = to_abx500_chargalg_device_info(psy); | 987 | di = power_supply_get_drvdata(psy); |
| 991 | /* For all psy where the driver name appears in any supplied_to */ | 988 | /* For all psy where the driver name appears in any supplied_to */ |
| 992 | for (i = 0; i < ext->num_supplicants; i++) { | 989 | for (i = 0; i < ext->num_supplicants; i++) { |
| 993 | if (!strcmp(ext->supplied_to[i], psy->name)) | 990 | if (!strcmp(ext->supplied_to[i], psy->desc->name)) |
| 994 | psy_found = true; | 991 | psy_found = true; |
| 995 | } | 992 | } |
| 996 | if (!psy_found) | 993 | if (!psy_found) |
| @@ -1001,29 +998,31 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1001 | * property because of handling that sysfs entry on its own, this is | 998 | * property because of handling that sysfs entry on its own, this is |
| 1002 | * the place to get the battery capacity. | 999 | * the place to get the battery capacity. |
| 1003 | */ | 1000 | */ |
| 1004 | if (!ext->get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) { | 1001 | if (!power_supply_get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) { |
| 1005 | di->batt_data.percent = ret.intval; | 1002 | di->batt_data.percent = ret.intval; |
| 1006 | capacity_updated = true; | 1003 | capacity_updated = true; |
| 1007 | } | 1004 | } |
| 1008 | 1005 | ||
| 1009 | /* Go through all properties for the psy */ | 1006 | /* Go through all properties for the psy */ |
| 1010 | for (j = 0; j < ext->num_properties; j++) { | 1007 | for (j = 0; j < ext->desc->num_properties; j++) { |
| 1011 | enum power_supply_property prop; | 1008 | enum power_supply_property prop; |
| 1012 | prop = ext->properties[j]; | 1009 | prop = ext->desc->properties[j]; |
| 1013 | 1010 | ||
| 1014 | /* Initialize chargers if not already done */ | 1011 | /* |
| 1012 | * Initialize chargers if not already done. | ||
| 1013 | * The ab8500_charger*/ | ||
| 1015 | if (!di->ac_chg && | 1014 | if (!di->ac_chg && |
| 1016 | ext->type == POWER_SUPPLY_TYPE_MAINS) | 1015 | ext->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 1017 | di->ac_chg = psy_to_ux500_charger(ext); | 1016 | di->ac_chg = psy_to_ux500_charger(ext); |
| 1018 | else if (!di->usb_chg && | 1017 | else if (!di->usb_chg && |
| 1019 | ext->type == POWER_SUPPLY_TYPE_USB) | 1018 | ext->desc->type == POWER_SUPPLY_TYPE_USB) |
| 1020 | di->usb_chg = psy_to_ux500_charger(ext); | 1019 | di->usb_chg = psy_to_ux500_charger(ext); |
| 1021 | 1020 | ||
| 1022 | if (ext->get_property(ext, prop, &ret)) | 1021 | if (power_supply_get_property(ext, prop, &ret)) |
| 1023 | continue; | 1022 | continue; |
| 1024 | switch (prop) { | 1023 | switch (prop) { |
| 1025 | case POWER_SUPPLY_PROP_PRESENT: | 1024 | case POWER_SUPPLY_PROP_PRESENT: |
| 1026 | switch (ext->type) { | 1025 | switch (ext->desc->type) { |
| 1027 | case POWER_SUPPLY_TYPE_BATTERY: | 1026 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1028 | /* Battery present */ | 1027 | /* Battery present */ |
| 1029 | if (ret.intval) | 1028 | if (ret.intval) |
| @@ -1070,7 +1069,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1070 | break; | 1069 | break; |
| 1071 | 1070 | ||
| 1072 | case POWER_SUPPLY_PROP_ONLINE: | 1071 | case POWER_SUPPLY_PROP_ONLINE: |
| 1073 | switch (ext->type) { | 1072 | switch (ext->desc->type) { |
| 1074 | case POWER_SUPPLY_TYPE_BATTERY: | 1073 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1075 | break; | 1074 | break; |
| 1076 | case POWER_SUPPLY_TYPE_MAINS: | 1075 | case POWER_SUPPLY_TYPE_MAINS: |
| @@ -1115,7 +1114,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1115 | break; | 1114 | break; |
| 1116 | 1115 | ||
| 1117 | case POWER_SUPPLY_PROP_HEALTH: | 1116 | case POWER_SUPPLY_PROP_HEALTH: |
| 1118 | switch (ext->type) { | 1117 | switch (ext->desc->type) { |
| 1119 | case POWER_SUPPLY_TYPE_BATTERY: | 1118 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1120 | break; | 1119 | break; |
| 1121 | case POWER_SUPPLY_TYPE_MAINS: | 1120 | case POWER_SUPPLY_TYPE_MAINS: |
| @@ -1198,7 +1197,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1198 | break; | 1197 | break; |
| 1199 | 1198 | ||
| 1200 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 1199 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
| 1201 | switch (ext->type) { | 1200 | switch (ext->desc->type) { |
| 1202 | case POWER_SUPPLY_TYPE_BATTERY: | 1201 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1203 | di->batt_data.volt = ret.intval / 1000; | 1202 | di->batt_data.volt = ret.intval / 1000; |
| 1204 | break; | 1203 | break; |
| @@ -1214,7 +1213,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1214 | break; | 1213 | break; |
| 1215 | 1214 | ||
| 1216 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | 1215 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: |
| 1217 | switch (ext->type) { | 1216 | switch (ext->desc->type) { |
| 1218 | case POWER_SUPPLY_TYPE_MAINS: | 1217 | case POWER_SUPPLY_TYPE_MAINS: |
| 1219 | /* AVG is used to indicate when we are | 1218 | /* AVG is used to indicate when we are |
| 1220 | * in CV mode */ | 1219 | * in CV mode */ |
| @@ -1239,7 +1238,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1239 | break; | 1238 | break; |
| 1240 | 1239 | ||
| 1241 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 1240 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| 1242 | switch (ext->type) { | 1241 | switch (ext->desc->type) { |
| 1243 | case POWER_SUPPLY_TYPE_BATTERY: | 1242 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1244 | if (ret.intval) | 1243 | if (ret.intval) |
| 1245 | di->events.batt_unknown = false; | 1244 | di->events.batt_unknown = false; |
| @@ -1257,7 +1256,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1257 | break; | 1256 | break; |
| 1258 | 1257 | ||
| 1259 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 1258 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
| 1260 | switch (ext->type) { | 1259 | switch (ext->desc->type) { |
| 1261 | case POWER_SUPPLY_TYPE_MAINS: | 1260 | case POWER_SUPPLY_TYPE_MAINS: |
| 1262 | di->chg_info.ac_curr = | 1261 | di->chg_info.ac_curr = |
| 1263 | ret.intval / 1000; | 1262 | ret.intval / 1000; |
| @@ -1275,7 +1274,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1275 | break; | 1274 | break; |
| 1276 | 1275 | ||
| 1277 | case POWER_SUPPLY_PROP_CURRENT_AVG: | 1276 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
| 1278 | switch (ext->type) { | 1277 | switch (ext->desc->type) { |
| 1279 | case POWER_SUPPLY_TYPE_BATTERY: | 1278 | case POWER_SUPPLY_TYPE_BATTERY: |
| 1280 | di->batt_data.avg_curr = ret.intval / 1000; | 1279 | di->batt_data.avg_curr = ret.intval / 1000; |
| 1281 | break; | 1280 | break; |
| @@ -1311,7 +1310,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) | |||
| 1311 | */ | 1310 | */ |
| 1312 | static void abx500_chargalg_external_power_changed(struct power_supply *psy) | 1311 | static void abx500_chargalg_external_power_changed(struct power_supply *psy) |
| 1313 | { | 1312 | { |
| 1314 | struct abx500_chargalg *di = to_abx500_chargalg_device_info(psy); | 1313 | struct abx500_chargalg *di = power_supply_get_drvdata(psy); |
| 1315 | 1314 | ||
| 1316 | /* | 1315 | /* |
| 1317 | * Trigger execution of the algorithm instantly and read | 1316 | * Trigger execution of the algorithm instantly and read |
| @@ -1336,7 +1335,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1336 | 1335 | ||
| 1337 | /* Collect data from all power_supply class devices */ | 1336 | /* Collect data from all power_supply class devices */ |
| 1338 | class_for_each_device(power_supply_class, NULL, | 1337 | class_for_each_device(power_supply_class, NULL, |
| 1339 | &di->chargalg_psy, abx500_chargalg_get_ext_psy_data); | 1338 | di->chargalg_psy, abx500_chargalg_get_ext_psy_data); |
| 1340 | 1339 | ||
| 1341 | abx500_chargalg_end_of_charge(di); | 1340 | abx500_chargalg_end_of_charge(di); |
| 1342 | abx500_chargalg_check_temp(di); | 1341 | abx500_chargalg_check_temp(di); |
| @@ -1478,7 +1477,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1478 | di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 1477 | di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| 1479 | di->maintenance_chg = false; | 1478 | di->maintenance_chg = false; |
| 1480 | abx500_chargalg_state_to(di, STATE_SUSPENDED); | 1479 | abx500_chargalg_state_to(di, STATE_SUSPENDED); |
| 1481 | power_supply_changed(&di->chargalg_psy); | 1480 | power_supply_changed(di->chargalg_psy); |
| 1482 | /* Intentional fallthrough */ | 1481 | /* Intentional fallthrough */ |
| 1483 | 1482 | ||
| 1484 | case STATE_SUSPENDED: | 1483 | case STATE_SUSPENDED: |
| @@ -1576,7 +1575,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1576 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; | 1575 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; |
| 1577 | di->eoc_cnt = 0; | 1576 | di->eoc_cnt = 0; |
| 1578 | di->maintenance_chg = false; | 1577 | di->maintenance_chg = false; |
| 1579 | power_supply_changed(&di->chargalg_psy); | 1578 | power_supply_changed(di->chargalg_psy); |
| 1580 | 1579 | ||
| 1581 | break; | 1580 | break; |
| 1582 | 1581 | ||
| @@ -1624,7 +1623,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1624 | di->bm->bat_type[ | 1623 | di->bm->bat_type[ |
| 1625 | di->bm->batt_id].maint_a_cur_lvl); | 1624 | di->bm->batt_id].maint_a_cur_lvl); |
| 1626 | abx500_chargalg_state_to(di, STATE_MAINTENANCE_A); | 1625 | abx500_chargalg_state_to(di, STATE_MAINTENANCE_A); |
| 1627 | power_supply_changed(&di->chargalg_psy); | 1626 | power_supply_changed(di->chargalg_psy); |
| 1628 | /* Intentional fallthrough*/ | 1627 | /* Intentional fallthrough*/ |
| 1629 | 1628 | ||
| 1630 | case STATE_MAINTENANCE_A: | 1629 | case STATE_MAINTENANCE_A: |
| @@ -1644,7 +1643,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1644 | di->bm->bat_type[ | 1643 | di->bm->bat_type[ |
| 1645 | di->bm->batt_id].maint_b_cur_lvl); | 1644 | di->bm->batt_id].maint_b_cur_lvl); |
| 1646 | abx500_chargalg_state_to(di, STATE_MAINTENANCE_B); | 1645 | abx500_chargalg_state_to(di, STATE_MAINTENANCE_B); |
| 1647 | power_supply_changed(&di->chargalg_psy); | 1646 | power_supply_changed(di->chargalg_psy); |
| 1648 | /* Intentional fallthrough*/ | 1647 | /* Intentional fallthrough*/ |
| 1649 | 1648 | ||
| 1650 | case STATE_MAINTENANCE_B: | 1649 | case STATE_MAINTENANCE_B: |
| @@ -1663,7 +1662,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di) | |||
| 1663 | abx500_chargalg_stop_maintenance_timer(di); | 1662 | abx500_chargalg_stop_maintenance_timer(di); |
| 1664 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; | 1663 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; |
| 1665 | abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH); | 1664 | abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH); |
| 1666 | power_supply_changed(&di->chargalg_psy); | 1665 | power_supply_changed(di->chargalg_psy); |
| 1667 | /* Intentional fallthrough */ | 1666 | /* Intentional fallthrough */ |
| 1668 | 1667 | ||
| 1669 | case STATE_TEMP_LOWHIGH: | 1668 | case STATE_TEMP_LOWHIGH: |
| @@ -1779,9 +1778,7 @@ static int abx500_chargalg_get_property(struct power_supply *psy, | |||
| 1779 | enum power_supply_property psp, | 1778 | enum power_supply_property psp, |
| 1780 | union power_supply_propval *val) | 1779 | union power_supply_propval *val) |
| 1781 | { | 1780 | { |
| 1782 | struct abx500_chargalg *di; | 1781 | struct abx500_chargalg *di = power_supply_get_drvdata(psy); |
| 1783 | |||
| 1784 | di = to_abx500_chargalg_device_info(psy); | ||
| 1785 | 1782 | ||
| 1786 | switch (psp) { | 1783 | switch (psp) { |
| 1787 | case POWER_SUPPLY_PROP_STATUS: | 1784 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -2034,7 +2031,7 @@ static int abx500_chargalg_remove(struct platform_device *pdev) | |||
| 2034 | /* Delete the work queue */ | 2031 | /* Delete the work queue */ |
| 2035 | destroy_workqueue(di->chargalg_wq); | 2032 | destroy_workqueue(di->chargalg_wq); |
| 2036 | 2033 | ||
| 2037 | power_supply_unregister(&di->chargalg_psy); | 2034 | power_supply_unregister(di->chargalg_psy); |
| 2038 | 2035 | ||
| 2039 | return 0; | 2036 | return 0; |
| 2040 | } | 2037 | } |
| @@ -2043,10 +2040,20 @@ static char *supply_interface[] = { | |||
| 2043 | "ab8500_fg", | 2040 | "ab8500_fg", |
| 2044 | }; | 2041 | }; |
| 2045 | 2042 | ||
| 2043 | static const struct power_supply_desc abx500_chargalg_desc = { | ||
| 2044 | .name = "abx500_chargalg", | ||
| 2045 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 2046 | .properties = abx500_chargalg_props, | ||
| 2047 | .num_properties = ARRAY_SIZE(abx500_chargalg_props), | ||
| 2048 | .get_property = abx500_chargalg_get_property, | ||
| 2049 | .external_power_changed = abx500_chargalg_external_power_changed, | ||
| 2050 | }; | ||
| 2051 | |||
| 2046 | static int abx500_chargalg_probe(struct platform_device *pdev) | 2052 | static int abx500_chargalg_probe(struct platform_device *pdev) |
| 2047 | { | 2053 | { |
| 2048 | struct device_node *np = pdev->dev.of_node; | 2054 | struct device_node *np = pdev->dev.of_node; |
| 2049 | struct abx500_bm_data *plat = pdev->dev.platform_data; | 2055 | struct abx500_bm_data *plat = pdev->dev.platform_data; |
| 2056 | struct power_supply_config psy_cfg = {}; | ||
| 2050 | struct abx500_chargalg *di; | 2057 | struct abx500_chargalg *di; |
| 2051 | int ret = 0; | 2058 | int ret = 0; |
| 2052 | 2059 | ||
| @@ -2074,16 +2081,9 @@ static int abx500_chargalg_probe(struct platform_device *pdev) | |||
| 2074 | di->dev = &pdev->dev; | 2081 | di->dev = &pdev->dev; |
| 2075 | di->parent = dev_get_drvdata(pdev->dev.parent); | 2082 | di->parent = dev_get_drvdata(pdev->dev.parent); |
| 2076 | 2083 | ||
| 2077 | /* chargalg supply */ | 2084 | psy_cfg.supplied_to = supply_interface; |
| 2078 | di->chargalg_psy.name = "abx500_chargalg"; | 2085 | psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); |
| 2079 | di->chargalg_psy.type = POWER_SUPPLY_TYPE_BATTERY; | 2086 | psy_cfg.drv_data = di; |
| 2080 | di->chargalg_psy.properties = abx500_chargalg_props; | ||
| 2081 | di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props); | ||
| 2082 | di->chargalg_psy.get_property = abx500_chargalg_get_property; | ||
| 2083 | di->chargalg_psy.supplied_to = supply_interface; | ||
| 2084 | di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface), | ||
| 2085 | di->chargalg_psy.external_power_changed = | ||
| 2086 | abx500_chargalg_external_power_changed; | ||
| 2087 | 2087 | ||
| 2088 | /* Initilialize safety timer */ | 2088 | /* Initilialize safety timer */ |
| 2089 | hrtimer_init(&di->safety_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | 2089 | hrtimer_init(&di->safety_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); |
| @@ -2115,9 +2115,11 @@ static int abx500_chargalg_probe(struct platform_device *pdev) | |||
| 2115 | di->chg_info.prev_conn_chg = -1; | 2115 | di->chg_info.prev_conn_chg = -1; |
| 2116 | 2116 | ||
| 2117 | /* Register chargalg power supply class */ | 2117 | /* Register chargalg power supply class */ |
| 2118 | ret = power_supply_register(di->dev, &di->chargalg_psy); | 2118 | di->chargalg_psy = power_supply_register(di->dev, &abx500_chargalg_desc, |
| 2119 | if (ret) { | 2119 | &psy_cfg); |
| 2120 | if (IS_ERR(di->chargalg_psy)) { | ||
| 2120 | dev_err(di->dev, "failed to register chargalg psy\n"); | 2121 | dev_err(di->dev, "failed to register chargalg psy\n"); |
| 2122 | ret = PTR_ERR(di->chargalg_psy); | ||
| 2121 | goto free_chargalg_wq; | 2123 | goto free_chargalg_wq; |
| 2122 | } | 2124 | } |
| 2123 | 2125 | ||
| @@ -2138,7 +2140,7 @@ static int abx500_chargalg_probe(struct platform_device *pdev) | |||
| 2138 | return ret; | 2140 | return ret; |
| 2139 | 2141 | ||
| 2140 | free_psy: | 2142 | free_psy: |
| 2141 | power_supply_unregister(&di->chargalg_psy); | 2143 | power_supply_unregister(di->chargalg_psy); |
| 2142 | free_chargalg_wq: | 2144 | free_chargalg_wq: |
| 2143 | destroy_workqueue(di->chargalg_wq); | 2145 | destroy_workqueue(di->chargalg_wq); |
| 2144 | return ret; | 2146 | return ret; |
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index 39763015b360..9d1a7fbcaed4 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c | |||
| @@ -15,10 +15,10 @@ | |||
| 15 | #include <linux/apm-emulation.h> | 15 | #include <linux/apm-emulation.h> |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | #define PSY_PROP(psy, prop, val) (psy->get_property(psy, \ | 18 | #define PSY_PROP(psy, prop, val) (power_supply_get_property(psy, \ |
| 19 | POWER_SUPPLY_PROP_##prop, val)) | 19 | POWER_SUPPLY_PROP_##prop, val)) |
| 20 | 20 | ||
| 21 | #define _MPSY_PROP(prop, val) (main_battery->get_property(main_battery, \ | 21 | #define _MPSY_PROP(prop, val) (power_supply_get_property(main_battery, \ |
| 22 | prop, val)) | 22 | prop, val)) |
| 23 | 23 | ||
| 24 | #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) | 24 | #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) |
| @@ -48,7 +48,7 @@ static int __find_main_battery(struct device *dev, void *data) | |||
| 48 | 48 | ||
| 49 | bp->bat = dev_get_drvdata(dev); | 49 | bp->bat = dev_get_drvdata(dev); |
| 50 | 50 | ||
| 51 | if (bp->bat->use_for_apm) { | 51 | if (bp->bat->desc->use_for_apm) { |
| 52 | /* nice, we explicitly asked to report this battery. */ | 52 | /* nice, we explicitly asked to report this battery. */ |
| 53 | bp->main = bp->bat; | 53 | bp->main = bp->bat; |
| 54 | return 1; | 54 | return 1; |
diff --git a/drivers/power/axp288_fuel_gauge.c b/drivers/power/axp288_fuel_gauge.c new file mode 100644 index 000000000000..ca1cc5a47eb1 --- /dev/null +++ b/drivers/power/axp288_fuel_gauge.c | |||
| @@ -0,0 +1,1154 @@ | |||
| 1 | /* | ||
| 2 | * axp288_fuel_gauge.c - Xpower AXP288 PMIC Fuel Gauge Driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Intel Corporation | ||
| 5 | * | ||
| 6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; version 2 of the License. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, but | ||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * General Public License for more details. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/regmap.h> | ||
| 23 | #include <linux/jiffies.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/workqueue.h> | ||
| 27 | #include <linux/mfd/axp20x.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | #include <linux/power_supply.h> | ||
| 30 | #include <linux/iio/consumer.h> | ||
| 31 | #include <linux/debugfs.h> | ||
| 32 | #include <linux/seq_file.h> | ||
| 33 | |||
| 34 | #define CHRG_STAT_BAT_SAFE_MODE (1 << 3) | ||
| 35 | #define CHRG_STAT_BAT_VALID (1 << 4) | ||
| 36 | #define CHRG_STAT_BAT_PRESENT (1 << 5) | ||
| 37 | #define CHRG_STAT_CHARGING (1 << 6) | ||
| 38 | #define CHRG_STAT_PMIC_OTP (1 << 7) | ||
| 39 | |||
| 40 | #define CHRG_CCCV_CC_MASK 0xf /* 4 bits */ | ||
| 41 | #define CHRG_CCCV_CC_BIT_POS 0 | ||
| 42 | #define CHRG_CCCV_CC_OFFSET 200 /* 200mA */ | ||
| 43 | #define CHRG_CCCV_CC_LSB_RES 200 /* 200mA */ | ||
| 44 | #define CHRG_CCCV_ITERM_20P (1 << 4) /* 20% of CC */ | ||
| 45 | #define CHRG_CCCV_CV_MASK 0x60 /* 2 bits */ | ||
| 46 | #define CHRG_CCCV_CV_BIT_POS 5 | ||
| 47 | #define CHRG_CCCV_CV_4100MV 0x0 /* 4.10V */ | ||
| 48 | #define CHRG_CCCV_CV_4150MV 0x1 /* 4.15V */ | ||
| 49 | #define CHRG_CCCV_CV_4200MV 0x2 /* 4.20V */ | ||
| 50 | #define CHRG_CCCV_CV_4350MV 0x3 /* 4.35V */ | ||
| 51 | #define CHRG_CCCV_CHG_EN (1 << 7) | ||
| 52 | |||
| 53 | #define CV_4100 4100 /* 4100mV */ | ||
| 54 | #define CV_4150 4150 /* 4150mV */ | ||
| 55 | #define CV_4200 4200 /* 4200mV */ | ||
| 56 | #define CV_4350 4350 /* 4350mV */ | ||
| 57 | |||
| 58 | #define TEMP_IRQ_CFG_QWBTU (1 << 0) | ||
| 59 | #define TEMP_IRQ_CFG_WBTU (1 << 1) | ||
| 60 | #define TEMP_IRQ_CFG_QWBTO (1 << 2) | ||
| 61 | #define TEMP_IRQ_CFG_WBTO (1 << 3) | ||
| 62 | #define TEMP_IRQ_CFG_MASK 0xf | ||
| 63 | |||
| 64 | #define FG_IRQ_CFG_LOWBATT_WL2 (1 << 0) | ||
| 65 | #define FG_IRQ_CFG_LOWBATT_WL1 (1 << 1) | ||
| 66 | #define FG_IRQ_CFG_LOWBATT_MASK 0x3 | ||
| 67 | #define LOWBAT_IRQ_STAT_LOWBATT_WL2 (1 << 0) | ||
| 68 | #define LOWBAT_IRQ_STAT_LOWBATT_WL1 (1 << 1) | ||
| 69 | |||
| 70 | #define FG_CNTL_OCV_ADJ_STAT (1 << 2) | ||
| 71 | #define FG_CNTL_OCV_ADJ_EN (1 << 3) | ||
| 72 | #define FG_CNTL_CAP_ADJ_STAT (1 << 4) | ||
| 73 | #define FG_CNTL_CAP_ADJ_EN (1 << 5) | ||
| 74 | #define FG_CNTL_CC_EN (1 << 6) | ||
| 75 | #define FG_CNTL_GAUGE_EN (1 << 7) | ||
| 76 | |||
| 77 | #define FG_REP_CAP_VALID (1 << 7) | ||
| 78 | #define FG_REP_CAP_VAL_MASK 0x7F | ||
| 79 | |||
| 80 | #define FG_DES_CAP1_VALID (1 << 7) | ||
| 81 | #define FG_DES_CAP1_VAL_MASK 0x7F | ||
| 82 | #define FG_DES_CAP0_VAL_MASK 0xFF | ||
| 83 | #define FG_DES_CAP_RES_LSB 1456 /* 1.456mAhr */ | ||
| 84 | |||
| 85 | #define FG_CC_MTR1_VALID (1 << 7) | ||
| 86 | #define FG_CC_MTR1_VAL_MASK 0x7F | ||
| 87 | #define FG_CC_MTR0_VAL_MASK 0xFF | ||
| 88 | #define FG_DES_CC_RES_LSB 1456 /* 1.456mAhr */ | ||
| 89 | |||
| 90 | #define FG_OCV_CAP_VALID (1 << 7) | ||
| 91 | #define FG_OCV_CAP_VAL_MASK 0x7F | ||
| 92 | #define FG_CC_CAP_VALID (1 << 7) | ||
| 93 | #define FG_CC_CAP_VAL_MASK 0x7F | ||
| 94 | |||
| 95 | #define FG_LOW_CAP_THR1_MASK 0xf0 /* 5% tp 20% */ | ||
| 96 | #define FG_LOW_CAP_THR1_VAL 0xa0 /* 15 perc */ | ||
| 97 | #define FG_LOW_CAP_THR2_MASK 0x0f /* 0% to 15% */ | ||
| 98 | #define FG_LOW_CAP_WARN_THR 14 /* 14 perc */ | ||
| 99 | #define FG_LOW_CAP_CRIT_THR 4 /* 4 perc */ | ||
| 100 | #define FG_LOW_CAP_SHDN_THR 0 /* 0 perc */ | ||
| 101 | |||
| 102 | #define STATUS_MON_DELAY_JIFFIES (HZ * 60) /*60 sec */ | ||
| 103 | #define NR_RETRY_CNT 3 | ||
| 104 | #define DEV_NAME "axp288_fuel_gauge" | ||
| 105 | |||
| 106 | /* 1.1mV per LSB expressed in uV */ | ||
| 107 | #define VOLTAGE_FROM_ADC(a) ((a * 11) / 10) | ||
| 108 | /* properties converted to tenths of degrees, uV, uA, uW */ | ||
| 109 | #define PROP_TEMP(a) ((a) * 10) | ||
| 110 | #define UNPROP_TEMP(a) ((a) / 10) | ||
| 111 | #define PROP_VOLT(a) ((a) * 1000) | ||
| 112 | #define PROP_CURR(a) ((a) * 1000) | ||
| 113 | |||
| 114 | #define AXP288_FG_INTR_NUM 6 | ||
| 115 | enum { | ||
| 116 | QWBTU_IRQ = 0, | ||
| 117 | WBTU_IRQ, | ||
| 118 | QWBTO_IRQ, | ||
| 119 | WBTO_IRQ, | ||
| 120 | WL2_IRQ, | ||
| 121 | WL1_IRQ, | ||
| 122 | }; | ||
| 123 | |||
| 124 | struct axp288_fg_info { | ||
| 125 | struct platform_device *pdev; | ||
| 126 | struct axp20x_fg_pdata *pdata; | ||
| 127 | struct regmap *regmap; | ||
| 128 | struct regmap_irq_chip_data *regmap_irqc; | ||
| 129 | int irq[AXP288_FG_INTR_NUM]; | ||
| 130 | struct power_supply *bat; | ||
| 131 | struct mutex lock; | ||
| 132 | int status; | ||
| 133 | struct delayed_work status_monitor; | ||
| 134 | struct dentry *debug_file; | ||
| 135 | }; | ||
| 136 | |||
| 137 | static enum power_supply_property fuel_gauge_props[] = { | ||
| 138 | POWER_SUPPLY_PROP_STATUS, | ||
| 139 | POWER_SUPPLY_PROP_PRESENT, | ||
| 140 | POWER_SUPPLY_PROP_HEALTH, | ||
| 141 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | ||
| 142 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
| 143 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 144 | POWER_SUPPLY_PROP_VOLTAGE_OCV, | ||
| 145 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
| 146 | POWER_SUPPLY_PROP_CAPACITY, | ||
| 147 | POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, | ||
| 148 | POWER_SUPPLY_PROP_TEMP, | ||
| 149 | POWER_SUPPLY_PROP_TEMP_MAX, | ||
| 150 | POWER_SUPPLY_PROP_TEMP_MIN, | ||
| 151 | POWER_SUPPLY_PROP_TEMP_ALERT_MIN, | ||
| 152 | POWER_SUPPLY_PROP_TEMP_ALERT_MAX, | ||
| 153 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 154 | POWER_SUPPLY_PROP_CHARGE_FULL, | ||
| 155 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
| 156 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
| 157 | POWER_SUPPLY_PROP_MODEL_NAME, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static int fuel_gauge_reg_readb(struct axp288_fg_info *info, int reg) | ||
| 161 | { | ||
| 162 | int ret, i; | ||
| 163 | unsigned int val; | ||
| 164 | |||
| 165 | for (i = 0; i < NR_RETRY_CNT; i++) { | ||
| 166 | ret = regmap_read(info->regmap, reg, &val); | ||
| 167 | if (ret == -EBUSY) | ||
| 168 | continue; | ||
| 169 | else | ||
| 170 | break; | ||
| 171 | } | ||
| 172 | |||
| 173 | if (ret < 0) | ||
| 174 | dev_err(&info->pdev->dev, "axp288 reg read err:%d\n", ret); | ||
| 175 | |||
| 176 | return val; | ||
| 177 | } | ||
| 178 | |||
| 179 | static int fuel_gauge_reg_writeb(struct axp288_fg_info *info, int reg, u8 val) | ||
| 180 | { | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | ret = regmap_write(info->regmap, reg, (unsigned int)val); | ||
| 184 | |||
| 185 | if (ret < 0) | ||
| 186 | dev_err(&info->pdev->dev, "axp288 reg write err:%d\n", ret); | ||
| 187 | |||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int pmic_read_adc_val(const char *name, int *raw_val, | ||
| 192 | struct axp288_fg_info *info) | ||
| 193 | { | ||
| 194 | int ret, val = 0; | ||
| 195 | struct iio_channel *indio_chan; | ||
| 196 | |||
| 197 | indio_chan = iio_channel_get(NULL, name); | ||
| 198 | if (IS_ERR_OR_NULL(indio_chan)) { | ||
| 199 | ret = PTR_ERR(indio_chan); | ||
| 200 | goto exit; | ||
| 201 | } | ||
| 202 | ret = iio_read_channel_raw(indio_chan, &val); | ||
| 203 | if (ret < 0) { | ||
| 204 | dev_err(&info->pdev->dev, | ||
| 205 | "IIO channel read error: %x, %x\n", ret, val); | ||
| 206 | goto err_exit; | ||
| 207 | } | ||
| 208 | |||
| 209 | dev_dbg(&info->pdev->dev, "adc raw val=%x\n", val); | ||
| 210 | *raw_val = val; | ||
| 211 | |||
| 212 | err_exit: | ||
| 213 | iio_channel_release(indio_chan); | ||
| 214 | exit: | ||
| 215 | return ret; | ||
| 216 | } | ||
| 217 | |||
| 218 | #ifdef CONFIG_DEBUG_FS | ||
| 219 | static int fuel_gauge_debug_show(struct seq_file *s, void *data) | ||
| 220 | { | ||
| 221 | struct axp288_fg_info *info = s->private; | ||
| 222 | int raw_val, ret; | ||
| 223 | |||
| 224 | seq_printf(s, " PWR_STATUS[%02x] : %02x\n", | ||
| 225 | AXP20X_PWR_INPUT_STATUS, | ||
| 226 | fuel_gauge_reg_readb(info, AXP20X_PWR_INPUT_STATUS)); | ||
| 227 | seq_printf(s, "PWR_OP_MODE[%02x] : %02x\n", | ||
| 228 | AXP20X_PWR_OP_MODE, | ||
| 229 | fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE)); | ||
| 230 | seq_printf(s, " CHRG_CTRL1[%02x] : %02x\n", | ||
| 231 | AXP20X_CHRG_CTRL1, | ||
| 232 | fuel_gauge_reg_readb(info, AXP20X_CHRG_CTRL1)); | ||
| 233 | seq_printf(s, " VLTF[%02x] : %02x\n", | ||
| 234 | AXP20X_V_LTF_DISCHRG, | ||
| 235 | fuel_gauge_reg_readb(info, AXP20X_V_LTF_DISCHRG)); | ||
| 236 | seq_printf(s, " VHTF[%02x] : %02x\n", | ||
| 237 | AXP20X_V_HTF_DISCHRG, | ||
| 238 | fuel_gauge_reg_readb(info, AXP20X_V_HTF_DISCHRG)); | ||
| 239 | seq_printf(s, " CC_CTRL[%02x] : %02x\n", | ||
| 240 | AXP20X_CC_CTRL, | ||
| 241 | fuel_gauge_reg_readb(info, AXP20X_CC_CTRL)); | ||
| 242 | seq_printf(s, "BATTERY CAP[%02x] : %02x\n", | ||
| 243 | AXP20X_FG_RES, | ||
| 244 | fuel_gauge_reg_readb(info, AXP20X_FG_RES)); | ||
| 245 | seq_printf(s, " FG_RDC1[%02x] : %02x\n", | ||
| 246 | AXP288_FG_RDC1_REG, | ||
| 247 | fuel_gauge_reg_readb(info, AXP288_FG_RDC1_REG)); | ||
| 248 | seq_printf(s, " FG_RDC0[%02x] : %02x\n", | ||
| 249 | AXP288_FG_RDC0_REG, | ||
| 250 | fuel_gauge_reg_readb(info, AXP288_FG_RDC0_REG)); | ||
| 251 | seq_printf(s, " FG_OCVH[%02x] : %02x\n", | ||
| 252 | AXP288_FG_OCVH_REG, | ||
| 253 | fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG)); | ||
| 254 | seq_printf(s, " FG_OCVL[%02x] : %02x\n", | ||
| 255 | AXP288_FG_OCVL_REG, | ||
| 256 | fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG)); | ||
| 257 | seq_printf(s, "FG_DES_CAP1[%02x] : %02x\n", | ||
| 258 | AXP288_FG_DES_CAP1_REG, | ||
| 259 | fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG)); | ||
| 260 | seq_printf(s, "FG_DES_CAP0[%02x] : %02x\n", | ||
| 261 | AXP288_FG_DES_CAP0_REG, | ||
| 262 | fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP0_REG)); | ||
| 263 | seq_printf(s, " FG_CC_MTR1[%02x] : %02x\n", | ||
| 264 | AXP288_FG_CC_MTR1_REG, | ||
| 265 | fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR1_REG)); | ||
| 266 | seq_printf(s, " FG_CC_MTR0[%02x] : %02x\n", | ||
| 267 | AXP288_FG_CC_MTR0_REG, | ||
| 268 | fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR0_REG)); | ||
| 269 | seq_printf(s, " FG_OCV_CAP[%02x] : %02x\n", | ||
| 270 | AXP288_FG_OCV_CAP_REG, | ||
| 271 | fuel_gauge_reg_readb(info, AXP288_FG_OCV_CAP_REG)); | ||
| 272 | seq_printf(s, " FG_CC_CAP[%02x] : %02x\n", | ||
| 273 | AXP288_FG_CC_CAP_REG, | ||
| 274 | fuel_gauge_reg_readb(info, AXP288_FG_CC_CAP_REG)); | ||
| 275 | seq_printf(s, " FG_LOW_CAP[%02x] : %02x\n", | ||
| 276 | AXP288_FG_LOW_CAP_REG, | ||
| 277 | fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG)); | ||
| 278 | seq_printf(s, "TUNING_CTL0[%02x] : %02x\n", | ||
| 279 | AXP288_FG_TUNE0, | ||
| 280 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE0)); | ||
| 281 | seq_printf(s, "TUNING_CTL1[%02x] : %02x\n", | ||
| 282 | AXP288_FG_TUNE1, | ||
| 283 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE1)); | ||
| 284 | seq_printf(s, "TUNING_CTL2[%02x] : %02x\n", | ||
| 285 | AXP288_FG_TUNE2, | ||
| 286 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE2)); | ||
| 287 | seq_printf(s, "TUNING_CTL3[%02x] : %02x\n", | ||
| 288 | AXP288_FG_TUNE3, | ||
| 289 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE3)); | ||
| 290 | seq_printf(s, "TUNING_CTL4[%02x] : %02x\n", | ||
| 291 | AXP288_FG_TUNE4, | ||
| 292 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE4)); | ||
| 293 | seq_printf(s, "TUNING_CTL5[%02x] : %02x\n", | ||
| 294 | AXP288_FG_TUNE5, | ||
| 295 | fuel_gauge_reg_readb(info, AXP288_FG_TUNE5)); | ||
| 296 | |||
| 297 | ret = pmic_read_adc_val("axp288-batt-temp", &raw_val, info); | ||
| 298 | if (ret >= 0) | ||
| 299 | seq_printf(s, "axp288-batttemp : %d\n", raw_val); | ||
| 300 | ret = pmic_read_adc_val("axp288-pmic-temp", &raw_val, info); | ||
| 301 | if (ret >= 0) | ||
| 302 | seq_printf(s, "axp288-pmictemp : %d\n", raw_val); | ||
| 303 | ret = pmic_read_adc_val("axp288-system-temp", &raw_val, info); | ||
| 304 | if (ret >= 0) | ||
| 305 | seq_printf(s, "axp288-systtemp : %d\n", raw_val); | ||
| 306 | ret = pmic_read_adc_val("axp288-chrg-curr", &raw_val, info); | ||
| 307 | if (ret >= 0) | ||
| 308 | seq_printf(s, "axp288-chrgcurr : %d\n", raw_val); | ||
| 309 | ret = pmic_read_adc_val("axp288-chrg-d-curr", &raw_val, info); | ||
| 310 | if (ret >= 0) | ||
| 311 | seq_printf(s, "axp288-dchrgcur : %d\n", raw_val); | ||
| 312 | ret = pmic_read_adc_val("axp288-batt-volt", &raw_val, info); | ||
| 313 | if (ret >= 0) | ||
| 314 | seq_printf(s, "axp288-battvolt : %d\n", raw_val); | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int debug_open(struct inode *inode, struct file *file) | ||
| 320 | { | ||
| 321 | return single_open(file, fuel_gauge_debug_show, inode->i_private); | ||
| 322 | } | ||
| 323 | |||
| 324 | static const struct file_operations fg_debug_fops = { | ||
| 325 | .open = debug_open, | ||
| 326 | .read = seq_read, | ||
| 327 | .llseek = seq_lseek, | ||
| 328 | .release = single_release, | ||
| 329 | }; | ||
| 330 | |||
| 331 | static void fuel_gauge_create_debugfs(struct axp288_fg_info *info) | ||
| 332 | { | ||
| 333 | info->debug_file = debugfs_create_file("fuelgauge", 0666, NULL, | ||
| 334 | info, &fg_debug_fops); | ||
| 335 | } | ||
| 336 | |||
| 337 | static void fuel_gauge_remove_debugfs(struct axp288_fg_info *info) | ||
| 338 | { | ||
| 339 | debugfs_remove(info->debug_file); | ||
| 340 | } | ||
| 341 | #else | ||
| 342 | static inline void fuel_gauge_create_debugfs(struct axp288_fg_info *info) | ||
| 343 | { | ||
| 344 | } | ||
| 345 | static inline void fuel_gauge_remove_debugfs(struct axp288_fg_info *info) | ||
| 346 | { | ||
| 347 | } | ||
| 348 | #endif | ||
| 349 | |||
| 350 | static void fuel_gauge_get_status(struct axp288_fg_info *info) | ||
| 351 | { | ||
| 352 | int pwr_stat, ret; | ||
| 353 | int charge, discharge; | ||
| 354 | |||
| 355 | pwr_stat = fuel_gauge_reg_readb(info, AXP20X_PWR_INPUT_STATUS); | ||
| 356 | if (pwr_stat < 0) { | ||
| 357 | dev_err(&info->pdev->dev, | ||
| 358 | "PWR STAT read failed:%d\n", pwr_stat); | ||
| 359 | return; | ||
| 360 | } | ||
| 361 | ret = pmic_read_adc_val("axp288-chrg-curr", &charge, info); | ||
| 362 | if (ret < 0) { | ||
| 363 | dev_err(&info->pdev->dev, | ||
| 364 | "ADC charge current read failed:%d\n", ret); | ||
| 365 | return; | ||
| 366 | } | ||
| 367 | ret = pmic_read_adc_val("axp288-chrg-d-curr", &discharge, info); | ||
| 368 | if (ret < 0) { | ||
| 369 | dev_err(&info->pdev->dev, | ||
| 370 | "ADC discharge current read failed:%d\n", ret); | ||
| 371 | return; | ||
| 372 | } | ||
| 373 | |||
| 374 | if (charge > 0) | ||
| 375 | info->status = POWER_SUPPLY_STATUS_CHARGING; | ||
| 376 | else if (discharge > 0) | ||
| 377 | info->status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 378 | else { | ||
| 379 | if (pwr_stat & CHRG_STAT_BAT_PRESENT) | ||
| 380 | info->status = POWER_SUPPLY_STATUS_FULL; | ||
| 381 | else | ||
| 382 | info->status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
| 383 | } | ||
| 384 | } | ||
| 385 | |||
| 386 | static int fuel_gauge_get_vbatt(struct axp288_fg_info *info, int *vbatt) | ||
| 387 | { | ||
| 388 | int ret = 0, raw_val; | ||
| 389 | |||
| 390 | ret = pmic_read_adc_val("axp288-batt-volt", &raw_val, info); | ||
| 391 | if (ret < 0) | ||
| 392 | goto vbatt_read_fail; | ||
| 393 | |||
| 394 | *vbatt = VOLTAGE_FROM_ADC(raw_val); | ||
| 395 | vbatt_read_fail: | ||
| 396 | return ret; | ||
| 397 | } | ||
| 398 | |||
| 399 | static int fuel_gauge_get_current(struct axp288_fg_info *info, int *cur) | ||
| 400 | { | ||
| 401 | int ret, value = 0; | ||
| 402 | int charge, discharge; | ||
| 403 | |||
| 404 | ret = pmic_read_adc_val("axp288-chrg-curr", &charge, info); | ||
| 405 | if (ret < 0) | ||
| 406 | goto current_read_fail; | ||
| 407 | ret = pmic_read_adc_val("axp288-chrg-d-curr", &discharge, info); | ||
| 408 | if (ret < 0) | ||
| 409 | goto current_read_fail; | ||
| 410 | |||
| 411 | if (charge > 0) | ||
| 412 | value = charge; | ||
| 413 | else if (discharge > 0) | ||
| 414 | value = -1 * discharge; | ||
| 415 | |||
| 416 | *cur = value; | ||
| 417 | current_read_fail: | ||
| 418 | return ret; | ||
| 419 | } | ||
| 420 | |||
| 421 | static int temp_to_adc(struct axp288_fg_info *info, int tval) | ||
| 422 | { | ||
| 423 | int rntc = 0, i, ret, adc_val; | ||
| 424 | int rmin, rmax, tmin, tmax; | ||
| 425 | int tcsz = info->pdata->tcsz; | ||
| 426 | |||
| 427 | /* get the Rntc resitance value for this temp */ | ||
| 428 | if (tval > info->pdata->thermistor_curve[0][1]) { | ||
| 429 | rntc = info->pdata->thermistor_curve[0][0]; | ||
| 430 | } else if (tval <= info->pdata->thermistor_curve[tcsz-1][1]) { | ||
| 431 | rntc = info->pdata->thermistor_curve[tcsz-1][0]; | ||
| 432 | } else { | ||
| 433 | for (i = 1; i < tcsz; i++) { | ||
| 434 | if (tval > info->pdata->thermistor_curve[i][1]) { | ||
| 435 | rmin = info->pdata->thermistor_curve[i-1][0]; | ||
| 436 | rmax = info->pdata->thermistor_curve[i][0]; | ||
| 437 | tmin = info->pdata->thermistor_curve[i-1][1]; | ||
| 438 | tmax = info->pdata->thermistor_curve[i][1]; | ||
| 439 | rntc = rmin + ((rmax - rmin) * | ||
| 440 | (tval - tmin) / (tmax - tmin)); | ||
| 441 | break; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | /* we need the current to calculate the proper adc voltage */ | ||
| 447 | ret = fuel_gauge_reg_readb(info, AXP20X_ADC_RATE); | ||
| 448 | if (ret < 0) { | ||
| 449 | dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); | ||
| 450 | ret = 0x30; | ||
| 451 | } | ||
| 452 | |||
| 453 | /* | ||
| 454 | * temperature is proportional to NTS thermistor resistance | ||
| 455 | * ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA | ||
| 456 | * [12-bit ADC VAL] = R_NTC(Ω) * current / 800 | ||
| 457 | */ | ||
| 458 | adc_val = rntc * (20 + (20 * ((ret >> 4) & 0x3))) / 800; | ||
| 459 | |||
| 460 | return adc_val; | ||
| 461 | } | ||
| 462 | |||
| 463 | static int adc_to_temp(struct axp288_fg_info *info, int adc_val) | ||
| 464 | { | ||
| 465 | int ret, r, i, tval = 0; | ||
| 466 | int rmin, rmax, tmin, tmax; | ||
| 467 | int tcsz = info->pdata->tcsz; | ||
| 468 | |||
| 469 | ret = fuel_gauge_reg_readb(info, AXP20X_ADC_RATE); | ||
| 470 | if (ret < 0) { | ||
| 471 | dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); | ||
| 472 | ret = 0x30; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* | ||
| 476 | * temperature is proportional to NTS thermistor resistance | ||
| 477 | * ADC_RATE[5-4] determines current, 00=20uA,01=40uA,10=60uA,11=80uA | ||
| 478 | * R_NTC(Ω) = [12-bit ADC VAL] * 800 / current | ||
| 479 | */ | ||
| 480 | r = adc_val * 800 / (20 + (20 * ((ret >> 4) & 0x3))); | ||
| 481 | |||
| 482 | if (r < info->pdata->thermistor_curve[0][0]) { | ||
| 483 | tval = info->pdata->thermistor_curve[0][1]; | ||
| 484 | } else if (r >= info->pdata->thermistor_curve[tcsz-1][0]) { | ||
| 485 | tval = info->pdata->thermistor_curve[tcsz-1][1]; | ||
| 486 | } else { | ||
| 487 | for (i = 1; i < tcsz; i++) { | ||
| 488 | if (r < info->pdata->thermistor_curve[i][0]) { | ||
| 489 | rmin = info->pdata->thermistor_curve[i-1][0]; | ||
| 490 | rmax = info->pdata->thermistor_curve[i][0]; | ||
| 491 | tmin = info->pdata->thermistor_curve[i-1][1]; | ||
| 492 | tmax = info->pdata->thermistor_curve[i][1]; | ||
| 493 | tval = tmin + ((tmax - tmin) * | ||
| 494 | (r - rmin) / (rmax - rmin)); | ||
| 495 | break; | ||
| 496 | } | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | return tval; | ||
| 501 | } | ||
| 502 | |||
| 503 | static int fuel_gauge_get_btemp(struct axp288_fg_info *info, int *btemp) | ||
| 504 | { | ||
| 505 | int ret, raw_val = 0; | ||
| 506 | |||
| 507 | ret = pmic_read_adc_val("axp288-batt-temp", &raw_val, info); | ||
| 508 | if (ret < 0) | ||
| 509 | goto temp_read_fail; | ||
| 510 | |||
| 511 | *btemp = adc_to_temp(info, raw_val); | ||
| 512 | |||
| 513 | temp_read_fail: | ||
| 514 | return ret; | ||
| 515 | } | ||
| 516 | |||
| 517 | static int fuel_gauge_get_vocv(struct axp288_fg_info *info, int *vocv) | ||
| 518 | { | ||
| 519 | int ret, value; | ||
| 520 | |||
| 521 | /* 12-bit data value, upper 8 in OCVH, lower 4 in OCVL */ | ||
| 522 | ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG); | ||
| 523 | if (ret < 0) | ||
| 524 | goto vocv_read_fail; | ||
| 525 | value = ret << 4; | ||
| 526 | |||
| 527 | ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG); | ||
| 528 | if (ret < 0) | ||
| 529 | goto vocv_read_fail; | ||
| 530 | value |= (ret & 0xf); | ||
| 531 | |||
| 532 | *vocv = VOLTAGE_FROM_ADC(value); | ||
| 533 | vocv_read_fail: | ||
| 534 | return ret; | ||
| 535 | } | ||
| 536 | |||
| 537 | static int fuel_gauge_battery_health(struct axp288_fg_info *info) | ||
| 538 | { | ||
| 539 | int temp, vocv; | ||
| 540 | int ret, health = POWER_SUPPLY_HEALTH_UNKNOWN; | ||
| 541 | |||
| 542 | ret = fuel_gauge_get_btemp(info, &temp); | ||
| 543 | if (ret < 0) | ||
| 544 | goto health_read_fail; | ||
| 545 | |||
| 546 | ret = fuel_gauge_get_vocv(info, &vocv); | ||
| 547 | if (ret < 0) | ||
| 548 | goto health_read_fail; | ||
| 549 | |||
| 550 | if (vocv > info->pdata->max_volt) | ||
| 551 | health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | ||
| 552 | else if (temp > info->pdata->max_temp) | ||
| 553 | health = POWER_SUPPLY_HEALTH_OVERHEAT; | ||
| 554 | else if (temp < info->pdata->min_temp) | ||
| 555 | health = POWER_SUPPLY_HEALTH_COLD; | ||
| 556 | else if (vocv < info->pdata->min_volt) | ||
| 557 | health = POWER_SUPPLY_HEALTH_DEAD; | ||
| 558 | else | ||
| 559 | health = POWER_SUPPLY_HEALTH_GOOD; | ||
| 560 | |||
| 561 | health_read_fail: | ||
| 562 | return health; | ||
| 563 | } | ||
| 564 | |||
| 565 | static int fuel_gauge_set_high_btemp_alert(struct axp288_fg_info *info) | ||
| 566 | { | ||
| 567 | int ret, adc_val; | ||
| 568 | |||
| 569 | /* program temperature threshold as 1/16 ADC value */ | ||
| 570 | adc_val = temp_to_adc(info, info->pdata->max_temp); | ||
| 571 | ret = fuel_gauge_reg_writeb(info, AXP20X_V_HTF_DISCHRG, adc_val >> 4); | ||
| 572 | |||
| 573 | return ret; | ||
| 574 | } | ||
| 575 | |||
| 576 | static int fuel_gauge_set_low_btemp_alert(struct axp288_fg_info *info) | ||
| 577 | { | ||
| 578 | int ret, adc_val; | ||
| 579 | |||
| 580 | /* program temperature threshold as 1/16 ADC value */ | ||
| 581 | adc_val = temp_to_adc(info, info->pdata->min_temp); | ||
| 582 | ret = fuel_gauge_reg_writeb(info, AXP20X_V_LTF_DISCHRG, adc_val >> 4); | ||
| 583 | |||
| 584 | return ret; | ||
| 585 | } | ||
| 586 | |||
| 587 | static int fuel_gauge_get_property(struct power_supply *ps, | ||
| 588 | enum power_supply_property prop, | ||
| 589 | union power_supply_propval *val) | ||
| 590 | { | ||
| 591 | struct axp288_fg_info *info = power_supply_get_drvdata(ps); | ||
| 592 | int ret = 0, value; | ||
| 593 | |||
| 594 | mutex_lock(&info->lock); | ||
| 595 | switch (prop) { | ||
| 596 | case POWER_SUPPLY_PROP_STATUS: | ||
| 597 | fuel_gauge_get_status(info); | ||
| 598 | val->intval = info->status; | ||
| 599 | break; | ||
| 600 | case POWER_SUPPLY_PROP_HEALTH: | ||
| 601 | val->intval = fuel_gauge_battery_health(info); | ||
| 602 | break; | ||
| 603 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 604 | ret = fuel_gauge_get_vbatt(info, &value); | ||
| 605 | if (ret < 0) | ||
| 606 | goto fuel_gauge_read_err; | ||
| 607 | val->intval = PROP_VOLT(value); | ||
| 608 | break; | ||
| 609 | case POWER_SUPPLY_PROP_VOLTAGE_OCV: | ||
| 610 | ret = fuel_gauge_get_vocv(info, &value); | ||
| 611 | if (ret < 0) | ||
| 612 | goto fuel_gauge_read_err; | ||
| 613 | val->intval = PROP_VOLT(value); | ||
| 614 | break; | ||
| 615 | case POWER_SUPPLY_PROP_CURRENT_NOW: | ||
| 616 | ret = fuel_gauge_get_current(info, &value); | ||
| 617 | if (ret < 0) | ||
| 618 | goto fuel_gauge_read_err; | ||
| 619 | val->intval = PROP_CURR(value); | ||
| 620 | break; | ||
| 621 | case POWER_SUPPLY_PROP_PRESENT: | ||
| 622 | ret = fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE); | ||
| 623 | if (ret < 0) | ||
| 624 | goto fuel_gauge_read_err; | ||
| 625 | |||
| 626 | if (ret & CHRG_STAT_BAT_PRESENT) | ||
| 627 | val->intval = 1; | ||
| 628 | else | ||
| 629 | val->intval = 0; | ||
| 630 | break; | ||
| 631 | case POWER_SUPPLY_PROP_CAPACITY: | ||
| 632 | ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); | ||
| 633 | if (ret < 0) | ||
| 634 | goto fuel_gauge_read_err; | ||
| 635 | |||
| 636 | if (!(ret & FG_REP_CAP_VALID)) | ||
| 637 | dev_err(&info->pdev->dev, | ||
| 638 | "capacity measurement not valid\n"); | ||
| 639 | val->intval = (ret & FG_REP_CAP_VAL_MASK); | ||
| 640 | break; | ||
| 641 | case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: | ||
| 642 | ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); | ||
| 643 | if (ret < 0) | ||
| 644 | goto fuel_gauge_read_err; | ||
| 645 | val->intval = (ret & 0x0f); | ||
| 646 | break; | ||
| 647 | case POWER_SUPPLY_PROP_TEMP: | ||
| 648 | ret = fuel_gauge_get_btemp(info, &value); | ||
| 649 | if (ret < 0) | ||
| 650 | goto fuel_gauge_read_err; | ||
| 651 | val->intval = PROP_TEMP(value); | ||
| 652 | break; | ||
| 653 | case POWER_SUPPLY_PROP_TEMP_MAX: | ||
| 654 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: | ||
| 655 | val->intval = PROP_TEMP(info->pdata->max_temp); | ||
| 656 | break; | ||
| 657 | case POWER_SUPPLY_PROP_TEMP_MIN: | ||
| 658 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: | ||
| 659 | val->intval = PROP_TEMP(info->pdata->min_temp); | ||
| 660 | break; | ||
| 661 | case POWER_SUPPLY_PROP_TECHNOLOGY: | ||
| 662 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; | ||
| 663 | break; | ||
| 664 | case POWER_SUPPLY_PROP_CHARGE_NOW: | ||
| 665 | ret = fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR1_REG); | ||
| 666 | if (ret < 0) | ||
| 667 | goto fuel_gauge_read_err; | ||
| 668 | |||
| 669 | value = (ret & FG_CC_MTR1_VAL_MASK) << 8; | ||
| 670 | ret = fuel_gauge_reg_readb(info, AXP288_FG_CC_MTR0_REG); | ||
| 671 | if (ret < 0) | ||
| 672 | goto fuel_gauge_read_err; | ||
| 673 | value |= (ret & FG_CC_MTR0_VAL_MASK); | ||
| 674 | val->intval = value * FG_DES_CAP_RES_LSB; | ||
| 675 | break; | ||
| 676 | case POWER_SUPPLY_PROP_CHARGE_FULL: | ||
| 677 | ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG); | ||
| 678 | if (ret < 0) | ||
| 679 | goto fuel_gauge_read_err; | ||
| 680 | |||
| 681 | value = (ret & FG_DES_CAP1_VAL_MASK) << 8; | ||
| 682 | ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP0_REG); | ||
| 683 | if (ret < 0) | ||
| 684 | goto fuel_gauge_read_err; | ||
| 685 | value |= (ret & FG_DES_CAP0_VAL_MASK); | ||
| 686 | val->intval = value * FG_DES_CAP_RES_LSB; | ||
| 687 | break; | ||
| 688 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | ||
| 689 | val->intval = PROP_CURR(info->pdata->design_cap); | ||
| 690 | break; | ||
| 691 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | ||
| 692 | val->intval = PROP_VOLT(info->pdata->max_volt); | ||
| 693 | break; | ||
| 694 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | ||
| 695 | val->intval = PROP_VOLT(info->pdata->min_volt); | ||
| 696 | break; | ||
| 697 | case POWER_SUPPLY_PROP_MODEL_NAME: | ||
| 698 | val->strval = info->pdata->battid; | ||
| 699 | break; | ||
| 700 | default: | ||
| 701 | mutex_unlock(&info->lock); | ||
| 702 | return -EINVAL; | ||
| 703 | } | ||
| 704 | |||
| 705 | mutex_unlock(&info->lock); | ||
| 706 | return 0; | ||
| 707 | |||
| 708 | fuel_gauge_read_err: | ||
| 709 | mutex_unlock(&info->lock); | ||
| 710 | return ret; | ||
| 711 | } | ||
| 712 | |||
| 713 | static int fuel_gauge_set_property(struct power_supply *ps, | ||
| 714 | enum power_supply_property prop, | ||
| 715 | const union power_supply_propval *val) | ||
| 716 | { | ||
| 717 | struct axp288_fg_info *info = power_supply_get_drvdata(ps); | ||
| 718 | int ret = 0; | ||
| 719 | |||
| 720 | mutex_lock(&info->lock); | ||
| 721 | switch (prop) { | ||
| 722 | case POWER_SUPPLY_PROP_STATUS: | ||
| 723 | info->status = val->intval; | ||
| 724 | break; | ||
| 725 | case POWER_SUPPLY_PROP_TEMP_MIN: | ||
| 726 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: | ||
| 727 | if ((val->intval < PD_DEF_MIN_TEMP) || | ||
| 728 | (val->intval > PD_DEF_MAX_TEMP)) { | ||
| 729 | ret = -EINVAL; | ||
| 730 | break; | ||
| 731 | } | ||
| 732 | info->pdata->min_temp = UNPROP_TEMP(val->intval); | ||
| 733 | ret = fuel_gauge_set_low_btemp_alert(info); | ||
| 734 | if (ret < 0) | ||
| 735 | dev_err(&info->pdev->dev, | ||
| 736 | "temp alert min set fail:%d\n", ret); | ||
| 737 | break; | ||
| 738 | case POWER_SUPPLY_PROP_TEMP_MAX: | ||
| 739 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: | ||
| 740 | if ((val->intval < PD_DEF_MIN_TEMP) || | ||
| 741 | (val->intval > PD_DEF_MAX_TEMP)) { | ||
| 742 | ret = -EINVAL; | ||
| 743 | break; | ||
| 744 | } | ||
| 745 | info->pdata->max_temp = UNPROP_TEMP(val->intval); | ||
| 746 | ret = fuel_gauge_set_high_btemp_alert(info); | ||
| 747 | if (ret < 0) | ||
| 748 | dev_err(&info->pdev->dev, | ||
| 749 | "temp alert max set fail:%d\n", ret); | ||
| 750 | break; | ||
| 751 | case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: | ||
| 752 | if ((val->intval < 0) || (val->intval > 15)) { | ||
| 753 | ret = -EINVAL; | ||
| 754 | break; | ||
| 755 | } | ||
| 756 | ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); | ||
| 757 | if (ret < 0) | ||
| 758 | break; | ||
| 759 | ret &= 0xf0; | ||
| 760 | ret |= (val->intval & 0xf); | ||
| 761 | ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, ret); | ||
| 762 | break; | ||
| 763 | default: | ||
| 764 | ret = -EINVAL; | ||
| 765 | break; | ||
| 766 | } | ||
| 767 | |||
| 768 | mutex_unlock(&info->lock); | ||
| 769 | return ret; | ||
| 770 | } | ||
| 771 | |||
| 772 | static int fuel_gauge_property_is_writeable(struct power_supply *psy, | ||
| 773 | enum power_supply_property psp) | ||
| 774 | { | ||
| 775 | int ret; | ||
| 776 | |||
| 777 | switch (psp) { | ||
| 778 | case POWER_SUPPLY_PROP_STATUS: | ||
| 779 | case POWER_SUPPLY_PROP_TEMP_MIN: | ||
| 780 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: | ||
| 781 | case POWER_SUPPLY_PROP_TEMP_MAX: | ||
| 782 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: | ||
| 783 | case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: | ||
| 784 | ret = 1; | ||
| 785 | break; | ||
| 786 | default: | ||
| 787 | ret = 0; | ||
| 788 | } | ||
| 789 | |||
| 790 | return ret; | ||
| 791 | } | ||
| 792 | |||
| 793 | static void fuel_gauge_status_monitor(struct work_struct *work) | ||
| 794 | { | ||
| 795 | struct axp288_fg_info *info = container_of(work, | ||
| 796 | struct axp288_fg_info, status_monitor.work); | ||
| 797 | |||
| 798 | fuel_gauge_get_status(info); | ||
| 799 | power_supply_changed(info->bat); | ||
| 800 | schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); | ||
| 801 | } | ||
| 802 | |||
| 803 | static irqreturn_t fuel_gauge_thread_handler(int irq, void *dev) | ||
| 804 | { | ||
| 805 | struct axp288_fg_info *info = dev; | ||
| 806 | int i; | ||
| 807 | |||
| 808 | for (i = 0; i < AXP288_FG_INTR_NUM; i++) { | ||
| 809 | if (info->irq[i] == irq) | ||
| 810 | break; | ||
| 811 | } | ||
| 812 | |||
| 813 | if (i >= AXP288_FG_INTR_NUM) { | ||
| 814 | dev_warn(&info->pdev->dev, "spurious interrupt!!\n"); | ||
| 815 | return IRQ_NONE; | ||
| 816 | } | ||
| 817 | |||
| 818 | switch (i) { | ||
| 819 | case QWBTU_IRQ: | ||
| 820 | dev_info(&info->pdev->dev, | ||
| 821 | "Quit Battery under temperature in work mode IRQ (QWBTU)\n"); | ||
| 822 | break; | ||
| 823 | case WBTU_IRQ: | ||
| 824 | dev_info(&info->pdev->dev, | ||
| 825 | "Battery under temperature in work mode IRQ (WBTU)\n"); | ||
| 826 | break; | ||
| 827 | case QWBTO_IRQ: | ||
| 828 | dev_info(&info->pdev->dev, | ||
| 829 | "Quit Battery over temperature in work mode IRQ (QWBTO)\n"); | ||
| 830 | break; | ||
| 831 | case WBTO_IRQ: | ||
| 832 | dev_info(&info->pdev->dev, | ||
| 833 | "Battery over temperature in work mode IRQ (WBTO)\n"); | ||
| 834 | break; | ||
| 835 | case WL2_IRQ: | ||
| 836 | dev_info(&info->pdev->dev, "Low Batt Warning(2) INTR\n"); | ||
| 837 | break; | ||
| 838 | case WL1_IRQ: | ||
| 839 | dev_info(&info->pdev->dev, "Low Batt Warning(1) INTR\n"); | ||
| 840 | break; | ||
| 841 | default: | ||
| 842 | dev_warn(&info->pdev->dev, "Spurious Interrupt!!!\n"); | ||
| 843 | } | ||
| 844 | |||
| 845 | power_supply_changed(info->bat); | ||
| 846 | return IRQ_HANDLED; | ||
| 847 | } | ||
| 848 | |||
| 849 | static void fuel_gauge_external_power_changed(struct power_supply *psy) | ||
| 850 | { | ||
| 851 | struct axp288_fg_info *info = power_supply_get_drvdata(psy); | ||
| 852 | |||
| 853 | power_supply_changed(info->bat); | ||
| 854 | } | ||
| 855 | |||
| 856 | static const struct power_supply_desc fuel_gauge_desc = { | ||
| 857 | .name = DEV_NAME, | ||
| 858 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 859 | .properties = fuel_gauge_props, | ||
| 860 | .num_properties = ARRAY_SIZE(fuel_gauge_props), | ||
| 861 | .get_property = fuel_gauge_get_property, | ||
| 862 | .set_property = fuel_gauge_set_property, | ||
| 863 | .property_is_writeable = fuel_gauge_property_is_writeable, | ||
| 864 | .external_power_changed = fuel_gauge_external_power_changed, | ||
| 865 | }; | ||
| 866 | |||
| 867 | static int fuel_gauge_set_lowbatt_thresholds(struct axp288_fg_info *info) | ||
| 868 | { | ||
| 869 | int ret; | ||
| 870 | u8 reg_val; | ||
| 871 | |||
| 872 | ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); | ||
| 873 | if (ret < 0) { | ||
| 874 | dev_err(&info->pdev->dev, "%s:read err:%d\n", __func__, ret); | ||
| 875 | return ret; | ||
| 876 | } | ||
| 877 | ret = (ret & FG_REP_CAP_VAL_MASK); | ||
| 878 | |||
| 879 | if (ret > FG_LOW_CAP_WARN_THR) | ||
| 880 | reg_val = FG_LOW_CAP_WARN_THR; | ||
| 881 | else if (ret > FG_LOW_CAP_CRIT_THR) | ||
| 882 | reg_val = FG_LOW_CAP_CRIT_THR; | ||
| 883 | else | ||
| 884 | reg_val = FG_LOW_CAP_SHDN_THR; | ||
| 885 | |||
| 886 | reg_val |= FG_LOW_CAP_THR1_VAL; | ||
| 887 | ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, reg_val); | ||
| 888 | if (ret < 0) | ||
| 889 | dev_err(&info->pdev->dev, "%s:write err:%d\n", __func__, ret); | ||
| 890 | |||
| 891 | return ret; | ||
| 892 | } | ||
| 893 | |||
| 894 | static int fuel_gauge_program_vbatt_full(struct axp288_fg_info *info) | ||
| 895 | { | ||
| 896 | int ret; | ||
| 897 | u8 val; | ||
| 898 | |||
| 899 | ret = fuel_gauge_reg_readb(info, AXP20X_CHRG_CTRL1); | ||
| 900 | if (ret < 0) | ||
| 901 | goto fg_prog_ocv_fail; | ||
| 902 | else | ||
| 903 | val = (ret & ~CHRG_CCCV_CV_MASK); | ||
| 904 | |||
| 905 | switch (info->pdata->max_volt) { | ||
| 906 | case CV_4100: | ||
| 907 | val |= (CHRG_CCCV_CV_4100MV << CHRG_CCCV_CV_BIT_POS); | ||
| 908 | break; | ||
| 909 | case CV_4150: | ||
| 910 | val |= (CHRG_CCCV_CV_4150MV << CHRG_CCCV_CV_BIT_POS); | ||
| 911 | break; | ||
| 912 | case CV_4200: | ||
| 913 | val |= (CHRG_CCCV_CV_4200MV << CHRG_CCCV_CV_BIT_POS); | ||
| 914 | break; | ||
| 915 | case CV_4350: | ||
| 916 | val |= (CHRG_CCCV_CV_4350MV << CHRG_CCCV_CV_BIT_POS); | ||
| 917 | break; | ||
| 918 | default: | ||
| 919 | val |= (CHRG_CCCV_CV_4200MV << CHRG_CCCV_CV_BIT_POS); | ||
| 920 | break; | ||
| 921 | } | ||
| 922 | |||
| 923 | ret = fuel_gauge_reg_writeb(info, AXP20X_CHRG_CTRL1, val); | ||
| 924 | fg_prog_ocv_fail: | ||
| 925 | return ret; | ||
| 926 | } | ||
| 927 | |||
| 928 | static int fuel_gauge_program_design_cap(struct axp288_fg_info *info) | ||
| 929 | { | ||
| 930 | int ret; | ||
| 931 | |||
| 932 | ret = fuel_gauge_reg_writeb(info, | ||
| 933 | AXP288_FG_DES_CAP1_REG, info->pdata->cap1); | ||
| 934 | if (ret < 0) | ||
| 935 | goto fg_prog_descap_fail; | ||
| 936 | |||
| 937 | ret = fuel_gauge_reg_writeb(info, | ||
| 938 | AXP288_FG_DES_CAP0_REG, info->pdata->cap0); | ||
| 939 | |||
| 940 | fg_prog_descap_fail: | ||
| 941 | return ret; | ||
| 942 | } | ||
| 943 | |||
| 944 | static int fuel_gauge_program_ocv_curve(struct axp288_fg_info *info) | ||
| 945 | { | ||
| 946 | int ret = 0, i; | ||
| 947 | |||
| 948 | for (i = 0; i < OCV_CURVE_SIZE; i++) { | ||
| 949 | ret = fuel_gauge_reg_writeb(info, | ||
| 950 | AXP288_FG_OCV_CURVE_REG + i, info->pdata->ocv_curve[i]); | ||
| 951 | if (ret < 0) | ||
| 952 | goto fg_prog_ocv_fail; | ||
| 953 | } | ||
| 954 | |||
| 955 | fg_prog_ocv_fail: | ||
| 956 | return ret; | ||
| 957 | } | ||
| 958 | |||
| 959 | static int fuel_gauge_program_rdc_vals(struct axp288_fg_info *info) | ||
| 960 | { | ||
| 961 | int ret; | ||
| 962 | |||
| 963 | ret = fuel_gauge_reg_writeb(info, | ||
| 964 | AXP288_FG_RDC1_REG, info->pdata->rdc1); | ||
| 965 | if (ret < 0) | ||
| 966 | goto fg_prog_ocv_fail; | ||
| 967 | |||
| 968 | ret = fuel_gauge_reg_writeb(info, | ||
| 969 | AXP288_FG_RDC0_REG, info->pdata->rdc0); | ||
| 970 | |||
| 971 | fg_prog_ocv_fail: | ||
| 972 | return ret; | ||
| 973 | } | ||
| 974 | |||
| 975 | static void fuel_gauge_init_config_regs(struct axp288_fg_info *info) | ||
| 976 | { | ||
| 977 | int ret; | ||
| 978 | |||
| 979 | /* | ||
| 980 | * check if the config data is already | ||
| 981 | * programmed and if so just return. | ||
| 982 | */ | ||
| 983 | |||
| 984 | ret = fuel_gauge_reg_readb(info, AXP288_FG_DES_CAP1_REG); | ||
| 985 | if (ret < 0) { | ||
| 986 | dev_warn(&info->pdev->dev, "CAP1 reg read err!!\n"); | ||
| 987 | } else if (!(ret & FG_DES_CAP1_VALID)) { | ||
| 988 | dev_info(&info->pdev->dev, "FG data needs to be initialized\n"); | ||
| 989 | } else { | ||
| 990 | dev_info(&info->pdev->dev, "FG data is already initialized\n"); | ||
| 991 | return; | ||
| 992 | } | ||
| 993 | |||
| 994 | ret = fuel_gauge_program_vbatt_full(info); | ||
| 995 | if (ret < 0) | ||
| 996 | dev_err(&info->pdev->dev, "set vbatt full fail:%d\n", ret); | ||
| 997 | |||
| 998 | ret = fuel_gauge_program_design_cap(info); | ||
| 999 | if (ret < 0) | ||
| 1000 | dev_err(&info->pdev->dev, "set design cap fail:%d\n", ret); | ||
| 1001 | |||
| 1002 | ret = fuel_gauge_program_rdc_vals(info); | ||
| 1003 | if (ret < 0) | ||
| 1004 | dev_err(&info->pdev->dev, "set rdc fail:%d\n", ret); | ||
| 1005 | |||
| 1006 | ret = fuel_gauge_program_ocv_curve(info); | ||
| 1007 | if (ret < 0) | ||
| 1008 | dev_err(&info->pdev->dev, "set ocv curve fail:%d\n", ret); | ||
| 1009 | |||
| 1010 | ret = fuel_gauge_set_lowbatt_thresholds(info); | ||
| 1011 | if (ret < 0) | ||
| 1012 | dev_err(&info->pdev->dev, "lowbatt thr set fail:%d\n", ret); | ||
| 1013 | |||
| 1014 | ret = fuel_gauge_reg_writeb(info, AXP20X_CC_CTRL, 0xef); | ||
| 1015 | if (ret < 0) | ||
| 1016 | dev_err(&info->pdev->dev, "gauge cntl set fail:%d\n", ret); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | static void fuel_gauge_init_irq(struct axp288_fg_info *info) | ||
| 1020 | { | ||
| 1021 | int ret, i, pirq; | ||
| 1022 | |||
| 1023 | for (i = 0; i < AXP288_FG_INTR_NUM; i++) { | ||
| 1024 | pirq = platform_get_irq(info->pdev, i); | ||
| 1025 | info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); | ||
| 1026 | if (info->irq[i] < 0) { | ||
| 1027 | dev_warn(&info->pdev->dev, | ||
| 1028 | "regmap_irq get virq failed for IRQ %d: %d\n", | ||
| 1029 | pirq, info->irq[i]); | ||
| 1030 | info->irq[i] = -1; | ||
| 1031 | goto intr_failed; | ||
| 1032 | } | ||
| 1033 | ret = request_threaded_irq(info->irq[i], | ||
| 1034 | NULL, fuel_gauge_thread_handler, | ||
| 1035 | IRQF_ONESHOT, DEV_NAME, info); | ||
| 1036 | if (ret) { | ||
| 1037 | dev_warn(&info->pdev->dev, | ||
| 1038 | "request irq failed for IRQ %d: %d\n", | ||
| 1039 | pirq, info->irq[i]); | ||
| 1040 | info->irq[i] = -1; | ||
| 1041 | goto intr_failed; | ||
| 1042 | } else { | ||
| 1043 | dev_info(&info->pdev->dev, "HW IRQ %d -> VIRQ %d\n", | ||
| 1044 | pirq, info->irq[i]); | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | return; | ||
| 1048 | |||
| 1049 | intr_failed: | ||
| 1050 | for (; i > 0; i--) { | ||
| 1051 | free_irq(info->irq[i - 1], info); | ||
| 1052 | info->irq[i - 1] = -1; | ||
| 1053 | } | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | static void fuel_gauge_init_hw_regs(struct axp288_fg_info *info) | ||
| 1057 | { | ||
| 1058 | int ret; | ||
| 1059 | unsigned int val; | ||
| 1060 | |||
| 1061 | ret = fuel_gauge_set_high_btemp_alert(info); | ||
| 1062 | if (ret < 0) | ||
| 1063 | dev_err(&info->pdev->dev, "high batt temp set fail:%d\n", ret); | ||
| 1064 | |||
| 1065 | ret = fuel_gauge_set_low_btemp_alert(info); | ||
| 1066 | if (ret < 0) | ||
| 1067 | dev_err(&info->pdev->dev, "low batt temp set fail:%d\n", ret); | ||
| 1068 | |||
| 1069 | /* enable interrupts */ | ||
| 1070 | val = fuel_gauge_reg_readb(info, AXP20X_IRQ3_EN); | ||
| 1071 | val |= TEMP_IRQ_CFG_MASK; | ||
| 1072 | fuel_gauge_reg_writeb(info, AXP20X_IRQ3_EN, val); | ||
| 1073 | |||
| 1074 | val = fuel_gauge_reg_readb(info, AXP20X_IRQ4_EN); | ||
| 1075 | val |= FG_IRQ_CFG_LOWBATT_MASK; | ||
| 1076 | val = fuel_gauge_reg_writeb(info, AXP20X_IRQ4_EN, val); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static int axp288_fuel_gauge_probe(struct platform_device *pdev) | ||
| 1080 | { | ||
| 1081 | int ret = 0; | ||
| 1082 | struct axp288_fg_info *info; | ||
| 1083 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); | ||
| 1084 | struct power_supply_config psy_cfg = {}; | ||
| 1085 | |||
| 1086 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
| 1087 | if (!info) | ||
| 1088 | return -ENOMEM; | ||
| 1089 | |||
| 1090 | info->pdev = pdev; | ||
| 1091 | info->regmap = axp20x->regmap; | ||
| 1092 | info->regmap_irqc = axp20x->regmap_irqc; | ||
| 1093 | info->status = POWER_SUPPLY_STATUS_UNKNOWN; | ||
| 1094 | info->pdata = pdev->dev.platform_data; | ||
| 1095 | if (!info->pdata) | ||
| 1096 | return -ENODEV; | ||
| 1097 | |||
| 1098 | platform_set_drvdata(pdev, info); | ||
| 1099 | |||
| 1100 | mutex_init(&info->lock); | ||
| 1101 | INIT_DELAYED_WORK(&info->status_monitor, fuel_gauge_status_monitor); | ||
| 1102 | |||
| 1103 | psy_cfg.drv_data = info; | ||
| 1104 | info->bat = power_supply_register(&pdev->dev, &fuel_gauge_desc, &psy_cfg); | ||
| 1105 | if (IS_ERR(info->bat)) { | ||
| 1106 | ret = PTR_ERR(info->bat); | ||
| 1107 | dev_err(&pdev->dev, "failed to register battery: %d\n", ret); | ||
| 1108 | return ret; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | fuel_gauge_create_debugfs(info); | ||
| 1112 | fuel_gauge_init_config_regs(info); | ||
| 1113 | fuel_gauge_init_irq(info); | ||
| 1114 | fuel_gauge_init_hw_regs(info); | ||
| 1115 | schedule_delayed_work(&info->status_monitor, STATUS_MON_DELAY_JIFFIES); | ||
| 1116 | |||
| 1117 | return ret; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | static struct platform_device_id axp288_fg_id_table[] = { | ||
| 1121 | { .name = DEV_NAME }, | ||
| 1122 | {}, | ||
| 1123 | }; | ||
| 1124 | |||
| 1125 | static int axp288_fuel_gauge_remove(struct platform_device *pdev) | ||
| 1126 | { | ||
| 1127 | struct axp288_fg_info *info = platform_get_drvdata(pdev); | ||
| 1128 | int i; | ||
| 1129 | |||
| 1130 | cancel_delayed_work_sync(&info->status_monitor); | ||
| 1131 | power_supply_unregister(info->bat); | ||
| 1132 | fuel_gauge_remove_debugfs(info); | ||
| 1133 | |||
| 1134 | for (i = 0; i < AXP288_FG_INTR_NUM; i++) | ||
| 1135 | if (info->irq[i] >= 0) | ||
| 1136 | free_irq(info->irq[i], info); | ||
| 1137 | |||
| 1138 | return 0; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | static struct platform_driver axp288_fuel_gauge_driver = { | ||
| 1142 | .probe = axp288_fuel_gauge_probe, | ||
| 1143 | .remove = axp288_fuel_gauge_remove, | ||
| 1144 | .id_table = axp288_fg_id_table, | ||
| 1145 | .driver = { | ||
| 1146 | .name = DEV_NAME, | ||
| 1147 | }, | ||
| 1148 | }; | ||
| 1149 | |||
| 1150 | module_platform_driver(axp288_fuel_gauge_driver); | ||
| 1151 | |||
| 1152 | MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>"); | ||
| 1153 | MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver"); | ||
| 1154 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index 1f49986fc605..6c534dcbc19c 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c | |||
| @@ -13,12 +13,6 @@ | |||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
| 15 | * | 15 | * |
| 16 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Datasheets: | 16 | * Datasheets: |
| 23 | * http://www.ti.com/product/bq24150 | 17 | * http://www.ti.com/product/bq24150 |
| 24 | * http://www.ti.com/product/bq24150a | 18 | * http://www.ti.com/product/bq24150a |
| @@ -26,6 +20,8 @@ | |||
| 26 | * http://www.ti.com/product/bq24153 | 20 | * http://www.ti.com/product/bq24153 |
| 27 | * http://www.ti.com/product/bq24153a | 21 | * http://www.ti.com/product/bq24153a |
| 28 | * http://www.ti.com/product/bq24155 | 22 | * http://www.ti.com/product/bq24155 |
| 23 | * http://www.ti.com/product/bq24157s | ||
| 24 | * http://www.ti.com/product/bq24158 | ||
| 29 | */ | 25 | */ |
| 30 | 26 | ||
| 31 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| @@ -147,6 +143,7 @@ enum bq2415x_chip { | |||
| 147 | BQ24155, | 143 | BQ24155, |
| 148 | BQ24156, | 144 | BQ24156, |
| 149 | BQ24156A, | 145 | BQ24156A, |
| 146 | BQ24157S, | ||
| 150 | BQ24158, | 147 | BQ24158, |
| 151 | }; | 148 | }; |
| 152 | 149 | ||
| @@ -162,18 +159,20 @@ static char *bq2415x_chip_name[] = { | |||
| 162 | "bq24155", | 159 | "bq24155", |
| 163 | "bq24156", | 160 | "bq24156", |
| 164 | "bq24156a", | 161 | "bq24156a", |
| 162 | "bq24157s", | ||
| 165 | "bq24158", | 163 | "bq24158", |
| 166 | }; | 164 | }; |
| 167 | 165 | ||
| 168 | struct bq2415x_device { | 166 | struct bq2415x_device { |
| 169 | struct device *dev; | 167 | struct device *dev; |
| 170 | struct bq2415x_platform_data init_data; | 168 | struct bq2415x_platform_data init_data; |
| 171 | struct power_supply charger; | 169 | struct power_supply *charger; |
| 170 | struct power_supply_desc charger_desc; | ||
| 172 | struct delayed_work work; | 171 | struct delayed_work work; |
| 173 | struct power_supply *notify_psy; | 172 | struct power_supply *notify_psy; |
| 174 | struct notifier_block nb; | 173 | struct notifier_block nb; |
| 175 | enum bq2415x_mode reported_mode;/* mode reported by hook function */ | 174 | enum bq2415x_mode reported_mode;/* mode reported by hook function */ |
| 176 | enum bq2415x_mode mode; /* current configured mode */ | 175 | enum bq2415x_mode mode; /* currently configured mode */ |
| 177 | enum bq2415x_chip chip; | 176 | enum bq2415x_chip chip; |
| 178 | const char *timer_error; | 177 | const char *timer_error; |
| 179 | char *model; | 178 | char *model; |
| @@ -352,8 +351,7 @@ static int bq2415x_exec_command(struct bq2415x_device *bq, | |||
| 352 | BQ2415X_BIT_CE); | 351 | BQ2415X_BIT_CE); |
| 353 | if (ret < 0) | 352 | if (ret < 0) |
| 354 | return ret; | 353 | return ret; |
| 355 | else | 354 | return ret > 0 ? 0 : 1; |
| 356 | return ret > 0 ? 0 : 1; | ||
| 357 | case BQ2415X_CHARGER_ENABLE: | 355 | case BQ2415X_CHARGER_ENABLE: |
| 358 | return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, | 356 | return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL, |
| 359 | 0, BQ2415X_BIT_CE); | 357 | 0, BQ2415X_BIT_CE); |
| @@ -426,20 +424,17 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) | |||
| 426 | case 0: | 424 | case 0: |
| 427 | if (bq->chip == BQ24151A) | 425 | if (bq->chip == BQ24151A) |
| 428 | return bq->chip; | 426 | return bq->chip; |
| 429 | else | 427 | return BQ24151; |
| 430 | return BQ24151; | ||
| 431 | case 1: | 428 | case 1: |
| 432 | if (bq->chip == BQ24150A || | 429 | if (bq->chip == BQ24150A || |
| 433 | bq->chip == BQ24152 || | 430 | bq->chip == BQ24152 || |
| 434 | bq->chip == BQ24155) | 431 | bq->chip == BQ24155) |
| 435 | return bq->chip; | 432 | return bq->chip; |
| 436 | else | 433 | return BQ24150; |
| 437 | return BQ24150; | ||
| 438 | case 2: | 434 | case 2: |
| 439 | if (bq->chip == BQ24153A) | 435 | if (bq->chip == BQ24153A) |
| 440 | return bq->chip; | 436 | return bq->chip; |
| 441 | else | 437 | return BQ24153; |
| 442 | return BQ24153; | ||
| 443 | default: | 438 | default: |
| 444 | return BQUNKNOWN; | 439 | return BQUNKNOWN; |
| 445 | } | 440 | } |
| @@ -450,9 +445,10 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq) | |||
| 450 | case 0: | 445 | case 0: |
| 451 | if (bq->chip == BQ24156A) | 446 | if (bq->chip == BQ24156A) |
| 452 | return bq->chip; | 447 | return bq->chip; |
| 453 | else | 448 | return BQ24156; |
| 454 | return BQ24156; | ||
| 455 | case 2: | 449 | case 2: |
| 450 | if (bq->chip == BQ24157S) | ||
| 451 | return bq->chip; | ||
| 456 | return BQ24158; | 452 | return BQ24158; |
| 457 | default: | 453 | default: |
| 458 | return BQUNKNOWN; | 454 | return BQUNKNOWN; |
| @@ -480,24 +476,22 @@ static int bq2415x_detect_revision(struct bq2415x_device *bq) | |||
| 480 | case BQ24152: | 476 | case BQ24152: |
| 481 | if (ret >= 0 && ret <= 3) | 477 | if (ret >= 0 && ret <= 3) |
| 482 | return ret; | 478 | return ret; |
| 483 | else | 479 | return -1; |
| 484 | return -1; | ||
| 485 | case BQ24153: | 480 | case BQ24153: |
| 486 | case BQ24153A: | 481 | case BQ24153A: |
| 487 | case BQ24156: | 482 | case BQ24156: |
| 488 | case BQ24156A: | 483 | case BQ24156A: |
| 484 | case BQ24157S: | ||
| 489 | case BQ24158: | 485 | case BQ24158: |
| 490 | if (ret == 3) | 486 | if (ret == 3) |
| 491 | return 0; | 487 | return 0; |
| 492 | else if (ret == 1) | 488 | else if (ret == 1) |
| 493 | return 1; | 489 | return 1; |
| 494 | else | 490 | return -1; |
| 495 | return -1; | ||
| 496 | case BQ24155: | 491 | case BQ24155: |
| 497 | if (ret == 3) | 492 | if (ret == 3) |
| 498 | return 3; | 493 | return 3; |
| 499 | else | 494 | return -1; |
| 500 | return -1; | ||
| 501 | case BQUNKNOWN: | 495 | case BQUNKNOWN: |
| 502 | return -1; | 496 | return -1; |
| 503 | } | 497 | } |
| @@ -791,7 +785,7 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) | |||
| 791 | bq2415x_set_default_value(bq, battery_regulation_voltage); | 785 | bq2415x_set_default_value(bq, battery_regulation_voltage); |
| 792 | 786 | ||
| 793 | bq->mode = mode; | 787 | bq->mode = mode; |
| 794 | sysfs_notify(&bq->charger.dev->kobj, NULL, "mode"); | 788 | sysfs_notify(&bq->charger->dev.kobj, NULL, "mode"); |
| 795 | 789 | ||
| 796 | return 0; | 790 | return 0; |
| 797 | 791 | ||
| @@ -816,7 +810,8 @@ static int bq2415x_notifier_call(struct notifier_block *nb, | |||
| 816 | 810 | ||
| 817 | dev_dbg(bq->dev, "notifier call was called\n"); | 811 | dev_dbg(bq->dev, "notifier call was called\n"); |
| 818 | 812 | ||
| 819 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop); | 813 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, |
| 814 | &prop); | ||
| 820 | if (ret != 0) | 815 | if (ret != 0) |
| 821 | return NOTIFY_OK; | 816 | return NOTIFY_OK; |
| 822 | 817 | ||
| @@ -874,7 +869,7 @@ static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state) | |||
| 874 | static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg) | 869 | static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg) |
| 875 | { | 870 | { |
| 876 | bq->timer_error = msg; | 871 | bq->timer_error = msg; |
| 877 | sysfs_notify(&bq->charger.dev->kobj, NULL, "timer"); | 872 | sysfs_notify(&bq->charger->dev.kobj, NULL, "timer"); |
| 878 | dev_err(bq->dev, "%s\n", msg); | 873 | dev_err(bq->dev, "%s\n", msg); |
| 879 | if (bq->automode > 0) | 874 | if (bq->automode > 0) |
| 880 | bq->automode = 0; | 875 | bq->automode = 0; |
| @@ -892,7 +887,7 @@ static void bq2415x_timer_work(struct work_struct *work) | |||
| 892 | int boost; | 887 | int boost; |
| 893 | 888 | ||
| 894 | if (bq->automode > 0 && (bq->reported_mode != bq->mode)) { | 889 | if (bq->automode > 0 && (bq->reported_mode != bq->mode)) { |
| 895 | sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); | 890 | sysfs_notify(&bq->charger->dev.kobj, NULL, "reported_mode"); |
| 896 | bq2415x_set_mode(bq, bq->reported_mode); | 891 | bq2415x_set_mode(bq, bq->reported_mode); |
| 897 | } | 892 | } |
| 898 | 893 | ||
| @@ -998,8 +993,7 @@ static int bq2415x_power_supply_get_property(struct power_supply *psy, | |||
| 998 | enum power_supply_property psp, | 993 | enum power_supply_property psp, |
| 999 | union power_supply_propval *val) | 994 | union power_supply_propval *val) |
| 1000 | { | 995 | { |
| 1001 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 996 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1002 | charger); | ||
| 1003 | int ret; | 997 | int ret; |
| 1004 | 998 | ||
| 1005 | switch (psp) { | 999 | switch (psp) { |
| @@ -1030,12 +1024,14 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq) | |||
| 1030 | int ret; | 1024 | int ret; |
| 1031 | int chip; | 1025 | int chip; |
| 1032 | char revstr[8]; | 1026 | char revstr[8]; |
| 1027 | struct power_supply_config psy_cfg = { .drv_data = bq, }; | ||
| 1033 | 1028 | ||
| 1034 | bq->charger.name = bq->name; | 1029 | bq->charger_desc.name = bq->name; |
| 1035 | bq->charger.type = POWER_SUPPLY_TYPE_USB; | 1030 | bq->charger_desc.type = POWER_SUPPLY_TYPE_USB; |
| 1036 | bq->charger.properties = bq2415x_power_supply_props; | 1031 | bq->charger_desc.properties = bq2415x_power_supply_props; |
| 1037 | bq->charger.num_properties = ARRAY_SIZE(bq2415x_power_supply_props); | 1032 | bq->charger_desc.num_properties = |
| 1038 | bq->charger.get_property = bq2415x_power_supply_get_property; | 1033 | ARRAY_SIZE(bq2415x_power_supply_props); |
| 1034 | bq->charger_desc.get_property = bq2415x_power_supply_get_property; | ||
| 1039 | 1035 | ||
| 1040 | ret = bq2415x_detect_chip(bq); | 1036 | ret = bq2415x_detect_chip(bq); |
| 1041 | if (ret < 0) | 1037 | if (ret < 0) |
| @@ -1058,10 +1054,11 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq) | |||
| 1058 | return -ENOMEM; | 1054 | return -ENOMEM; |
| 1059 | } | 1055 | } |
| 1060 | 1056 | ||
| 1061 | ret = power_supply_register(bq->dev, &bq->charger); | 1057 | bq->charger = power_supply_register(bq->dev, &bq->charger_desc, |
| 1062 | if (ret) { | 1058 | &psy_cfg); |
| 1059 | if (IS_ERR(bq->charger)) { | ||
| 1063 | kfree(bq->model); | 1060 | kfree(bq->model); |
| 1064 | return ret; | 1061 | return PTR_ERR(bq->charger); |
| 1065 | } | 1062 | } |
| 1066 | 1063 | ||
| 1067 | return 0; | 1064 | return 0; |
| @@ -1073,7 +1070,7 @@ static void bq2415x_power_supply_exit(struct bq2415x_device *bq) | |||
| 1073 | if (bq->automode > 0) | 1070 | if (bq->automode > 0) |
| 1074 | bq->automode = 0; | 1071 | bq->automode = 0; |
| 1075 | cancel_delayed_work_sync(&bq->work); | 1072 | cancel_delayed_work_sync(&bq->work); |
| 1076 | power_supply_unregister(&bq->charger); | 1073 | power_supply_unregister(bq->charger); |
| 1077 | kfree(bq->model); | 1074 | kfree(bq->model); |
| 1078 | } | 1075 | } |
| 1079 | 1076 | ||
| @@ -1085,8 +1082,7 @@ static ssize_t bq2415x_sysfs_show_status(struct device *dev, | |||
| 1085 | char *buf) | 1082 | char *buf) |
| 1086 | { | 1083 | { |
| 1087 | struct power_supply *psy = dev_get_drvdata(dev); | 1084 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1088 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1085 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1089 | charger); | ||
| 1090 | enum bq2415x_command command; | 1086 | enum bq2415x_command command; |
| 1091 | int ret; | 1087 | int ret; |
| 1092 | 1088 | ||
| @@ -1119,8 +1115,7 @@ static ssize_t bq2415x_sysfs_set_timer(struct device *dev, | |||
| 1119 | size_t count) | 1115 | size_t count) |
| 1120 | { | 1116 | { |
| 1121 | struct power_supply *psy = dev_get_drvdata(dev); | 1117 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1122 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1118 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1123 | charger); | ||
| 1124 | int ret = 0; | 1119 | int ret = 0; |
| 1125 | 1120 | ||
| 1126 | if (strncmp(buf, "auto", 4) == 0) | 1121 | if (strncmp(buf, "auto", 4) == 0) |
| @@ -1141,8 +1136,7 @@ static ssize_t bq2415x_sysfs_show_timer(struct device *dev, | |||
| 1141 | char *buf) | 1136 | char *buf) |
| 1142 | { | 1137 | { |
| 1143 | struct power_supply *psy = dev_get_drvdata(dev); | 1138 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1144 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1139 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1145 | charger); | ||
| 1146 | 1140 | ||
| 1147 | if (bq->timer_error) | 1141 | if (bq->timer_error) |
| 1148 | return sprintf(buf, "%s\n", bq->timer_error); | 1142 | return sprintf(buf, "%s\n", bq->timer_error); |
| @@ -1166,8 +1160,7 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev, | |||
| 1166 | size_t count) | 1160 | size_t count) |
| 1167 | { | 1161 | { |
| 1168 | struct power_supply *psy = dev_get_drvdata(dev); | 1162 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1169 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1163 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1170 | charger); | ||
| 1171 | enum bq2415x_mode mode; | 1164 | enum bq2415x_mode mode; |
| 1172 | int ret = 0; | 1165 | int ret = 0; |
| 1173 | 1166 | ||
| @@ -1219,8 +1212,7 @@ static ssize_t bq2415x_sysfs_show_mode(struct device *dev, | |||
| 1219 | char *buf) | 1212 | char *buf) |
| 1220 | { | 1213 | { |
| 1221 | struct power_supply *psy = dev_get_drvdata(dev); | 1214 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1222 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1215 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1223 | charger); | ||
| 1224 | ssize_t ret = 0; | 1216 | ssize_t ret = 0; |
| 1225 | 1217 | ||
| 1226 | if (bq->automode > 0) | 1218 | if (bq->automode > 0) |
| @@ -1257,8 +1249,7 @@ static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev, | |||
| 1257 | char *buf) | 1249 | char *buf) |
| 1258 | { | 1250 | { |
| 1259 | struct power_supply *psy = dev_get_drvdata(dev); | 1251 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1260 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1252 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1261 | charger); | ||
| 1262 | 1253 | ||
| 1263 | if (bq->automode < 0) | 1254 | if (bq->automode < 0) |
| 1264 | return -EINVAL; | 1255 | return -EINVAL; |
| @@ -1286,8 +1277,7 @@ static ssize_t bq2415x_sysfs_set_registers(struct device *dev, | |||
| 1286 | size_t count) | 1277 | size_t count) |
| 1287 | { | 1278 | { |
| 1288 | struct power_supply *psy = dev_get_drvdata(dev); | 1279 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1289 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1280 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1290 | charger); | ||
| 1291 | ssize_t ret = 0; | 1281 | ssize_t ret = 0; |
| 1292 | unsigned int reg; | 1282 | unsigned int reg; |
| 1293 | unsigned int val; | 1283 | unsigned int val; |
| @@ -1322,8 +1312,7 @@ static ssize_t bq2415x_sysfs_show_registers(struct device *dev, | |||
| 1322 | char *buf) | 1312 | char *buf) |
| 1323 | { | 1313 | { |
| 1324 | struct power_supply *psy = dev_get_drvdata(dev); | 1314 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1325 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1315 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1326 | charger); | ||
| 1327 | ssize_t ret = 0; | 1316 | ssize_t ret = 0; |
| 1328 | 1317 | ||
| 1329 | ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_STATUS, buf+ret); | 1318 | ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_STATUS, buf+ret); |
| @@ -1341,8 +1330,7 @@ static ssize_t bq2415x_sysfs_set_limit(struct device *dev, | |||
| 1341 | size_t count) | 1330 | size_t count) |
| 1342 | { | 1331 | { |
| 1343 | struct power_supply *psy = dev_get_drvdata(dev); | 1332 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1344 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1333 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1345 | charger); | ||
| 1346 | long val; | 1334 | long val; |
| 1347 | int ret; | 1335 | int ret; |
| 1348 | 1336 | ||
| @@ -1373,8 +1361,7 @@ static ssize_t bq2415x_sysfs_show_limit(struct device *dev, | |||
| 1373 | char *buf) | 1361 | char *buf) |
| 1374 | { | 1362 | { |
| 1375 | struct power_supply *psy = dev_get_drvdata(dev); | 1363 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1376 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1364 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1377 | charger); | ||
| 1378 | int ret; | 1365 | int ret; |
| 1379 | 1366 | ||
| 1380 | if (strcmp(attr->attr.name, "current_limit") == 0) | 1367 | if (strcmp(attr->attr.name, "current_limit") == 0) |
| @@ -1402,8 +1389,7 @@ static ssize_t bq2415x_sysfs_set_enable(struct device *dev, | |||
| 1402 | size_t count) | 1389 | size_t count) |
| 1403 | { | 1390 | { |
| 1404 | struct power_supply *psy = dev_get_drvdata(dev); | 1391 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1405 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1392 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1406 | charger); | ||
| 1407 | enum bq2415x_command command; | 1393 | enum bq2415x_command command; |
| 1408 | long val; | 1394 | long val; |
| 1409 | int ret; | 1395 | int ret; |
| @@ -1438,8 +1424,7 @@ static ssize_t bq2415x_sysfs_show_enable(struct device *dev, | |||
| 1438 | char *buf) | 1424 | char *buf) |
| 1439 | { | 1425 | { |
| 1440 | struct power_supply *psy = dev_get_drvdata(dev); | 1426 | struct power_supply *psy = dev_get_drvdata(dev); |
| 1441 | struct bq2415x_device *bq = container_of(psy, struct bq2415x_device, | 1427 | struct bq2415x_device *bq = power_supply_get_drvdata(psy); |
| 1442 | charger); | ||
| 1443 | enum bq2415x_command command; | 1428 | enum bq2415x_command command; |
| 1444 | int ret; | 1429 | int ret; |
| 1445 | 1430 | ||
| @@ -1530,13 +1515,13 @@ static const struct attribute_group bq2415x_sysfs_attr_group = { | |||
| 1530 | 1515 | ||
| 1531 | static int bq2415x_sysfs_init(struct bq2415x_device *bq) | 1516 | static int bq2415x_sysfs_init(struct bq2415x_device *bq) |
| 1532 | { | 1517 | { |
| 1533 | return sysfs_create_group(&bq->charger.dev->kobj, | 1518 | return sysfs_create_group(&bq->charger->dev.kobj, |
| 1534 | &bq2415x_sysfs_attr_group); | 1519 | &bq2415x_sysfs_attr_group); |
| 1535 | } | 1520 | } |
| 1536 | 1521 | ||
| 1537 | static void bq2415x_sysfs_exit(struct bq2415x_device *bq) | 1522 | static void bq2415x_sysfs_exit(struct bq2415x_device *bq) |
| 1538 | { | 1523 | { |
| 1539 | sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group); | 1524 | sysfs_remove_group(&bq->charger->dev.kobj, &bq2415x_sysfs_attr_group); |
| 1540 | } | 1525 | } |
| 1541 | 1526 | ||
| 1542 | /* main bq2415x probe function */ | 1527 | /* main bq2415x probe function */ |
| @@ -1609,27 +1594,27 @@ static int bq2415x_probe(struct i2c_client *client, | |||
| 1609 | ret = of_property_read_u32(np, "ti,current-limit", | 1594 | ret = of_property_read_u32(np, "ti,current-limit", |
| 1610 | &bq->init_data.current_limit); | 1595 | &bq->init_data.current_limit); |
| 1611 | if (ret) | 1596 | if (ret) |
| 1612 | goto error_2; | 1597 | goto error_3; |
| 1613 | ret = of_property_read_u32(np, "ti,weak-battery-voltage", | 1598 | ret = of_property_read_u32(np, "ti,weak-battery-voltage", |
| 1614 | &bq->init_data.weak_battery_voltage); | 1599 | &bq->init_data.weak_battery_voltage); |
| 1615 | if (ret) | 1600 | if (ret) |
| 1616 | goto error_2; | 1601 | goto error_3; |
| 1617 | ret = of_property_read_u32(np, "ti,battery-regulation-voltage", | 1602 | ret = of_property_read_u32(np, "ti,battery-regulation-voltage", |
| 1618 | &bq->init_data.battery_regulation_voltage); | 1603 | &bq->init_data.battery_regulation_voltage); |
| 1619 | if (ret) | 1604 | if (ret) |
| 1620 | goto error_2; | 1605 | goto error_3; |
| 1621 | ret = of_property_read_u32(np, "ti,charge-current", | 1606 | ret = of_property_read_u32(np, "ti,charge-current", |
| 1622 | &bq->init_data.charge_current); | 1607 | &bq->init_data.charge_current); |
| 1623 | if (ret) | 1608 | if (ret) |
| 1624 | goto error_2; | 1609 | goto error_3; |
| 1625 | ret = of_property_read_u32(np, "ti,termination-current", | 1610 | ret = of_property_read_u32(np, "ti,termination-current", |
| 1626 | &bq->init_data.termination_current); | 1611 | &bq->init_data.termination_current); |
| 1627 | if (ret) | 1612 | if (ret) |
| 1628 | goto error_2; | 1613 | goto error_3; |
| 1629 | ret = of_property_read_u32(np, "ti,resistor-sense", | 1614 | ret = of_property_read_u32(np, "ti,resistor-sense", |
| 1630 | &bq->init_data.resistor_sense); | 1615 | &bq->init_data.resistor_sense); |
| 1631 | if (ret) | 1616 | if (ret) |
| 1632 | goto error_2; | 1617 | goto error_3; |
| 1633 | } else { | 1618 | } else { |
| 1634 | memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); | 1619 | memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); |
| 1635 | } | 1620 | } |
| @@ -1639,19 +1624,19 @@ static int bq2415x_probe(struct i2c_client *client, | |||
| 1639 | ret = bq2415x_power_supply_init(bq); | 1624 | ret = bq2415x_power_supply_init(bq); |
| 1640 | if (ret) { | 1625 | if (ret) { |
| 1641 | dev_err(bq->dev, "failed to register power supply: %d\n", ret); | 1626 | dev_err(bq->dev, "failed to register power supply: %d\n", ret); |
| 1642 | goto error_2; | 1627 | goto error_3; |
| 1643 | } | 1628 | } |
| 1644 | 1629 | ||
| 1645 | ret = bq2415x_sysfs_init(bq); | 1630 | ret = bq2415x_sysfs_init(bq); |
| 1646 | if (ret) { | 1631 | if (ret) { |
| 1647 | dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); | 1632 | dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); |
| 1648 | goto error_3; | 1633 | goto error_4; |
| 1649 | } | 1634 | } |
| 1650 | 1635 | ||
| 1651 | ret = bq2415x_set_defaults(bq); | 1636 | ret = bq2415x_set_defaults(bq); |
| 1652 | if (ret) { | 1637 | if (ret) { |
| 1653 | dev_err(bq->dev, "failed to set default values: %d\n", ret); | 1638 | dev_err(bq->dev, "failed to set default values: %d\n", ret); |
| 1654 | goto error_4; | 1639 | goto error_5; |
| 1655 | } | 1640 | } |
| 1656 | 1641 | ||
| 1657 | if (bq->notify_psy) { | 1642 | if (bq->notify_psy) { |
| @@ -1659,7 +1644,7 @@ static int bq2415x_probe(struct i2c_client *client, | |||
| 1659 | ret = power_supply_reg_notifier(&bq->nb); | 1644 | ret = power_supply_reg_notifier(&bq->nb); |
| 1660 | if (ret) { | 1645 | if (ret) { |
| 1661 | dev_err(bq->dev, "failed to reg notifier: %d\n", ret); | 1646 | dev_err(bq->dev, "failed to reg notifier: %d\n", ret); |
| 1662 | goto error_5; | 1647 | goto error_6; |
| 1663 | } | 1648 | } |
| 1664 | 1649 | ||
| 1665 | /* Query for initial reported_mode and set it */ | 1650 | /* Query for initial reported_mode and set it */ |
| @@ -1679,11 +1664,14 @@ static int bq2415x_probe(struct i2c_client *client, | |||
| 1679 | dev_info(bq->dev, "driver registered\n"); | 1664 | dev_info(bq->dev, "driver registered\n"); |
| 1680 | return 0; | 1665 | return 0; |
| 1681 | 1666 | ||
| 1667 | error_6: | ||
| 1682 | error_5: | 1668 | error_5: |
| 1683 | error_4: | ||
| 1684 | bq2415x_sysfs_exit(bq); | 1669 | bq2415x_sysfs_exit(bq); |
| 1685 | error_3: | 1670 | error_4: |
| 1686 | bq2415x_power_supply_exit(bq); | 1671 | bq2415x_power_supply_exit(bq); |
| 1672 | error_3: | ||
| 1673 | if (bq->notify_psy) | ||
| 1674 | power_supply_put(bq->notify_psy); | ||
| 1687 | error_2: | 1675 | error_2: |
| 1688 | kfree(name); | 1676 | kfree(name); |
| 1689 | error_1: | 1677 | error_1: |
| @@ -1700,8 +1688,10 @@ static int bq2415x_remove(struct i2c_client *client) | |||
| 1700 | { | 1688 | { |
| 1701 | struct bq2415x_device *bq = i2c_get_clientdata(client); | 1689 | struct bq2415x_device *bq = i2c_get_clientdata(client); |
| 1702 | 1690 | ||
| 1703 | if (bq->notify_psy) | 1691 | if (bq->notify_psy) { |
| 1704 | power_supply_unreg_notifier(&bq->nb); | 1692 | power_supply_unreg_notifier(&bq->nb); |
| 1693 | power_supply_put(bq->notify_psy); | ||
| 1694 | } | ||
| 1705 | 1695 | ||
| 1706 | bq2415x_sysfs_exit(bq); | 1696 | bq2415x_sysfs_exit(bq); |
| 1707 | bq2415x_power_supply_exit(bq); | 1697 | bq2415x_power_supply_exit(bq); |
| @@ -1731,6 +1721,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = { | |||
| 1731 | { "bq24155", BQ24155 }, | 1721 | { "bq24155", BQ24155 }, |
| 1732 | { "bq24156", BQ24156 }, | 1722 | { "bq24156", BQ24156 }, |
| 1733 | { "bq24156a", BQ24156A }, | 1723 | { "bq24156a", BQ24156A }, |
| 1724 | { "bq24157s", BQ24157S }, | ||
| 1734 | { "bq24158", BQ24158 }, | 1725 | { "bq24158", BQ24158 }, |
| 1735 | {}, | 1726 | {}, |
| 1736 | }; | 1727 | }; |
diff --git a/drivers/power/bq24190_charger.c b/drivers/power/bq24190_charger.c index d0e8236a6404..407c4af83891 100644 --- a/drivers/power/bq24190_charger.c +++ b/drivers/power/bq24190_charger.c | |||
| @@ -152,8 +152,8 @@ | |||
| 152 | struct bq24190_dev_info { | 152 | struct bq24190_dev_info { |
| 153 | struct i2c_client *client; | 153 | struct i2c_client *client; |
| 154 | struct device *dev; | 154 | struct device *dev; |
| 155 | struct power_supply charger; | 155 | struct power_supply *charger; |
| 156 | struct power_supply battery; | 156 | struct power_supply *battery; |
| 157 | char model_name[I2C_NAME_SIZE]; | 157 | char model_name[I2C_NAME_SIZE]; |
| 158 | kernel_ulong_t model; | 158 | kernel_ulong_t model; |
| 159 | unsigned int gpio_int; | 159 | unsigned int gpio_int; |
| @@ -423,8 +423,7 @@ static ssize_t bq24190_sysfs_show(struct device *dev, | |||
| 423 | struct device_attribute *attr, char *buf) | 423 | struct device_attribute *attr, char *buf) |
| 424 | { | 424 | { |
| 425 | struct power_supply *psy = dev_get_drvdata(dev); | 425 | struct power_supply *psy = dev_get_drvdata(dev); |
| 426 | struct bq24190_dev_info *bdi = | 426 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 427 | container_of(psy, struct bq24190_dev_info, charger); | ||
| 428 | struct bq24190_sysfs_field_info *info; | 427 | struct bq24190_sysfs_field_info *info; |
| 429 | int ret; | 428 | int ret; |
| 430 | u8 v; | 429 | u8 v; |
| @@ -444,8 +443,7 @@ static ssize_t bq24190_sysfs_store(struct device *dev, | |||
| 444 | struct device_attribute *attr, const char *buf, size_t count) | 443 | struct device_attribute *attr, const char *buf, size_t count) |
| 445 | { | 444 | { |
| 446 | struct power_supply *psy = dev_get_drvdata(dev); | 445 | struct power_supply *psy = dev_get_drvdata(dev); |
| 447 | struct bq24190_dev_info *bdi = | 446 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 448 | container_of(psy, struct bq24190_dev_info, charger); | ||
| 449 | struct bq24190_sysfs_field_info *info; | 447 | struct bq24190_sysfs_field_info *info; |
| 450 | int ret; | 448 | int ret; |
| 451 | u8 v; | 449 | u8 v; |
| @@ -469,13 +467,13 @@ static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) | |||
| 469 | { | 467 | { |
| 470 | bq24190_sysfs_init_attrs(); | 468 | bq24190_sysfs_init_attrs(); |
| 471 | 469 | ||
| 472 | return sysfs_create_group(&bdi->charger.dev->kobj, | 470 | return sysfs_create_group(&bdi->charger->dev.kobj, |
| 473 | &bq24190_sysfs_attr_group); | 471 | &bq24190_sysfs_attr_group); |
| 474 | } | 472 | } |
| 475 | 473 | ||
| 476 | static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) | 474 | static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) |
| 477 | { | 475 | { |
| 478 | sysfs_remove_group(&bdi->charger.dev->kobj, &bq24190_sysfs_attr_group); | 476 | sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group); |
| 479 | } | 477 | } |
| 480 | #else | 478 | #else |
| 481 | static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) | 479 | static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) |
| @@ -807,8 +805,7 @@ static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi, | |||
| 807 | static int bq24190_charger_get_property(struct power_supply *psy, | 805 | static int bq24190_charger_get_property(struct power_supply *psy, |
| 808 | enum power_supply_property psp, union power_supply_propval *val) | 806 | enum power_supply_property psp, union power_supply_propval *val) |
| 809 | { | 807 | { |
| 810 | struct bq24190_dev_info *bdi = | 808 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 811 | container_of(psy, struct bq24190_dev_info, charger); | ||
| 812 | int ret; | 809 | int ret; |
| 813 | 810 | ||
| 814 | dev_dbg(bdi->dev, "prop: %d\n", psp); | 811 | dev_dbg(bdi->dev, "prop: %d\n", psp); |
| @@ -861,8 +858,7 @@ static int bq24190_charger_set_property(struct power_supply *psy, | |||
| 861 | enum power_supply_property psp, | 858 | enum power_supply_property psp, |
| 862 | const union power_supply_propval *val) | 859 | const union power_supply_propval *val) |
| 863 | { | 860 | { |
| 864 | struct bq24190_dev_info *bdi = | 861 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 865 | container_of(psy, struct bq24190_dev_info, charger); | ||
| 866 | int ret; | 862 | int ret; |
| 867 | 863 | ||
| 868 | dev_dbg(bdi->dev, "prop: %d\n", psp); | 864 | dev_dbg(bdi->dev, "prop: %d\n", psp); |
| @@ -922,18 +918,15 @@ static char *bq24190_charger_supplied_to[] = { | |||
| 922 | "main-battery", | 918 | "main-battery", |
| 923 | }; | 919 | }; |
| 924 | 920 | ||
| 925 | static void bq24190_charger_init(struct power_supply *charger) | 921 | static const struct power_supply_desc bq24190_charger_desc = { |
| 926 | { | 922 | .name = "bq24190-charger", |
| 927 | charger->name = "bq24190-charger"; | 923 | .type = POWER_SUPPLY_TYPE_USB, |
| 928 | charger->type = POWER_SUPPLY_TYPE_USB; | 924 | .properties = bq24190_charger_properties, |
| 929 | charger->properties = bq24190_charger_properties; | 925 | .num_properties = ARRAY_SIZE(bq24190_charger_properties), |
| 930 | charger->num_properties = ARRAY_SIZE(bq24190_charger_properties); | 926 | .get_property = bq24190_charger_get_property, |
| 931 | charger->supplied_to = bq24190_charger_supplied_to; | 927 | .set_property = bq24190_charger_set_property, |
| 932 | charger->num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to); | 928 | .property_is_writeable = bq24190_charger_property_is_writeable, |
| 933 | charger->get_property = bq24190_charger_get_property; | 929 | }; |
| 934 | charger->set_property = bq24190_charger_set_property; | ||
| 935 | charger->property_is_writeable = bq24190_charger_property_is_writeable; | ||
| 936 | } | ||
| 937 | 930 | ||
| 938 | /* Battery power supply property routines */ | 931 | /* Battery power supply property routines */ |
| 939 | 932 | ||
| @@ -1102,8 +1095,7 @@ static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi, | |||
| 1102 | static int bq24190_battery_get_property(struct power_supply *psy, | 1095 | static int bq24190_battery_get_property(struct power_supply *psy, |
| 1103 | enum power_supply_property psp, union power_supply_propval *val) | 1096 | enum power_supply_property psp, union power_supply_propval *val) |
| 1104 | { | 1097 | { |
| 1105 | struct bq24190_dev_info *bdi = | 1098 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 1106 | container_of(psy, struct bq24190_dev_info, battery); | ||
| 1107 | int ret; | 1099 | int ret; |
| 1108 | 1100 | ||
| 1109 | dev_dbg(bdi->dev, "prop: %d\n", psp); | 1101 | dev_dbg(bdi->dev, "prop: %d\n", psp); |
| @@ -1144,8 +1136,7 @@ static int bq24190_battery_set_property(struct power_supply *psy, | |||
| 1144 | enum power_supply_property psp, | 1136 | enum power_supply_property psp, |
| 1145 | const union power_supply_propval *val) | 1137 | const union power_supply_propval *val) |
| 1146 | { | 1138 | { |
| 1147 | struct bq24190_dev_info *bdi = | 1139 | struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); |
| 1148 | container_of(psy, struct bq24190_dev_info, battery); | ||
| 1149 | int ret; | 1140 | int ret; |
| 1150 | 1141 | ||
| 1151 | dev_dbg(bdi->dev, "prop: %d\n", psp); | 1142 | dev_dbg(bdi->dev, "prop: %d\n", psp); |
| @@ -1193,16 +1184,15 @@ static enum power_supply_property bq24190_battery_properties[] = { | |||
| 1193 | POWER_SUPPLY_PROP_SCOPE, | 1184 | POWER_SUPPLY_PROP_SCOPE, |
| 1194 | }; | 1185 | }; |
| 1195 | 1186 | ||
| 1196 | static void bq24190_battery_init(struct power_supply *battery) | 1187 | static const struct power_supply_desc bq24190_battery_desc = { |
| 1197 | { | 1188 | .name = "bq24190-battery", |
| 1198 | battery->name = "bq24190-battery"; | 1189 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 1199 | battery->type = POWER_SUPPLY_TYPE_BATTERY; | 1190 | .properties = bq24190_battery_properties, |
| 1200 | battery->properties = bq24190_battery_properties; | 1191 | .num_properties = ARRAY_SIZE(bq24190_battery_properties), |
| 1201 | battery->num_properties = ARRAY_SIZE(bq24190_battery_properties); | 1192 | .get_property = bq24190_battery_get_property, |
| 1202 | battery->get_property = bq24190_battery_get_property; | 1193 | .set_property = bq24190_battery_set_property, |
| 1203 | battery->set_property = bq24190_battery_set_property; | 1194 | .property_is_writeable = bq24190_battery_property_is_writeable, |
| 1204 | battery->property_is_writeable = bq24190_battery_property_is_writeable; | 1195 | }; |
| 1205 | } | ||
| 1206 | 1196 | ||
| 1207 | static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) | 1197 | static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) |
| 1208 | { | 1198 | { |
| @@ -1269,8 +1259,8 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) | |||
| 1269 | * interrupt received). | 1259 | * interrupt received). |
| 1270 | */ | 1260 | */ |
| 1271 | if (alert_userspace && !bdi->first_time) { | 1261 | if (alert_userspace && !bdi->first_time) { |
| 1272 | power_supply_changed(&bdi->charger); | 1262 | power_supply_changed(bdi->charger); |
| 1273 | power_supply_changed(&bdi->battery); | 1263 | power_supply_changed(bdi->battery); |
| 1274 | bdi->first_time = false; | 1264 | bdi->first_time = false; |
| 1275 | } | 1265 | } |
| 1276 | 1266 | ||
| @@ -1362,6 +1352,7 @@ static int bq24190_probe(struct i2c_client *client, | |||
| 1362 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 1352 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 1363 | struct device *dev = &client->dev; | 1353 | struct device *dev = &client->dev; |
| 1364 | struct bq24190_platform_data *pdata = client->dev.platform_data; | 1354 | struct bq24190_platform_data *pdata = client->dev.platform_data; |
| 1355 | struct power_supply_config charger_cfg = {}, battery_cfg = {}; | ||
| 1365 | struct bq24190_dev_info *bdi; | 1356 | struct bq24190_dev_info *bdi; |
| 1366 | int ret; | 1357 | int ret; |
| 1367 | 1358 | ||
| @@ -1416,19 +1407,23 @@ static int bq24190_probe(struct i2c_client *client, | |||
| 1416 | goto out2; | 1407 | goto out2; |
| 1417 | } | 1408 | } |
| 1418 | 1409 | ||
| 1419 | bq24190_charger_init(&bdi->charger); | 1410 | charger_cfg.drv_data = bdi; |
| 1420 | 1411 | charger_cfg.supplied_to = bq24190_charger_supplied_to; | |
| 1421 | ret = power_supply_register(dev, &bdi->charger); | 1412 | charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to), |
| 1422 | if (ret) { | 1413 | bdi->charger = power_supply_register(dev, &bq24190_charger_desc, |
| 1414 | &charger_cfg); | ||
| 1415 | if (IS_ERR(bdi->charger)) { | ||
| 1423 | dev_err(dev, "Can't register charger\n"); | 1416 | dev_err(dev, "Can't register charger\n"); |
| 1417 | ret = PTR_ERR(bdi->charger); | ||
| 1424 | goto out2; | 1418 | goto out2; |
| 1425 | } | 1419 | } |
| 1426 | 1420 | ||
| 1427 | bq24190_battery_init(&bdi->battery); | 1421 | battery_cfg.drv_data = bdi; |
| 1428 | 1422 | bdi->battery = power_supply_register(dev, &bq24190_battery_desc, | |
| 1429 | ret = power_supply_register(dev, &bdi->battery); | 1423 | &battery_cfg); |
| 1430 | if (ret) { | 1424 | if (IS_ERR(bdi->battery)) { |
| 1431 | dev_err(dev, "Can't register battery\n"); | 1425 | dev_err(dev, "Can't register battery\n"); |
| 1426 | ret = PTR_ERR(bdi->battery); | ||
| 1432 | goto out3; | 1427 | goto out3; |
| 1433 | } | 1428 | } |
| 1434 | 1429 | ||
| @@ -1441,9 +1436,9 @@ static int bq24190_probe(struct i2c_client *client, | |||
| 1441 | return 0; | 1436 | return 0; |
| 1442 | 1437 | ||
| 1443 | out4: | 1438 | out4: |
| 1444 | power_supply_unregister(&bdi->battery); | 1439 | power_supply_unregister(bdi->battery); |
| 1445 | out3: | 1440 | out3: |
| 1446 | power_supply_unregister(&bdi->charger); | 1441 | power_supply_unregister(bdi->charger); |
| 1447 | out2: | 1442 | out2: |
| 1448 | pm_runtime_disable(dev); | 1443 | pm_runtime_disable(dev); |
| 1449 | out1: | 1444 | out1: |
| @@ -1462,8 +1457,8 @@ static int bq24190_remove(struct i2c_client *client) | |||
| 1462 | pm_runtime_put_sync(bdi->dev); | 1457 | pm_runtime_put_sync(bdi->dev); |
| 1463 | 1458 | ||
| 1464 | bq24190_sysfs_remove_group(bdi); | 1459 | bq24190_sysfs_remove_group(bdi); |
| 1465 | power_supply_unregister(&bdi->battery); | 1460 | power_supply_unregister(bdi->battery); |
| 1466 | power_supply_unregister(&bdi->charger); | 1461 | power_supply_unregister(bdi->charger); |
| 1467 | pm_runtime_disable(bdi->dev); | 1462 | pm_runtime_disable(bdi->dev); |
| 1468 | 1463 | ||
| 1469 | if (bdi->gpio_int) | 1464 | if (bdi->gpio_int) |
| @@ -1499,8 +1494,8 @@ static int bq24190_pm_resume(struct device *dev) | |||
| 1499 | pm_runtime_put_sync(bdi->dev); | 1494 | pm_runtime_put_sync(bdi->dev); |
| 1500 | 1495 | ||
| 1501 | /* Things may have changed while suspended so alert upper layer */ | 1496 | /* Things may have changed while suspended so alert upper layer */ |
| 1502 | power_supply_changed(&bdi->charger); | 1497 | power_supply_changed(bdi->charger); |
| 1503 | power_supply_changed(&bdi->battery); | 1498 | power_supply_changed(bdi->battery); |
| 1504 | 1499 | ||
| 1505 | return 0; | 1500 | return 0; |
| 1506 | } | 1501 | } |
diff --git a/drivers/power/bq24735-charger.c b/drivers/power/bq24735-charger.c index d022b823305b..961a18930027 100644 --- a/drivers/power/bq24735-charger.c +++ b/drivers/power/bq24735-charger.c | |||
| @@ -44,14 +44,15 @@ | |||
| 44 | #define BQ24735_DEVICE_ID 0xff | 44 | #define BQ24735_DEVICE_ID 0xff |
| 45 | 45 | ||
| 46 | struct bq24735 { | 46 | struct bq24735 { |
| 47 | struct power_supply charger; | 47 | struct power_supply *charger; |
| 48 | struct i2c_client *client; | 48 | struct power_supply_desc charger_desc; |
| 49 | struct bq24735_platform *pdata; | 49 | struct i2c_client *client; |
| 50 | struct bq24735_platform *pdata; | ||
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 52 | static inline struct bq24735 *to_bq24735(struct power_supply *psy) | 53 | static inline struct bq24735 *to_bq24735(struct power_supply *psy) |
| 53 | { | 54 | { |
| 54 | return container_of(psy, struct bq24735, charger); | 55 | return power_supply_get_drvdata(psy); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | static enum power_supply_property bq24735_charger_properties[] = { | 58 | static enum power_supply_property bq24735_charger_properties[] = { |
| @@ -192,9 +193,7 @@ static int bq24735_charger_get_property(struct power_supply *psy, | |||
| 192 | enum power_supply_property psp, | 193 | enum power_supply_property psp, |
| 193 | union power_supply_propval *val) | 194 | union power_supply_propval *val) |
| 194 | { | 195 | { |
| 195 | struct bq24735 *charger; | 196 | struct bq24735 *charger = to_bq24735(psy); |
| 196 | |||
| 197 | charger = container_of(psy, struct bq24735, charger); | ||
| 198 | 197 | ||
| 199 | switch (psp) { | 198 | switch (psp) { |
| 200 | case POWER_SUPPLY_PROP_ONLINE: | 199 | case POWER_SUPPLY_PROP_ONLINE: |
| @@ -248,7 +247,8 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
| 248 | { | 247 | { |
| 249 | int ret; | 248 | int ret; |
| 250 | struct bq24735 *charger; | 249 | struct bq24735 *charger; |
| 251 | struct power_supply *supply; | 250 | struct power_supply_desc *supply_desc; |
| 251 | struct power_supply_config psy_cfg = {}; | ||
| 252 | char *name; | 252 | char *name; |
| 253 | 253 | ||
| 254 | charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); | 254 | charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); |
| @@ -277,16 +277,18 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
| 277 | 277 | ||
| 278 | charger->client = client; | 278 | charger->client = client; |
| 279 | 279 | ||
| 280 | supply = &charger->charger; | 280 | supply_desc = &charger->charger_desc; |
| 281 | 281 | ||
| 282 | supply->name = name; | 282 | supply_desc->name = name; |
| 283 | supply->type = POWER_SUPPLY_TYPE_MAINS; | 283 | supply_desc->type = POWER_SUPPLY_TYPE_MAINS; |
| 284 | supply->properties = bq24735_charger_properties; | 284 | supply_desc->properties = bq24735_charger_properties; |
| 285 | supply->num_properties = ARRAY_SIZE(bq24735_charger_properties); | 285 | supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); |
| 286 | supply->get_property = bq24735_charger_get_property; | 286 | supply_desc->get_property = bq24735_charger_get_property; |
| 287 | supply->supplied_to = charger->pdata->supplied_to; | 287 | |
| 288 | supply->num_supplicants = charger->pdata->num_supplicants; | 288 | psy_cfg.supplied_to = charger->pdata->supplied_to; |
| 289 | supply->of_node = client->dev.of_node; | 289 | psy_cfg.num_supplicants = charger->pdata->num_supplicants; |
| 290 | psy_cfg.of_node = client->dev.of_node; | ||
| 291 | psy_cfg.drv_data = charger; | ||
| 290 | 292 | ||
| 291 | i2c_set_clientdata(client, charger); | 293 | i2c_set_clientdata(client, charger); |
| 292 | 294 | ||
| @@ -341,8 +343,10 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
| 341 | } | 343 | } |
| 342 | } | 344 | } |
| 343 | 345 | ||
| 344 | ret = power_supply_register(&client->dev, supply); | 346 | charger->charger = power_supply_register(&client->dev, supply_desc, |
| 345 | if (ret < 0) { | 347 | &psy_cfg); |
| 348 | if (IS_ERR(charger->charger)) { | ||
| 349 | ret = PTR_ERR(charger->charger); | ||
| 346 | dev_err(&client->dev, "Failed to register power supply: %d\n", | 350 | dev_err(&client->dev, "Failed to register power supply: %d\n", |
| 347 | ret); | 351 | ret); |
| 348 | goto err_free_name; | 352 | goto err_free_name; |
| @@ -354,7 +358,8 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
| 354 | IRQF_TRIGGER_RISING | | 358 | IRQF_TRIGGER_RISING | |
| 355 | IRQF_TRIGGER_FALLING | | 359 | IRQF_TRIGGER_FALLING | |
| 356 | IRQF_ONESHOT, | 360 | IRQF_ONESHOT, |
| 357 | supply->name, supply); | 361 | supply_desc->name, |
| 362 | charger->charger); | ||
| 358 | if (ret) { | 363 | if (ret) { |
| 359 | dev_err(&client->dev, | 364 | dev_err(&client->dev, |
| 360 | "Unable to register IRQ %d err %d\n", | 365 | "Unable to register IRQ %d err %d\n", |
| @@ -365,7 +370,7 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
| 365 | 370 | ||
| 366 | return 0; | 371 | return 0; |
| 367 | err_unregister_supply: | 372 | err_unregister_supply: |
| 368 | power_supply_unregister(supply); | 373 | power_supply_unregister(charger->charger); |
| 369 | err_free_name: | 374 | err_free_name: |
| 370 | if (name != charger->pdata->name) | 375 | if (name != charger->pdata->name) |
| 371 | kfree(name); | 376 | kfree(name); |
| @@ -381,10 +386,10 @@ static int bq24735_charger_remove(struct i2c_client *client) | |||
| 381 | devm_free_irq(&charger->client->dev, charger->client->irq, | 386 | devm_free_irq(&charger->client->dev, charger->client->irq, |
| 382 | &charger->charger); | 387 | &charger->charger); |
| 383 | 388 | ||
| 384 | power_supply_unregister(&charger->charger); | 389 | power_supply_unregister(charger->charger); |
| 385 | 390 | ||
| 386 | if (charger->charger.name != charger->pdata->name) | 391 | if (charger->charger_desc.name != charger->pdata->name) |
| 387 | kfree(charger->charger.name); | 392 | kfree(charger->charger_desc.name); |
| 388 | 393 | ||
| 389 | return 0; | 394 | return 0; |
| 390 | } | 395 | } |
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index b72ba7c1bd69..a57433de5c24 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c | |||
| @@ -16,14 +16,12 @@ | |||
| 16 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | 16 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
| 17 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 17 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
| 18 | * | 18 | * |
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Datasheets: | 19 | * Datasheets: |
| 23 | * http://focus.ti.com/docs/prod/folders/print/bq27000.html | 20 | * http://focus.ti.com/docs/prod/folders/print/bq27000.html |
| 24 | * http://focus.ti.com/docs/prod/folders/print/bq27500.html | 21 | * http://focus.ti.com/docs/prod/folders/print/bq27500.html |
| 25 | * http://www.ti.com/product/bq27425-g1 | 22 | * http://www.ti.com/product/bq27425-g1 |
| 26 | * http://www.ti.com/product/BQ27742-G1 | 23 | * http://www.ti.com/product/BQ27742-G1 |
| 24 | * http://www.ti.com/product/BQ27510-G3 | ||
| 27 | */ | 25 | */ |
| 28 | 26 | ||
| 29 | #include <linux/device.h> | 27 | #include <linux/device.h> |
| @@ -74,6 +72,10 @@ | |||
| 74 | 72 | ||
| 75 | #define BQ27742_POWER_AVG 0x76 | 73 | #define BQ27742_POWER_AVG 0x76 |
| 76 | 74 | ||
| 75 | #define BQ27510_REG_SOC 0x20 | ||
| 76 | #define BQ27510_REG_DCAP 0x2E /* Design capacity */ | ||
| 77 | #define BQ27510_REG_CYCT 0x1E /* Cycle count total */ | ||
| 78 | |||
| 77 | /* bq27425 register addresses are same as bq27x00 addresses minus 4 */ | 79 | /* bq27425 register addresses are same as bq27x00 addresses minus 4 */ |
| 78 | #define BQ27425_REG_OFFSET 0x04 | 80 | #define BQ27425_REG_OFFSET 0x04 |
| 79 | #define BQ27425_REG_SOC (0x1C + BQ27425_REG_OFFSET) | 81 | #define BQ27425_REG_SOC (0x1C + BQ27425_REG_OFFSET) |
| @@ -87,7 +89,7 @@ struct bq27x00_access_methods { | |||
| 87 | int (*read)(struct bq27x00_device_info *di, u8 reg, bool single); | 89 | int (*read)(struct bq27x00_device_info *di, u8 reg, bool single); |
| 88 | }; | 90 | }; |
| 89 | 91 | ||
| 90 | enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742}; | 92 | enum bq27x00_chip { BQ27000, BQ27500, BQ27425, BQ27742, BQ27510}; |
| 91 | 93 | ||
| 92 | struct bq27x00_reg_cache { | 94 | struct bq27x00_reg_cache { |
| 93 | int temperature; | 95 | int temperature; |
| @@ -114,7 +116,7 @@ struct bq27x00_device_info { | |||
| 114 | unsigned long last_update; | 116 | unsigned long last_update; |
| 115 | struct delayed_work work; | 117 | struct delayed_work work; |
| 116 | 118 | ||
| 117 | struct power_supply bat; | 119 | struct power_supply *bat; |
| 118 | 120 | ||
| 119 | struct bq27x00_access_methods bus; | 121 | struct bq27x00_access_methods bus; |
| 120 | 122 | ||
| @@ -174,6 +176,24 @@ static enum power_supply_property bq27742_battery_props[] = { | |||
| 174 | POWER_SUPPLY_PROP_HEALTH, | 176 | POWER_SUPPLY_PROP_HEALTH, |
| 175 | }; | 177 | }; |
| 176 | 178 | ||
| 179 | static enum power_supply_property bq27510_battery_props[] = { | ||
| 180 | POWER_SUPPLY_PROP_STATUS, | ||
| 181 | POWER_SUPPLY_PROP_PRESENT, | ||
| 182 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 183 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
| 184 | POWER_SUPPLY_PROP_CAPACITY, | ||
| 185 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, | ||
| 186 | POWER_SUPPLY_PROP_TEMP, | ||
| 187 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, | ||
| 188 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 189 | POWER_SUPPLY_PROP_CHARGE_FULL, | ||
| 190 | POWER_SUPPLY_PROP_CHARGE_NOW, | ||
| 191 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | ||
| 192 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
| 193 | POWER_SUPPLY_PROP_POWER_AVG, | ||
| 194 | POWER_SUPPLY_PROP_HEALTH, | ||
| 195 | }; | ||
| 196 | |||
| 177 | static unsigned int poll_interval = 360; | 197 | static unsigned int poll_interval = 360; |
| 178 | module_param(poll_interval, uint, 0644); | 198 | module_param(poll_interval, uint, 0644); |
| 179 | MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ | 199 | MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ |
| @@ -198,7 +218,8 @@ static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg, | |||
| 198 | */ | 218 | */ |
| 199 | static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di) | 219 | static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di) |
| 200 | { | 220 | { |
| 201 | if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742) | 221 | if (di->chip == BQ27425 || di->chip == BQ27500 || di->chip == BQ27742 |
| 222 | || di->chip == BQ27510) | ||
| 202 | return true; | 223 | return true; |
| 203 | return false; | 224 | return false; |
| 204 | } | 225 | } |
| @@ -213,6 +234,8 @@ static int bq27x00_battery_read_rsoc(struct bq27x00_device_info *di) | |||
| 213 | 234 | ||
| 214 | if (di->chip == BQ27500 || di->chip == BQ27742) | 235 | if (di->chip == BQ27500 || di->chip == BQ27742) |
| 215 | rsoc = bq27x00_read(di, BQ27500_REG_SOC, false); | 236 | rsoc = bq27x00_read(di, BQ27500_REG_SOC, false); |
| 237 | else if (di->chip == BQ27510) | ||
| 238 | rsoc = bq27x00_read(di, BQ27510_REG_SOC, false); | ||
| 216 | else if (di->chip == BQ27425) | 239 | else if (di->chip == BQ27425) |
| 217 | rsoc = bq27x00_read(di, BQ27425_REG_SOC, false); | 240 | rsoc = bq27x00_read(di, BQ27425_REG_SOC, false); |
| 218 | else | 241 | else |
| @@ -286,6 +309,8 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di) | |||
| 286 | if (bq27xxx_is_chip_version_higher(di)) { | 309 | if (bq27xxx_is_chip_version_higher(di)) { |
| 287 | if (di->chip == BQ27425) | 310 | if (di->chip == BQ27425) |
| 288 | ilmd = bq27x00_read(di, BQ27425_REG_DCAP, false); | 311 | ilmd = bq27x00_read(di, BQ27425_REG_DCAP, false); |
| 312 | else if (di->chip == BQ27510) | ||
| 313 | ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false); | ||
| 289 | else | 314 | else |
| 290 | ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); | 315 | ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); |
| 291 | } else | 316 | } else |
| @@ -354,7 +379,10 @@ static int bq27x00_battery_read_cyct(struct bq27x00_device_info *di) | |||
| 354 | { | 379 | { |
| 355 | int cyct; | 380 | int cyct; |
| 356 | 381 | ||
| 357 | cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false); | 382 | if (di->chip == BQ27510) |
| 383 | cyct = bq27x00_read(di, BQ27510_REG_CYCT, false); | ||
| 384 | else | ||
| 385 | cyct = bq27x00_read(di, BQ27x00_REG_CYCT, false); | ||
| 358 | if (cyct < 0) | 386 | if (cyct < 0) |
| 359 | dev_err(di->dev, "error reading cycle count total\n"); | 387 | dev_err(di->dev, "error reading cycle count total\n"); |
| 360 | 388 | ||
| @@ -425,6 +453,10 @@ static int bq27x00_battery_read_health(struct bq27x00_device_info *di) | |||
| 425 | else | 453 | else |
| 426 | tval = POWER_SUPPLY_HEALTH_GOOD; | 454 | tval = POWER_SUPPLY_HEALTH_GOOD; |
| 427 | return tval; | 455 | return tval; |
| 456 | } else if (di->chip == BQ27510) { | ||
| 457 | if (tval & BQ27500_FLAG_OTC) | ||
| 458 | return POWER_SUPPLY_HEALTH_OVERHEAT; | ||
| 459 | return POWER_SUPPLY_HEALTH_GOOD; | ||
| 428 | } else { | 460 | } else { |
| 429 | if (tval & BQ27000_FLAG_EDV1) | 461 | if (tval & BQ27000_FLAG_EDV1) |
| 430 | tval = POWER_SUPPLY_HEALTH_DEAD; | 462 | tval = POWER_SUPPLY_HEALTH_DEAD; |
| @@ -440,6 +472,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) | |||
| 440 | { | 472 | { |
| 441 | struct bq27x00_reg_cache cache = {0, }; | 473 | struct bq27x00_reg_cache cache = {0, }; |
| 442 | bool is_bq27500 = di->chip == BQ27500; | 474 | bool is_bq27500 = di->chip == BQ27500; |
| 475 | bool is_bq27510 = di->chip == BQ27510; | ||
| 443 | bool is_bq27425 = di->chip == BQ27425; | 476 | bool is_bq27425 = di->chip == BQ27425; |
| 444 | bool is_bq27742 = di->chip == BQ27742; | 477 | bool is_bq27742 = di->chip == BQ27742; |
| 445 | bool flags_1b = !(is_bq27500 || is_bq27742); | 478 | bool flags_1b = !(is_bq27500 || is_bq27742); |
| @@ -449,7 +482,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) | |||
| 449 | /* read error */ | 482 | /* read error */ |
| 450 | cache.flags = -1; | 483 | cache.flags = -1; |
| 451 | if (cache.flags >= 0) { | 484 | if (cache.flags >= 0) { |
| 452 | if (!is_bq27500 && !is_bq27425 && !is_bq27742 | 485 | if (!is_bq27500 && !is_bq27425 && !is_bq27742 && !is_bq27510 |
| 453 | && (cache.flags & BQ27000_FLAG_CI)) { | 486 | && (cache.flags & BQ27000_FLAG_CI)) { |
| 454 | dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); | 487 | dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); |
| 455 | cache.capacity = -ENODATA; | 488 | cache.capacity = -ENODATA; |
| @@ -461,7 +494,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) | |||
| 461 | cache.health = -ENODATA; | 494 | cache.health = -ENODATA; |
| 462 | } else { | 495 | } else { |
| 463 | cache.capacity = bq27x00_battery_read_rsoc(di); | 496 | cache.capacity = bq27x00_battery_read_rsoc(di); |
| 464 | if (is_bq27742) | 497 | if (is_bq27742 || is_bq27510) |
| 465 | cache.time_to_empty = | 498 | cache.time_to_empty = |
| 466 | bq27x00_battery_read_time(di, | 499 | bq27x00_battery_read_time(di, |
| 467 | BQ27x00_REG_TTE); | 500 | BQ27x00_REG_TTE); |
| @@ -498,7 +531,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) | |||
| 498 | } | 531 | } |
| 499 | 532 | ||
| 500 | if (di->cache.capacity != cache.capacity) | 533 | if (di->cache.capacity != cache.capacity) |
| 501 | power_supply_changed(&di->bat); | 534 | power_supply_changed(di->bat); |
| 502 | 535 | ||
| 503 | if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) | 536 | if (memcmp(&di->cache, &cache, sizeof(cache)) != 0) |
| 504 | di->cache = cache; | 537 | di->cache = cache; |
| @@ -570,7 +603,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di, | |||
| 570 | status = POWER_SUPPLY_STATUS_FULL; | 603 | status = POWER_SUPPLY_STATUS_FULL; |
| 571 | else if (di->cache.flags & BQ27000_FLAG_CHGS) | 604 | else if (di->cache.flags & BQ27000_FLAG_CHGS) |
| 572 | status = POWER_SUPPLY_STATUS_CHARGING; | 605 | status = POWER_SUPPLY_STATUS_CHARGING; |
| 573 | else if (power_supply_am_i_supplied(&di->bat)) | 606 | else if (power_supply_am_i_supplied(di->bat)) |
| 574 | status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 607 | status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| 575 | else | 608 | else |
| 576 | status = POWER_SUPPLY_STATUS_DISCHARGING; | 609 | status = POWER_SUPPLY_STATUS_DISCHARGING; |
| @@ -642,15 +675,12 @@ static int bq27x00_simple_value(int value, | |||
| 642 | return 0; | 675 | return 0; |
| 643 | } | 676 | } |
| 644 | 677 | ||
| 645 | #define to_bq27x00_device_info(x) container_of((x), \ | ||
| 646 | struct bq27x00_device_info, bat); | ||
| 647 | |||
| 648 | static int bq27x00_battery_get_property(struct power_supply *psy, | 678 | static int bq27x00_battery_get_property(struct power_supply *psy, |
| 649 | enum power_supply_property psp, | 679 | enum power_supply_property psp, |
| 650 | union power_supply_propval *val) | 680 | union power_supply_propval *val) |
| 651 | { | 681 | { |
| 652 | int ret = 0; | 682 | int ret = 0; |
| 653 | struct bq27x00_device_info *di = to_bq27x00_device_info(psy); | 683 | struct bq27x00_device_info *di = power_supply_get_drvdata(psy); |
| 654 | 684 | ||
| 655 | mutex_lock(&di->lock); | 685 | mutex_lock(&di->lock); |
| 656 | if (time_is_before_jiffies(di->last_update + 5 * HZ)) { | 686 | if (time_is_before_jiffies(di->last_update + 5 * HZ)) { |
| @@ -728,35 +758,47 @@ static int bq27x00_battery_get_property(struct power_supply *psy, | |||
| 728 | 758 | ||
| 729 | static void bq27x00_external_power_changed(struct power_supply *psy) | 759 | static void bq27x00_external_power_changed(struct power_supply *psy) |
| 730 | { | 760 | { |
| 731 | struct bq27x00_device_info *di = to_bq27x00_device_info(psy); | 761 | struct bq27x00_device_info *di = power_supply_get_drvdata(psy); |
| 732 | 762 | ||
| 733 | cancel_delayed_work_sync(&di->work); | 763 | cancel_delayed_work_sync(&di->work); |
| 734 | schedule_delayed_work(&di->work, 0); | 764 | schedule_delayed_work(&di->work, 0); |
| 735 | } | 765 | } |
| 736 | 766 | ||
| 737 | static int bq27x00_powersupply_init(struct bq27x00_device_info *di) | 767 | static int bq27x00_powersupply_init(struct bq27x00_device_info *di, |
| 768 | const char *name) | ||
| 738 | { | 769 | { |
| 739 | int ret; | 770 | int ret; |
| 771 | struct power_supply_desc *psy_desc; | ||
| 772 | struct power_supply_config psy_cfg = { .drv_data = di, }; | ||
| 740 | 773 | ||
| 741 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 774 | psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL); |
| 775 | if (!psy_desc) | ||
| 776 | return -ENOMEM; | ||
| 777 | |||
| 778 | psy_desc->name = name; | ||
| 779 | psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 742 | if (di->chip == BQ27425) { | 780 | if (di->chip == BQ27425) { |
| 743 | di->bat.properties = bq27425_battery_props; | 781 | psy_desc->properties = bq27425_battery_props; |
| 744 | di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props); | 782 | psy_desc->num_properties = ARRAY_SIZE(bq27425_battery_props); |
| 745 | } else if (di->chip == BQ27742) { | 783 | } else if (di->chip == BQ27742) { |
| 746 | di->bat.properties = bq27742_battery_props; | 784 | psy_desc->properties = bq27742_battery_props; |
| 747 | di->bat.num_properties = ARRAY_SIZE(bq27742_battery_props); | 785 | psy_desc->num_properties = ARRAY_SIZE(bq27742_battery_props); |
| 786 | } else if (di->chip == BQ27510) { | ||
| 787 | psy_desc->properties = bq27510_battery_props; | ||
| 788 | psy_desc->num_properties = ARRAY_SIZE(bq27510_battery_props); | ||
| 748 | } else { | 789 | } else { |
| 749 | di->bat.properties = bq27x00_battery_props; | 790 | psy_desc->properties = bq27x00_battery_props; |
| 750 | di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); | 791 | psy_desc->num_properties = ARRAY_SIZE(bq27x00_battery_props); |
| 751 | } | 792 | } |
| 752 | di->bat.get_property = bq27x00_battery_get_property; | 793 | psy_desc->get_property = bq27x00_battery_get_property; |
| 753 | di->bat.external_power_changed = bq27x00_external_power_changed; | 794 | psy_desc->external_power_changed = bq27x00_external_power_changed; |
| 754 | 795 | ||
| 755 | INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll); | 796 | INIT_DELAYED_WORK(&di->work, bq27x00_battery_poll); |
| 756 | mutex_init(&di->lock); | 797 | mutex_init(&di->lock); |
| 757 | 798 | ||
| 758 | ret = power_supply_register(di->dev, &di->bat); | 799 | di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); |
| 759 | if (ret) { | 800 | if (IS_ERR(di->bat)) { |
| 801 | ret = PTR_ERR(di->bat); | ||
| 760 | dev_err(di->dev, "failed to register battery: %d\n", ret); | 802 | dev_err(di->dev, "failed to register battery: %d\n", ret); |
| 761 | return ret; | 803 | return ret; |
| 762 | } | 804 | } |
| @@ -780,7 +822,7 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di) | |||
| 780 | 822 | ||
| 781 | cancel_delayed_work_sync(&di->work); | 823 | cancel_delayed_work_sync(&di->work); |
| 782 | 824 | ||
| 783 | power_supply_unregister(&di->bat); | 825 | power_supply_unregister(di->bat); |
| 784 | 826 | ||
| 785 | mutex_destroy(&di->lock); | 827 | mutex_destroy(&di->lock); |
| 786 | } | 828 | } |
| @@ -844,37 +886,34 @@ static int bq27x00_battery_probe(struct i2c_client *client, | |||
| 844 | if (num < 0) | 886 | if (num < 0) |
| 845 | return num; | 887 | return num; |
| 846 | 888 | ||
| 847 | name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); | 889 | name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); |
| 848 | if (!name) { | 890 | if (!name) { |
| 849 | dev_err(&client->dev, "failed to allocate device name\n"); | 891 | dev_err(&client->dev, "failed to allocate device name\n"); |
| 850 | retval = -ENOMEM; | 892 | retval = -ENOMEM; |
| 851 | goto batt_failed_1; | 893 | goto batt_failed; |
| 852 | } | 894 | } |
| 853 | 895 | ||
| 854 | di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); | 896 | di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); |
| 855 | if (!di) { | 897 | if (!di) { |
| 856 | dev_err(&client->dev, "failed to allocate device info data\n"); | 898 | dev_err(&client->dev, "failed to allocate device info data\n"); |
| 857 | retval = -ENOMEM; | 899 | retval = -ENOMEM; |
| 858 | goto batt_failed_2; | 900 | goto batt_failed; |
| 859 | } | 901 | } |
| 860 | 902 | ||
| 861 | di->id = num; | 903 | di->id = num; |
| 862 | di->dev = &client->dev; | 904 | di->dev = &client->dev; |
| 863 | di->chip = id->driver_data; | 905 | di->chip = id->driver_data; |
| 864 | di->bat.name = name; | ||
| 865 | di->bus.read = &bq27x00_read_i2c; | 906 | di->bus.read = &bq27x00_read_i2c; |
| 866 | 907 | ||
| 867 | retval = bq27x00_powersupply_init(di); | 908 | retval = bq27x00_powersupply_init(di, name); |
| 868 | if (retval) | 909 | if (retval) |
| 869 | goto batt_failed_2; | 910 | goto batt_failed; |
| 870 | 911 | ||
| 871 | i2c_set_clientdata(client, di); | 912 | i2c_set_clientdata(client, di); |
| 872 | 913 | ||
| 873 | return 0; | 914 | return 0; |
| 874 | 915 | ||
| 875 | batt_failed_2: | 916 | batt_failed: |
| 876 | kfree(name); | ||
| 877 | batt_failed_1: | ||
| 878 | mutex_lock(&battery_mutex); | 917 | mutex_lock(&battery_mutex); |
| 879 | idr_remove(&battery_id, num); | 918 | idr_remove(&battery_id, num); |
| 880 | mutex_unlock(&battery_mutex); | 919 | mutex_unlock(&battery_mutex); |
| @@ -888,8 +927,6 @@ static int bq27x00_battery_remove(struct i2c_client *client) | |||
| 888 | 927 | ||
| 889 | bq27x00_powersupply_unregister(di); | 928 | bq27x00_powersupply_unregister(di); |
| 890 | 929 | ||
| 891 | kfree(di->bat.name); | ||
| 892 | |||
| 893 | mutex_lock(&battery_mutex); | 930 | mutex_lock(&battery_mutex); |
| 894 | idr_remove(&battery_id, di->id); | 931 | idr_remove(&battery_id, di->id); |
| 895 | mutex_unlock(&battery_mutex); | 932 | mutex_unlock(&battery_mutex); |
| @@ -902,6 +939,7 @@ static const struct i2c_device_id bq27x00_id[] = { | |||
| 902 | { "bq27500", BQ27500 }, | 939 | { "bq27500", BQ27500 }, |
| 903 | { "bq27425", BQ27425 }, | 940 | { "bq27425", BQ27425 }, |
| 904 | { "bq27742", BQ27742 }, | 941 | { "bq27742", BQ27742 }, |
| 942 | { "bq27510", BQ27510 }, | ||
| 905 | {}, | 943 | {}, |
| 906 | }; | 944 | }; |
| 907 | MODULE_DEVICE_TABLE(i2c, bq27x00_id); | 945 | MODULE_DEVICE_TABLE(i2c, bq27x00_id); |
| @@ -977,6 +1015,7 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
| 977 | { | 1015 | { |
| 978 | struct bq27x00_device_info *di; | 1016 | struct bq27x00_device_info *di; |
| 979 | struct bq27000_platform_data *pdata = pdev->dev.platform_data; | 1017 | struct bq27000_platform_data *pdata = pdev->dev.platform_data; |
| 1018 | const char *name; | ||
| 980 | 1019 | ||
| 981 | if (!pdata) { | 1020 | if (!pdata) { |
| 982 | dev_err(&pdev->dev, "no platform_data supplied\n"); | 1021 | dev_err(&pdev->dev, "no platform_data supplied\n"); |
| @@ -999,10 +1038,10 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
| 999 | di->dev = &pdev->dev; | 1038 | di->dev = &pdev->dev; |
| 1000 | di->chip = BQ27000; | 1039 | di->chip = BQ27000; |
| 1001 | 1040 | ||
| 1002 | di->bat.name = pdata->name ?: dev_name(&pdev->dev); | 1041 | name = pdata->name ?: dev_name(&pdev->dev); |
| 1003 | di->bus.read = &bq27000_read_platform; | 1042 | di->bus.read = &bq27000_read_platform; |
| 1004 | 1043 | ||
| 1005 | return bq27x00_powersupply_init(di); | 1044 | return bq27x00_powersupply_init(di, name); |
| 1006 | } | 1045 | } |
| 1007 | 1046 | ||
| 1008 | static int bq27000_battery_remove(struct platform_device *pdev) | 1047 | static int bq27000_battery_remove(struct platform_device *pdev) |
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 14b0d85318eb..0aed13f90891 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c | |||
| @@ -103,10 +103,11 @@ static bool is_batt_present(struct charger_manager *cm) | |||
| 103 | if (!psy) | 103 | if (!psy) |
| 104 | break; | 104 | break; |
| 105 | 105 | ||
| 106 | ret = psy->get_property(psy, | 106 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, |
| 107 | POWER_SUPPLY_PROP_PRESENT, &val); | 107 | &val); |
| 108 | if (ret == 0 && val.intval) | 108 | if (ret == 0 && val.intval) |
| 109 | present = true; | 109 | present = true; |
| 110 | power_supply_put(psy); | ||
| 110 | break; | 111 | break; |
| 111 | case CM_CHARGER_STAT: | 112 | case CM_CHARGER_STAT: |
| 112 | for (i = 0; cm->desc->psy_charger_stat[i]; i++) { | 113 | for (i = 0; cm->desc->psy_charger_stat[i]; i++) { |
| @@ -118,8 +119,9 @@ static bool is_batt_present(struct charger_manager *cm) | |||
| 118 | continue; | 119 | continue; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, | 122 | ret = power_supply_get_property(psy, |
| 122 | &val); | 123 | POWER_SUPPLY_PROP_PRESENT, &val); |
| 124 | power_supply_put(psy); | ||
| 123 | if (ret == 0 && val.intval) { | 125 | if (ret == 0 && val.intval) { |
| 124 | present = true; | 126 | present = true; |
| 125 | break; | 127 | break; |
| @@ -155,7 +157,9 @@ static bool is_ext_pwr_online(struct charger_manager *cm) | |||
| 155 | continue; | 157 | continue; |
| 156 | } | 158 | } |
| 157 | 159 | ||
| 158 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); | 160 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, |
| 161 | &val); | ||
| 162 | power_supply_put(psy); | ||
| 159 | if (ret == 0 && val.intval) { | 163 | if (ret == 0 && val.intval) { |
| 160 | online = true; | 164 | online = true; |
| 161 | break; | 165 | break; |
| @@ -183,8 +187,9 @@ static int get_batt_uV(struct charger_manager *cm, int *uV) | |||
| 183 | if (!fuel_gauge) | 187 | if (!fuel_gauge) |
| 184 | return -ENODEV; | 188 | return -ENODEV; |
| 185 | 189 | ||
| 186 | ret = fuel_gauge->get_property(fuel_gauge, | 190 | ret = power_supply_get_property(fuel_gauge, |
| 187 | POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); | 191 | POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); |
| 192 | power_supply_put(fuel_gauge); | ||
| 188 | if (ret) | 193 | if (ret) |
| 189 | return ret; | 194 | return ret; |
| 190 | 195 | ||
| @@ -223,20 +228,26 @@ static bool is_charging(struct charger_manager *cm) | |||
| 223 | } | 228 | } |
| 224 | 229 | ||
| 225 | /* 2. The charger should be online (ext-power) */ | 230 | /* 2. The charger should be online (ext-power) */ |
| 226 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val); | 231 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, |
| 232 | &val); | ||
| 227 | if (ret) { | 233 | if (ret) { |
| 228 | dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", | 234 | dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", |
| 229 | cm->desc->psy_charger_stat[i]); | 235 | cm->desc->psy_charger_stat[i]); |
| 236 | power_supply_put(psy); | ||
| 230 | continue; | 237 | continue; |
| 231 | } | 238 | } |
| 232 | if (val.intval == 0) | 239 | if (val.intval == 0) { |
| 240 | power_supply_put(psy); | ||
| 233 | continue; | 241 | continue; |
| 242 | } | ||
| 234 | 243 | ||
| 235 | /* | 244 | /* |
| 236 | * 3. The charger should not be FULL, DISCHARGING, | 245 | * 3. The charger should not be FULL, DISCHARGING, |
| 237 | * or NOT_CHARGING. | 246 | * or NOT_CHARGING. |
| 238 | */ | 247 | */ |
| 239 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val); | 248 | ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, |
| 249 | &val); | ||
| 250 | power_supply_put(psy); | ||
| 240 | if (ret) { | 251 | if (ret) { |
| 241 | dev_warn(cm->dev, "Cannot read STATUS value from %s\n", | 252 | dev_warn(cm->dev, "Cannot read STATUS value from %s\n", |
| 242 | cm->desc->psy_charger_stat[i]); | 253 | cm->desc->psy_charger_stat[i]); |
| @@ -264,6 +275,7 @@ static bool is_full_charged(struct charger_manager *cm) | |||
| 264 | struct charger_desc *desc = cm->desc; | 275 | struct charger_desc *desc = cm->desc; |
| 265 | union power_supply_propval val; | 276 | union power_supply_propval val; |
| 266 | struct power_supply *fuel_gauge; | 277 | struct power_supply *fuel_gauge; |
| 278 | bool is_full = false; | ||
| 267 | int ret = 0; | 279 | int ret = 0; |
| 268 | int uV; | 280 | int uV; |
| 269 | 281 | ||
| @@ -279,30 +291,38 @@ static bool is_full_charged(struct charger_manager *cm) | |||
| 279 | val.intval = 0; | 291 | val.intval = 0; |
| 280 | 292 | ||
| 281 | /* Not full if capacity of fuel gauge isn't full */ | 293 | /* Not full if capacity of fuel gauge isn't full */ |
| 282 | ret = fuel_gauge->get_property(fuel_gauge, | 294 | ret = power_supply_get_property(fuel_gauge, |
| 283 | POWER_SUPPLY_PROP_CHARGE_FULL, &val); | 295 | POWER_SUPPLY_PROP_CHARGE_FULL, &val); |
| 284 | if (!ret && val.intval > desc->fullbatt_full_capacity) | 296 | if (!ret && val.intval > desc->fullbatt_full_capacity) { |
| 285 | return true; | 297 | is_full = true; |
| 298 | goto out; | ||
| 299 | } | ||
| 286 | } | 300 | } |
| 287 | 301 | ||
| 288 | /* Full, if it's over the fullbatt voltage */ | 302 | /* Full, if it's over the fullbatt voltage */ |
| 289 | if (desc->fullbatt_uV > 0) { | 303 | if (desc->fullbatt_uV > 0) { |
| 290 | ret = get_batt_uV(cm, &uV); | 304 | ret = get_batt_uV(cm, &uV); |
| 291 | if (!ret && uV >= desc->fullbatt_uV) | 305 | if (!ret && uV >= desc->fullbatt_uV) { |
| 292 | return true; | 306 | is_full = true; |
| 307 | goto out; | ||
| 308 | } | ||
| 293 | } | 309 | } |
| 294 | 310 | ||
| 295 | /* Full, if the capacity is more than fullbatt_soc */ | 311 | /* Full, if the capacity is more than fullbatt_soc */ |
| 296 | if (desc->fullbatt_soc > 0) { | 312 | if (desc->fullbatt_soc > 0) { |
| 297 | val.intval = 0; | 313 | val.intval = 0; |
| 298 | 314 | ||
| 299 | ret = fuel_gauge->get_property(fuel_gauge, | 315 | ret = power_supply_get_property(fuel_gauge, |
| 300 | POWER_SUPPLY_PROP_CAPACITY, &val); | 316 | POWER_SUPPLY_PROP_CAPACITY, &val); |
| 301 | if (!ret && val.intval >= desc->fullbatt_soc) | 317 | if (!ret && val.intval >= desc->fullbatt_soc) { |
| 302 | return true; | 318 | is_full = true; |
| 319 | goto out; | ||
| 320 | } | ||
| 303 | } | 321 | } |
| 304 | 322 | ||
| 305 | return false; | 323 | out: |
| 324 | power_supply_put(fuel_gauge); | ||
| 325 | return is_full; | ||
| 306 | } | 326 | } |
| 307 | 327 | ||
| 308 | /** | 328 | /** |
| @@ -575,14 +595,18 @@ static int cm_get_battery_temperature_by_psy(struct charger_manager *cm, | |||
| 575 | int *temp) | 595 | int *temp) |
| 576 | { | 596 | { |
| 577 | struct power_supply *fuel_gauge; | 597 | struct power_supply *fuel_gauge; |
| 598 | int ret; | ||
| 578 | 599 | ||
| 579 | fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); | 600 | fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); |
| 580 | if (!fuel_gauge) | 601 | if (!fuel_gauge) |
| 581 | return -ENODEV; | 602 | return -ENODEV; |
| 582 | 603 | ||
| 583 | return fuel_gauge->get_property(fuel_gauge, | 604 | ret = power_supply_get_property(fuel_gauge, |
| 584 | POWER_SUPPLY_PROP_TEMP, | 605 | POWER_SUPPLY_PROP_TEMP, |
| 585 | (union power_supply_propval *)temp); | 606 | (union power_supply_propval *)temp); |
| 607 | power_supply_put(fuel_gauge); | ||
| 608 | |||
| 609 | return ret; | ||
| 586 | } | 610 | } |
| 587 | 611 | ||
| 588 | static int cm_get_battery_temperature(struct charger_manager *cm, | 612 | static int cm_get_battery_temperature(struct charger_manager *cm, |
| @@ -861,10 +885,9 @@ static int charger_get_property(struct power_supply *psy, | |||
| 861 | enum power_supply_property psp, | 885 | enum power_supply_property psp, |
| 862 | union power_supply_propval *val) | 886 | union power_supply_propval *val) |
| 863 | { | 887 | { |
| 864 | struct charger_manager *cm = container_of(psy, | 888 | struct charger_manager *cm = power_supply_get_drvdata(psy); |
| 865 | struct charger_manager, charger_psy); | ||
| 866 | struct charger_desc *desc = cm->desc; | 889 | struct charger_desc *desc = cm->desc; |
| 867 | struct power_supply *fuel_gauge; | 890 | struct power_supply *fuel_gauge = NULL; |
| 868 | int ret = 0; | 891 | int ret = 0; |
| 869 | int uV; | 892 | int uV; |
| 870 | 893 | ||
| @@ -900,26 +923,26 @@ static int charger_get_property(struct power_supply *psy, | |||
| 900 | ret = -ENODEV; | 923 | ret = -ENODEV; |
| 901 | break; | 924 | break; |
| 902 | } | 925 | } |
| 903 | ret = fuel_gauge->get_property(fuel_gauge, | 926 | ret = power_supply_get_property(fuel_gauge, |
| 904 | POWER_SUPPLY_PROP_CURRENT_NOW, val); | 927 | POWER_SUPPLY_PROP_CURRENT_NOW, val); |
| 905 | break; | 928 | break; |
| 906 | case POWER_SUPPLY_PROP_TEMP: | 929 | case POWER_SUPPLY_PROP_TEMP: |
| 907 | case POWER_SUPPLY_PROP_TEMP_AMBIENT: | 930 | case POWER_SUPPLY_PROP_TEMP_AMBIENT: |
| 908 | return cm_get_battery_temperature(cm, &val->intval); | 931 | return cm_get_battery_temperature(cm, &val->intval); |
| 909 | case POWER_SUPPLY_PROP_CAPACITY: | 932 | case POWER_SUPPLY_PROP_CAPACITY: |
| 910 | fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); | ||
| 911 | if (!fuel_gauge) { | ||
| 912 | ret = -ENODEV; | ||
| 913 | break; | ||
| 914 | } | ||
| 915 | |||
| 916 | if (!is_batt_present(cm)) { | 933 | if (!is_batt_present(cm)) { |
| 917 | /* There is no battery. Assume 100% */ | 934 | /* There is no battery. Assume 100% */ |
| 918 | val->intval = 100; | 935 | val->intval = 100; |
| 919 | break; | 936 | break; |
| 920 | } | 937 | } |
| 921 | 938 | ||
| 922 | ret = fuel_gauge->get_property(fuel_gauge, | 939 | fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); |
| 940 | if (!fuel_gauge) { | ||
| 941 | ret = -ENODEV; | ||
| 942 | break; | ||
| 943 | } | ||
| 944 | |||
| 945 | ret = power_supply_get_property(fuel_gauge, | ||
| 923 | POWER_SUPPLY_PROP_CAPACITY, val); | 946 | POWER_SUPPLY_PROP_CAPACITY, val); |
| 924 | if (ret) | 947 | if (ret) |
| 925 | break; | 948 | break; |
| @@ -975,7 +998,7 @@ static int charger_get_property(struct power_supply *psy, | |||
| 975 | break; | 998 | break; |
| 976 | } | 999 | } |
| 977 | 1000 | ||
| 978 | ret = fuel_gauge->get_property(fuel_gauge, | 1001 | ret = power_supply_get_property(fuel_gauge, |
| 979 | POWER_SUPPLY_PROP_CHARGE_NOW, | 1002 | POWER_SUPPLY_PROP_CHARGE_NOW, |
| 980 | val); | 1003 | val); |
| 981 | if (ret) { | 1004 | if (ret) { |
| @@ -993,6 +1016,8 @@ static int charger_get_property(struct power_supply *psy, | |||
| 993 | default: | 1016 | default: |
| 994 | return -EINVAL; | 1017 | return -EINVAL; |
| 995 | } | 1018 | } |
| 1019 | if (fuel_gauge) | ||
| 1020 | power_supply_put(fuel_gauge); | ||
| 996 | return ret; | 1021 | return ret; |
| 997 | } | 1022 | } |
| 998 | 1023 | ||
| @@ -1015,7 +1040,7 @@ static enum power_supply_property default_charger_props[] = { | |||
| 1015 | */ | 1040 | */ |
| 1016 | }; | 1041 | }; |
| 1017 | 1042 | ||
| 1018 | static struct power_supply psy_default = { | 1043 | static const struct power_supply_desc psy_default = { |
| 1019 | .name = "battery", | 1044 | .name = "battery", |
| 1020 | .type = POWER_SUPPLY_TYPE_BATTERY, | 1045 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 1021 | .properties = default_charger_props, | 1046 | .properties = default_charger_props, |
| @@ -1396,7 +1421,7 @@ static int charger_manager_register_sysfs(struct charger_manager *cm) | |||
| 1396 | dev_info(cm->dev, "'%s' regulator's externally_control is %d\n", | 1421 | dev_info(cm->dev, "'%s' regulator's externally_control is %d\n", |
| 1397 | charger->regulator_name, charger->externally_control); | 1422 | charger->regulator_name, charger->externally_control); |
| 1398 | 1423 | ||
| 1399 | ret = sysfs_create_group(&cm->charger_psy.dev->kobj, | 1424 | ret = sysfs_create_group(&cm->charger_psy->dev.kobj, |
| 1400 | &charger->attr_g); | 1425 | &charger->attr_g); |
| 1401 | if (ret < 0) { | 1426 | if (ret < 0) { |
| 1402 | dev_err(cm->dev, "Cannot create sysfs entry of %s regulator\n", | 1427 | dev_err(cm->dev, "Cannot create sysfs entry of %s regulator\n", |
| @@ -1424,13 +1449,13 @@ static int cm_init_thermal_data(struct charger_manager *cm, | |||
| 1424 | int ret; | 1449 | int ret; |
| 1425 | 1450 | ||
| 1426 | /* Verify whether fuel gauge provides battery temperature */ | 1451 | /* Verify whether fuel gauge provides battery temperature */ |
| 1427 | ret = fuel_gauge->get_property(fuel_gauge, | 1452 | ret = power_supply_get_property(fuel_gauge, |
| 1428 | POWER_SUPPLY_PROP_TEMP, &val); | 1453 | POWER_SUPPLY_PROP_TEMP, &val); |
| 1429 | 1454 | ||
| 1430 | if (!ret) { | 1455 | if (!ret) { |
| 1431 | cm->charger_psy.properties[cm->charger_psy.num_properties] = | 1456 | cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] = |
| 1432 | POWER_SUPPLY_PROP_TEMP; | 1457 | POWER_SUPPLY_PROP_TEMP; |
| 1433 | cm->charger_psy.num_properties++; | 1458 | cm->charger_psy_desc.num_properties++; |
| 1434 | cm->desc->measure_battery_temp = true; | 1459 | cm->desc->measure_battery_temp = true; |
| 1435 | } | 1460 | } |
| 1436 | #ifdef CONFIG_THERMAL | 1461 | #ifdef CONFIG_THERMAL |
| @@ -1441,9 +1466,9 @@ static int cm_init_thermal_data(struct charger_manager *cm, | |||
| 1441 | return PTR_ERR(cm->tzd_batt); | 1466 | return PTR_ERR(cm->tzd_batt); |
| 1442 | 1467 | ||
| 1443 | /* Use external thermometer */ | 1468 | /* Use external thermometer */ |
| 1444 | cm->charger_psy.properties[cm->charger_psy.num_properties] = | 1469 | cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] = |
| 1445 | POWER_SUPPLY_PROP_TEMP_AMBIENT; | 1470 | POWER_SUPPLY_PROP_TEMP_AMBIENT; |
| 1446 | cm->charger_psy.num_properties++; | 1471 | cm->charger_psy_desc.num_properties++; |
| 1447 | cm->desc->measure_battery_temp = true; | 1472 | cm->desc->measure_battery_temp = true; |
| 1448 | ret = 0; | 1473 | ret = 0; |
| 1449 | } | 1474 | } |
| @@ -1459,7 +1484,7 @@ static int cm_init_thermal_data(struct charger_manager *cm, | |||
| 1459 | return ret; | 1484 | return ret; |
| 1460 | } | 1485 | } |
| 1461 | 1486 | ||
| 1462 | static struct of_device_id charger_manager_match[] = { | 1487 | static const struct of_device_id charger_manager_match[] = { |
| 1463 | { | 1488 | { |
| 1464 | .compatible = "charger-manager", | 1489 | .compatible = "charger-manager", |
| 1465 | }, | 1490 | }, |
| @@ -1603,6 +1628,7 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
| 1603 | int j = 0; | 1628 | int j = 0; |
| 1604 | union power_supply_propval val; | 1629 | union power_supply_propval val; |
| 1605 | struct power_supply *fuel_gauge; | 1630 | struct power_supply *fuel_gauge; |
| 1631 | struct power_supply_config psy_cfg = {}; | ||
| 1606 | 1632 | ||
| 1607 | if (IS_ERR(desc)) { | 1633 | if (IS_ERR(desc)) { |
| 1608 | dev_err(&pdev->dev, "No platform data (desc) found\n"); | 1634 | dev_err(&pdev->dev, "No platform data (desc) found\n"); |
| @@ -1617,6 +1643,7 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
| 1617 | /* Basic Values. Unspecified are Null or 0 */ | 1643 | /* Basic Values. Unspecified are Null or 0 */ |
| 1618 | cm->dev = &pdev->dev; | 1644 | cm->dev = &pdev->dev; |
| 1619 | cm->desc = desc; | 1645 | cm->desc = desc; |
| 1646 | psy_cfg.drv_data = cm; | ||
| 1620 | 1647 | ||
| 1621 | /* Initialize alarm timer */ | 1648 | /* Initialize alarm timer */ |
| 1622 | if (alarmtimer_get_rtcdev()) { | 1649 | if (alarmtimer_get_rtcdev()) { |
| @@ -1672,13 +1699,7 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
| 1672 | desc->psy_charger_stat[i]); | 1699 | desc->psy_charger_stat[i]); |
| 1673 | return -ENODEV; | 1700 | return -ENODEV; |
| 1674 | } | 1701 | } |
| 1675 | } | 1702 | power_supply_put(psy); |
| 1676 | |||
| 1677 | fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); | ||
| 1678 | if (!fuel_gauge) { | ||
| 1679 | dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", | ||
| 1680 | desc->psy_fuel_gauge); | ||
| 1681 | return -ENODEV; | ||
| 1682 | } | 1703 | } |
| 1683 | 1704 | ||
| 1684 | if (desc->polling_interval_ms == 0 || | 1705 | if (desc->polling_interval_ms == 0 || |
| @@ -1696,40 +1717,46 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
| 1696 | 1717 | ||
| 1697 | platform_set_drvdata(pdev, cm); | 1718 | platform_set_drvdata(pdev, cm); |
| 1698 | 1719 | ||
| 1699 | memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default)); | 1720 | memcpy(&cm->charger_psy_desc, &psy_default, sizeof(psy_default)); |
| 1700 | 1721 | ||
| 1701 | if (!desc->psy_name) | 1722 | if (!desc->psy_name) |
| 1702 | strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); | 1723 | strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); |
| 1703 | else | 1724 | else |
| 1704 | strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); | 1725 | strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); |
| 1705 | cm->charger_psy.name = cm->psy_name_buf; | 1726 | cm->charger_psy_desc.name = cm->psy_name_buf; |
| 1706 | 1727 | ||
| 1707 | /* Allocate for psy properties because they may vary */ | 1728 | /* Allocate for psy properties because they may vary */ |
| 1708 | cm->charger_psy.properties = devm_kzalloc(&pdev->dev, | 1729 | cm->charger_psy_desc.properties = devm_kzalloc(&pdev->dev, |
| 1709 | sizeof(enum power_supply_property) | 1730 | sizeof(enum power_supply_property) |
| 1710 | * (ARRAY_SIZE(default_charger_props) + | 1731 | * (ARRAY_SIZE(default_charger_props) + |
| 1711 | NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL); | 1732 | NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL); |
| 1712 | if (!cm->charger_psy.properties) | 1733 | if (!cm->charger_psy_desc.properties) |
| 1713 | return -ENOMEM; | 1734 | return -ENOMEM; |
| 1714 | 1735 | ||
| 1715 | memcpy(cm->charger_psy.properties, default_charger_props, | 1736 | memcpy(cm->charger_psy_desc.properties, default_charger_props, |
| 1716 | sizeof(enum power_supply_property) * | 1737 | sizeof(enum power_supply_property) * |
| 1717 | ARRAY_SIZE(default_charger_props)); | 1738 | ARRAY_SIZE(default_charger_props)); |
| 1718 | cm->charger_psy.num_properties = psy_default.num_properties; | 1739 | cm->charger_psy_desc.num_properties = psy_default.num_properties; |
| 1719 | 1740 | ||
| 1720 | /* Find which optional psy-properties are available */ | 1741 | /* Find which optional psy-properties are available */ |
| 1721 | if (!fuel_gauge->get_property(fuel_gauge, | 1742 | fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); |
| 1743 | if (!fuel_gauge) { | ||
| 1744 | dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", | ||
| 1745 | desc->psy_fuel_gauge); | ||
| 1746 | return -ENODEV; | ||
| 1747 | } | ||
| 1748 | if (!power_supply_get_property(fuel_gauge, | ||
| 1722 | POWER_SUPPLY_PROP_CHARGE_NOW, &val)) { | 1749 | POWER_SUPPLY_PROP_CHARGE_NOW, &val)) { |
| 1723 | cm->charger_psy.properties[cm->charger_psy.num_properties] = | 1750 | cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] = |
| 1724 | POWER_SUPPLY_PROP_CHARGE_NOW; | 1751 | POWER_SUPPLY_PROP_CHARGE_NOW; |
| 1725 | cm->charger_psy.num_properties++; | 1752 | cm->charger_psy_desc.num_properties++; |
| 1726 | } | 1753 | } |
| 1727 | if (!fuel_gauge->get_property(fuel_gauge, | 1754 | if (!power_supply_get_property(fuel_gauge, |
| 1728 | POWER_SUPPLY_PROP_CURRENT_NOW, | 1755 | POWER_SUPPLY_PROP_CURRENT_NOW, |
| 1729 | &val)) { | 1756 | &val)) { |
| 1730 | cm->charger_psy.properties[cm->charger_psy.num_properties] = | 1757 | cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] = |
| 1731 | POWER_SUPPLY_PROP_CURRENT_NOW; | 1758 | POWER_SUPPLY_PROP_CURRENT_NOW; |
| 1732 | cm->charger_psy.num_properties++; | 1759 | cm->charger_psy_desc.num_properties++; |
| 1733 | } | 1760 | } |
| 1734 | 1761 | ||
| 1735 | ret = cm_init_thermal_data(cm, fuel_gauge); | 1762 | ret = cm_init_thermal_data(cm, fuel_gauge); |
| @@ -1737,14 +1764,16 @@ static int charger_manager_probe(struct platform_device *pdev) | |||
| 1737 | dev_err(&pdev->dev, "Failed to initialize thermal data\n"); | 1764 | dev_err(&pdev->dev, "Failed to initialize thermal data\n"); |
| 1738 | cm->desc->measure_battery_temp = false; | 1765 | cm->desc->measure_battery_temp = false; |
| 1739 | } | 1766 | } |
| 1767 | power_supply_put(fuel_gauge); | ||
| 1740 | 1768 | ||
| 1741 | INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk); | 1769 | INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk); |
| 1742 | 1770 | ||
| 1743 | ret = power_supply_register(NULL, &cm->charger_psy); | 1771 | cm->charger_psy = power_supply_register(NULL, &cm->charger_psy_desc, |
| 1744 | if (ret) { | 1772 | &psy_cfg); |
| 1773 | if (IS_ERR(cm->charger_psy)) { | ||
| 1745 | dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", | 1774 | dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", |
| 1746 | cm->charger_psy.name); | 1775 | cm->charger_psy_desc.name); |
| 1747 | return ret; | 1776 | return PTR_ERR(cm->charger_psy); |
| 1748 | } | 1777 | } |
| 1749 | 1778 | ||
| 1750 | /* Register extcon device for charger cable */ | 1779 | /* Register extcon device for charger cable */ |
| @@ -1790,7 +1819,7 @@ err_reg_sysfs: | |||
| 1790 | struct charger_regulator *charger; | 1819 | struct charger_regulator *charger; |
| 1791 | 1820 | ||
| 1792 | charger = &desc->charger_regulators[i]; | 1821 | charger = &desc->charger_regulators[i]; |
| 1793 | sysfs_remove_group(&cm->charger_psy.dev->kobj, | 1822 | sysfs_remove_group(&cm->charger_psy->dev.kobj, |
| 1794 | &charger->attr_g); | 1823 | &charger->attr_g); |
| 1795 | } | 1824 | } |
| 1796 | err_reg_extcon: | 1825 | err_reg_extcon: |
| @@ -1808,7 +1837,7 @@ err_reg_extcon: | |||
| 1808 | regulator_put(desc->charger_regulators[i].consumer); | 1837 | regulator_put(desc->charger_regulators[i].consumer); |
| 1809 | } | 1838 | } |
| 1810 | 1839 | ||
| 1811 | power_supply_unregister(&cm->charger_psy); | 1840 | power_supply_unregister(cm->charger_psy); |
| 1812 | 1841 | ||
| 1813 | return ret; | 1842 | return ret; |
| 1814 | } | 1843 | } |
| @@ -1840,7 +1869,7 @@ static int charger_manager_remove(struct platform_device *pdev) | |||
| 1840 | for (i = 0 ; i < desc->num_charger_regulators ; i++) | 1869 | for (i = 0 ; i < desc->num_charger_regulators ; i++) |
| 1841 | regulator_put(desc->charger_regulators[i].consumer); | 1870 | regulator_put(desc->charger_regulators[i].consumer); |
| 1842 | 1871 | ||
| 1843 | power_supply_unregister(&cm->charger_psy); | 1872 | power_supply_unregister(cm->charger_psy); |
| 1844 | 1873 | ||
| 1845 | try_charger_enable(cm, false); | 1874 | try_charger_enable(cm, false); |
| 1846 | 1875 | ||
| @@ -1999,7 +2028,7 @@ static bool find_power_supply(struct charger_manager *cm, | |||
| 1999 | bool found = false; | 2028 | bool found = false; |
| 2000 | 2029 | ||
| 2001 | for (i = 0; cm->desc->psy_charger_stat[i]; i++) { | 2030 | for (i = 0; cm->desc->psy_charger_stat[i]; i++) { |
| 2002 | if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) { | 2031 | if (!strcmp(psy->desc->name, cm->desc->psy_charger_stat[i])) { |
| 2003 | found = true; | 2032 | found = true; |
| 2004 | break; | 2033 | break; |
| 2005 | } | 2034 | } |
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index 594e4dbc2d51..2da9ed8ccbb5 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c | |||
| @@ -30,7 +30,7 @@ static int wakeup_enabled; | |||
| 30 | 30 | ||
| 31 | struct collie_bat { | 31 | struct collie_bat { |
| 32 | int status; | 32 | int status; |
| 33 | struct power_supply psy; | 33 | struct power_supply *psy; |
| 34 | int full_chrg; | 34 | int full_chrg; |
| 35 | 35 | ||
| 36 | struct mutex work_lock; /* protects data */ | 36 | struct mutex work_lock; /* protects data */ |
| @@ -98,7 +98,7 @@ static int collie_bat_get_property(struct power_supply *psy, | |||
| 98 | union power_supply_propval *val) | 98 | union power_supply_propval *val) |
| 99 | { | 99 | { |
| 100 | int ret = 0; | 100 | int ret = 0; |
| 101 | struct collie_bat *bat = container_of(psy, struct collie_bat, psy); | 101 | struct collie_bat *bat = power_supply_get_drvdata(psy); |
| 102 | 102 | ||
| 103 | if (bat->is_present && !bat->is_present(bat) | 103 | if (bat->is_present && !bat->is_present(bat) |
| 104 | && psp != POWER_SUPPLY_PROP_PRESENT) { | 104 | && psp != POWER_SUPPLY_PROP_PRESENT) { |
| @@ -155,14 +155,14 @@ static irqreturn_t collie_bat_gpio_isr(int irq, void *data) | |||
| 155 | static void collie_bat_update(struct collie_bat *bat) | 155 | static void collie_bat_update(struct collie_bat *bat) |
| 156 | { | 156 | { |
| 157 | int old; | 157 | int old; |
| 158 | struct power_supply *psy = &bat->psy; | 158 | struct power_supply *psy = bat->psy; |
| 159 | 159 | ||
| 160 | mutex_lock(&bat->work_lock); | 160 | mutex_lock(&bat->work_lock); |
| 161 | 161 | ||
| 162 | old = bat->status; | 162 | old = bat->status; |
| 163 | 163 | ||
| 164 | if (bat->is_present && !bat->is_present(bat)) { | 164 | if (bat->is_present && !bat->is_present(bat)) { |
| 165 | printk(KERN_NOTICE "%s not present\n", psy->name); | 165 | printk(KERN_NOTICE "%s not present\n", psy->desc->name); |
| 166 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; | 166 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; |
| 167 | bat->full_chrg = -1; | 167 | bat->full_chrg = -1; |
| 168 | } else if (power_supply_am_i_supplied(psy)) { | 168 | } else if (power_supply_am_i_supplied(psy)) { |
| @@ -220,18 +220,20 @@ static enum power_supply_property collie_bat_bu_props[] = { | |||
| 220 | POWER_SUPPLY_PROP_PRESENT, | 220 | POWER_SUPPLY_PROP_PRESENT, |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| 223 | static const struct power_supply_desc collie_bat_main_desc = { | ||
| 224 | .name = "main-battery", | ||
| 225 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 226 | .properties = collie_bat_main_props, | ||
| 227 | .num_properties = ARRAY_SIZE(collie_bat_main_props), | ||
| 228 | .get_property = collie_bat_get_property, | ||
| 229 | .external_power_changed = collie_bat_external_power_changed, | ||
| 230 | .use_for_apm = 1, | ||
| 231 | }; | ||
| 232 | |||
| 223 | static struct collie_bat collie_bat_main = { | 233 | static struct collie_bat collie_bat_main = { |
| 224 | .status = POWER_SUPPLY_STATUS_DISCHARGING, | 234 | .status = POWER_SUPPLY_STATUS_DISCHARGING, |
| 225 | .full_chrg = -1, | 235 | .full_chrg = -1, |
| 226 | .psy = { | 236 | .psy = NULL, |
| 227 | .name = "main-battery", | ||
| 228 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 229 | .properties = collie_bat_main_props, | ||
| 230 | .num_properties = ARRAY_SIZE(collie_bat_main_props), | ||
| 231 | .get_property = collie_bat_get_property, | ||
| 232 | .external_power_changed = collie_bat_external_power_changed, | ||
| 233 | .use_for_apm = 1, | ||
| 234 | }, | ||
| 235 | 237 | ||
| 236 | .gpio_full = COLLIE_GPIO_CO, | 238 | .gpio_full = COLLIE_GPIO_CO, |
| 237 | .gpio_charge_on = COLLIE_GPIO_CHARGE_ON, | 239 | .gpio_charge_on = COLLIE_GPIO_CHARGE_ON, |
| @@ -249,18 +251,19 @@ static struct collie_bat collie_bat_main = { | |||
| 249 | .adc_temp_divider = 10000, | 251 | .adc_temp_divider = 10000, |
| 250 | }; | 252 | }; |
| 251 | 253 | ||
| 254 | static const struct power_supply_desc collie_bat_bu_desc = { | ||
| 255 | .name = "backup-battery", | ||
| 256 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 257 | .properties = collie_bat_bu_props, | ||
| 258 | .num_properties = ARRAY_SIZE(collie_bat_bu_props), | ||
| 259 | .get_property = collie_bat_get_property, | ||
| 260 | .external_power_changed = collie_bat_external_power_changed, | ||
| 261 | }; | ||
| 262 | |||
| 252 | static struct collie_bat collie_bat_bu = { | 263 | static struct collie_bat collie_bat_bu = { |
| 253 | .status = POWER_SUPPLY_STATUS_UNKNOWN, | 264 | .status = POWER_SUPPLY_STATUS_UNKNOWN, |
| 254 | .full_chrg = -1, | 265 | .full_chrg = -1, |
| 255 | 266 | .psy = NULL, | |
| 256 | .psy = { | ||
| 257 | .name = "backup-battery", | ||
| 258 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 259 | .properties = collie_bat_bu_props, | ||
| 260 | .num_properties = ARRAY_SIZE(collie_bat_bu_props), | ||
| 261 | .get_property = collie_bat_get_property, | ||
| 262 | .external_power_changed = collie_bat_external_power_changed, | ||
| 263 | }, | ||
| 264 | 267 | ||
| 265 | .gpio_full = -1, | 268 | .gpio_full = -1, |
| 266 | .gpio_charge_on = -1, | 269 | .gpio_charge_on = -1, |
| @@ -319,6 +322,7 @@ static int collie_bat_resume(struct ucb1x00_dev *dev) | |||
| 319 | static int collie_bat_probe(struct ucb1x00_dev *dev) | 322 | static int collie_bat_probe(struct ucb1x00_dev *dev) |
| 320 | { | 323 | { |
| 321 | int ret; | 324 | int ret; |
| 325 | struct power_supply_config psy_main_cfg = {}, psy_bu_cfg = {}; | ||
| 322 | 326 | ||
| 323 | if (!machine_is_collie()) | 327 | if (!machine_is_collie()) |
| 324 | return -ENODEV; | 328 | return -ENODEV; |
| @@ -334,12 +338,23 @@ static int collie_bat_probe(struct ucb1x00_dev *dev) | |||
| 334 | 338 | ||
| 335 | INIT_WORK(&bat_work, collie_bat_work); | 339 | INIT_WORK(&bat_work, collie_bat_work); |
| 336 | 340 | ||
| 337 | ret = power_supply_register(&dev->ucb->dev, &collie_bat_main.psy); | 341 | psy_main_cfg.drv_data = &collie_bat_main; |
| 338 | if (ret) | 342 | collie_bat_main.psy = power_supply_register(&dev->ucb->dev, |
| 343 | &collie_bat_main_desc, | ||
| 344 | &psy_main_cfg); | ||
| 345 | if (IS_ERR(collie_bat_main.psy)) { | ||
| 346 | ret = PTR_ERR(collie_bat_main.psy); | ||
| 339 | goto err_psy_reg_main; | 347 | goto err_psy_reg_main; |
| 340 | ret = power_supply_register(&dev->ucb->dev, &collie_bat_bu.psy); | 348 | } |
| 341 | if (ret) | 349 | |
| 350 | psy_main_cfg.drv_data = &collie_bat_bu; | ||
| 351 | collie_bat_bu.psy = power_supply_register(&dev->ucb->dev, | ||
| 352 | &collie_bat_bu_desc, | ||
| 353 | &psy_bu_cfg); | ||
| 354 | if (IS_ERR(collie_bat_bu.psy)) { | ||
| 355 | ret = PTR_ERR(collie_bat_bu.psy); | ||
| 342 | goto err_psy_reg_bu; | 356 | goto err_psy_reg_bu; |
| 357 | } | ||
| 343 | 358 | ||
| 344 | ret = request_irq(gpio_to_irq(COLLIE_GPIO_CO), | 359 | ret = request_irq(gpio_to_irq(COLLIE_GPIO_CO), |
| 345 | collie_bat_gpio_isr, | 360 | collie_bat_gpio_isr, |
| @@ -354,9 +369,9 @@ static int collie_bat_probe(struct ucb1x00_dev *dev) | |||
| 354 | return 0; | 369 | return 0; |
| 355 | 370 | ||
| 356 | err_irq: | 371 | err_irq: |
| 357 | power_supply_unregister(&collie_bat_bu.psy); | 372 | power_supply_unregister(collie_bat_bu.psy); |
| 358 | err_psy_reg_bu: | 373 | err_psy_reg_bu: |
| 359 | power_supply_unregister(&collie_bat_main.psy); | 374 | power_supply_unregister(collie_bat_main.psy); |
| 360 | err_psy_reg_main: | 375 | err_psy_reg_main: |
| 361 | 376 | ||
| 362 | /* see comment in collie_bat_remove */ | 377 | /* see comment in collie_bat_remove */ |
| @@ -369,8 +384,8 @@ static void collie_bat_remove(struct ucb1x00_dev *dev) | |||
| 369 | { | 384 | { |
| 370 | free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); | 385 | free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); |
| 371 | 386 | ||
| 372 | power_supply_unregister(&collie_bat_bu.psy); | 387 | power_supply_unregister(collie_bat_bu.psy); |
| 373 | power_supply_unregister(&collie_bat_main.psy); | 388 | power_supply_unregister(collie_bat_main.psy); |
| 374 | 389 | ||
| 375 | /* | 390 | /* |
| 376 | * Now cancel the bat_work. We won't get any more schedules, | 391 | * Now cancel the bat_work. We won't get any more schedules, |
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c index 78cd5d66144b..5ca0f4d90792 100644 --- a/drivers/power/da9030_battery.c +++ b/drivers/power/da9030_battery.c | |||
| @@ -89,7 +89,8 @@ struct da9030_battery_thresholds { | |||
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | struct da9030_charger { | 91 | struct da9030_charger { |
| 92 | struct power_supply psy; | 92 | struct power_supply *psy; |
| 93 | struct power_supply_desc psy_desc; | ||
| 93 | 94 | ||
| 94 | struct device *master; | 95 | struct device *master; |
| 95 | 96 | ||
| @@ -245,7 +246,7 @@ static void da9030_set_charge(struct da9030_charger *charger, int on) | |||
| 245 | 246 | ||
| 246 | da903x_write(charger->master, DA9030_CHARGE_CONTROL, val); | 247 | da903x_write(charger->master, DA9030_CHARGE_CONTROL, val); |
| 247 | 248 | ||
| 248 | power_supply_changed(&charger->psy); | 249 | power_supply_changed(charger->psy); |
| 249 | } | 250 | } |
| 250 | 251 | ||
| 251 | static void da9030_charger_check_state(struct da9030_charger *charger) | 252 | static void da9030_charger_check_state(struct da9030_charger *charger) |
| @@ -341,8 +342,7 @@ static int da9030_battery_get_property(struct power_supply *psy, | |||
| 341 | enum power_supply_property psp, | 342 | enum power_supply_property psp, |
| 342 | union power_supply_propval *val) | 343 | union power_supply_propval *val) |
| 343 | { | 344 | { |
| 344 | struct da9030_charger *charger; | 345 | struct da9030_charger *charger = power_supply_get_drvdata(psy); |
| 345 | charger = container_of(psy, struct da9030_charger, psy); | ||
| 346 | 346 | ||
| 347 | switch (psp) { | 347 | switch (psp) { |
| 348 | case POWER_SUPPLY_PROP_STATUS: | 348 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -447,16 +447,16 @@ static void da9030_battery_convert_thresholds(struct da9030_charger *charger, | |||
| 447 | 447 | ||
| 448 | static void da9030_battery_setup_psy(struct da9030_charger *charger) | 448 | static void da9030_battery_setup_psy(struct da9030_charger *charger) |
| 449 | { | 449 | { |
| 450 | struct power_supply *psy = &charger->psy; | 450 | struct power_supply_desc *psy_desc = &charger->psy_desc; |
| 451 | struct power_supply_info *info = charger->battery_info; | 451 | struct power_supply_info *info = charger->battery_info; |
| 452 | 452 | ||
| 453 | psy->name = info->name; | 453 | psy_desc->name = info->name; |
| 454 | psy->use_for_apm = info->use_for_apm; | 454 | psy_desc->use_for_apm = info->use_for_apm; |
| 455 | psy->type = POWER_SUPPLY_TYPE_BATTERY; | 455 | psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; |
| 456 | psy->get_property = da9030_battery_get_property; | 456 | psy_desc->get_property = da9030_battery_get_property; |
| 457 | 457 | ||
| 458 | psy->properties = da9030_battery_props; | 458 | psy_desc->properties = da9030_battery_props; |
| 459 | psy->num_properties = ARRAY_SIZE(da9030_battery_props); | 459 | psy_desc->num_properties = ARRAY_SIZE(da9030_battery_props); |
| 460 | }; | 460 | }; |
| 461 | 461 | ||
| 462 | static int da9030_battery_charger_init(struct da9030_charger *charger) | 462 | static int da9030_battery_charger_init(struct da9030_charger *charger) |
| @@ -494,6 +494,7 @@ static int da9030_battery_charger_init(struct da9030_charger *charger) | |||
| 494 | static int da9030_battery_probe(struct platform_device *pdev) | 494 | static int da9030_battery_probe(struct platform_device *pdev) |
| 495 | { | 495 | { |
| 496 | struct da9030_charger *charger; | 496 | struct da9030_charger *charger; |
| 497 | struct power_supply_config psy_cfg = {}; | ||
| 497 | struct da9030_battery_info *pdata = pdev->dev.platform_data; | 498 | struct da9030_battery_info *pdata = pdev->dev.platform_data; |
| 498 | int ret; | 499 | int ret; |
| 499 | 500 | ||
| @@ -541,9 +542,13 @@ static int da9030_battery_probe(struct platform_device *pdev) | |||
| 541 | goto err_notifier; | 542 | goto err_notifier; |
| 542 | 543 | ||
| 543 | da9030_battery_setup_psy(charger); | 544 | da9030_battery_setup_psy(charger); |
| 544 | ret = power_supply_register(&pdev->dev, &charger->psy); | 545 | psy_cfg.drv_data = charger; |
| 545 | if (ret) | 546 | charger->psy = power_supply_register(&pdev->dev, &charger->psy_desc, |
| 547 | &psy_cfg); | ||
| 548 | if (IS_ERR(charger->psy)) { | ||
| 549 | ret = PTR_ERR(charger->psy); | ||
| 546 | goto err_ps_register; | 550 | goto err_ps_register; |
| 551 | } | ||
| 547 | 552 | ||
| 548 | charger->debug_file = da9030_bat_create_debugfs(charger); | 553 | charger->debug_file = da9030_bat_create_debugfs(charger); |
| 549 | platform_set_drvdata(pdev, charger); | 554 | platform_set_drvdata(pdev, charger); |
| @@ -571,7 +576,7 @@ static int da9030_battery_remove(struct platform_device *dev) | |||
| 571 | DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT); | 576 | DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT); |
| 572 | cancel_delayed_work_sync(&charger->work); | 577 | cancel_delayed_work_sync(&charger->work); |
| 573 | da9030_set_charge(charger, 0); | 578 | da9030_set_charge(charger, 0); |
| 574 | power_supply_unregister(&charger->psy); | 579 | power_supply_unregister(charger->psy); |
| 575 | 580 | ||
| 576 | return 0; | 581 | return 0; |
| 577 | } | 582 | } |
diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c index d17250f745c2..830ec46fe7d0 100644 --- a/drivers/power/da9052-battery.c +++ b/drivers/power/da9052-battery.c | |||
| @@ -169,7 +169,7 @@ static u32 const vc_tbl[3][68][2] = { | |||
| 169 | 169 | ||
| 170 | struct da9052_battery { | 170 | struct da9052_battery { |
| 171 | struct da9052 *da9052; | 171 | struct da9052 *da9052; |
| 172 | struct power_supply psy; | 172 | struct power_supply *psy; |
| 173 | struct notifier_block nb; | 173 | struct notifier_block nb; |
| 174 | int charger_type; | 174 | int charger_type; |
| 175 | int status; | 175 | int status; |
| @@ -452,7 +452,7 @@ static irqreturn_t da9052_bat_irq(int irq, void *data) | |||
| 452 | 452 | ||
| 453 | if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN || | 453 | if (irq == DA9052_IRQ_CHGEND || irq == DA9052_IRQ_DCIN || |
| 454 | irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) { | 454 | irq == DA9052_IRQ_VBUS || irq == DA9052_IRQ_TBAT) { |
| 455 | power_supply_changed(&bat->psy); | 455 | power_supply_changed(bat->psy); |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | return IRQ_HANDLED; | 458 | return IRQ_HANDLED; |
| @@ -499,8 +499,7 @@ static int da9052_bat_get_property(struct power_supply *psy, | |||
| 499 | { | 499 | { |
| 500 | int ret; | 500 | int ret; |
| 501 | int illegal; | 501 | int illegal; |
| 502 | struct da9052_battery *bat = container_of(psy, struct da9052_battery, | 502 | struct da9052_battery *bat = power_supply_get_drvdata(psy); |
| 503 | psy); | ||
| 504 | 503 | ||
| 505 | ret = da9052_bat_check_presence(bat, &illegal); | 504 | ret = da9052_bat_check_presence(bat, &illegal); |
| 506 | if (ret < 0) | 505 | if (ret < 0) |
| @@ -561,7 +560,7 @@ static enum power_supply_property da9052_bat_props[] = { | |||
| 561 | POWER_SUPPLY_PROP_TECHNOLOGY, | 560 | POWER_SUPPLY_PROP_TECHNOLOGY, |
| 562 | }; | 561 | }; |
| 563 | 562 | ||
| 564 | static struct power_supply template_battery = { | 563 | static struct power_supply_desc psy_desc = { |
| 565 | .name = "da9052-bat", | 564 | .name = "da9052-bat", |
| 566 | .type = POWER_SUPPLY_TYPE_BATTERY, | 565 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 567 | .properties = da9052_bat_props, | 566 | .properties = da9052_bat_props, |
| @@ -591,6 +590,7 @@ static s32 da9052_bat_probe(struct platform_device *pdev) | |||
| 591 | { | 590 | { |
| 592 | struct da9052_pdata *pdata; | 591 | struct da9052_pdata *pdata; |
| 593 | struct da9052_battery *bat; | 592 | struct da9052_battery *bat; |
| 593 | struct power_supply_config psy_cfg = {}; | ||
| 594 | int ret; | 594 | int ret; |
| 595 | int i; | 595 | int i; |
| 596 | 596 | ||
| @@ -599,8 +599,9 @@ static s32 da9052_bat_probe(struct platform_device *pdev) | |||
| 599 | if (!bat) | 599 | if (!bat) |
| 600 | return -ENOMEM; | 600 | return -ENOMEM; |
| 601 | 601 | ||
| 602 | psy_cfg.drv_data = bat; | ||
| 603 | |||
| 602 | bat->da9052 = dev_get_drvdata(pdev->dev.parent); | 604 | bat->da9052 = dev_get_drvdata(pdev->dev.parent); |
| 603 | bat->psy = template_battery; | ||
| 604 | bat->charger_type = DA9052_NOCHARGER; | 605 | bat->charger_type = DA9052_NOCHARGER; |
| 605 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; | 606 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; |
| 606 | bat->health = POWER_SUPPLY_HEALTH_UNKNOWN; | 607 | bat->health = POWER_SUPPLY_HEALTH_UNKNOWN; |
| @@ -608,9 +609,9 @@ static s32 da9052_bat_probe(struct platform_device *pdev) | |||
| 608 | 609 | ||
| 609 | pdata = bat->da9052->dev->platform_data; | 610 | pdata = bat->da9052->dev->platform_data; |
| 610 | if (pdata != NULL && pdata->use_for_apm) | 611 | if (pdata != NULL && pdata->use_for_apm) |
| 611 | bat->psy.use_for_apm = pdata->use_for_apm; | 612 | psy_desc.use_for_apm = pdata->use_for_apm; |
| 612 | else | 613 | else |
| 613 | bat->psy.use_for_apm = 1; | 614 | psy_desc.use_for_apm = 1; |
| 614 | 615 | ||
| 615 | for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) { | 616 | for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) { |
| 616 | ret = da9052_request_irq(bat->da9052, | 617 | ret = da9052_request_irq(bat->da9052, |
| @@ -625,9 +626,11 @@ static s32 da9052_bat_probe(struct platform_device *pdev) | |||
| 625 | } | 626 | } |
| 626 | } | 627 | } |
| 627 | 628 | ||
| 628 | ret = power_supply_register(&pdev->dev, &bat->psy); | 629 | bat->psy = power_supply_register(&pdev->dev, &psy_desc, &psy_cfg); |
| 629 | if (ret) | 630 | if (IS_ERR(bat->psy)) { |
| 631 | ret = PTR_ERR(bat->psy); | ||
| 630 | goto err; | 632 | goto err; |
| 633 | } | ||
| 631 | 634 | ||
| 632 | platform_set_drvdata(pdev, bat); | 635 | platform_set_drvdata(pdev, bat); |
| 633 | return 0; | 636 | return 0; |
| @@ -646,7 +649,7 @@ static int da9052_bat_remove(struct platform_device *pdev) | |||
| 646 | for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) | 649 | for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) |
| 647 | da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); | 650 | da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat); |
| 648 | 651 | ||
| 649 | power_supply_unregister(&bat->psy); | 652 | power_supply_unregister(bat->psy); |
| 650 | 653 | ||
| 651 | return 0; | 654 | return 0; |
| 652 | } | 655 | } |
diff --git a/drivers/power/da9150-charger.c b/drivers/power/da9150-charger.c new file mode 100644 index 000000000000..60099815296e --- /dev/null +++ b/drivers/power/da9150-charger.c | |||
| @@ -0,0 +1,694 @@ | |||
| 1 | /* | ||
| 2 | * DA9150 Charger Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Dialog Semiconductor | ||
| 5 | * | ||
| 6 | * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/of_platform.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/power_supply.h> | ||
| 22 | #include <linux/notifier.h> | ||
| 23 | #include <linux/usb/phy.h> | ||
| 24 | #include <linux/iio/consumer.h> | ||
| 25 | #include <linux/mfd/da9150/core.h> | ||
| 26 | #include <linux/mfd/da9150/registers.h> | ||
| 27 | |||
| 28 | /* Private data */ | ||
| 29 | struct da9150_charger { | ||
| 30 | struct da9150 *da9150; | ||
| 31 | struct device *dev; | ||
| 32 | |||
| 33 | struct power_supply *usb; | ||
| 34 | struct power_supply *battery; | ||
| 35 | struct power_supply *supply_online; | ||
| 36 | |||
| 37 | struct usb_phy *usb_phy; | ||
| 38 | struct notifier_block otg_nb; | ||
| 39 | struct work_struct otg_work; | ||
| 40 | unsigned long usb_event; | ||
| 41 | |||
| 42 | struct iio_channel *ibus_chan; | ||
| 43 | struct iio_channel *vbus_chan; | ||
| 44 | struct iio_channel *tjunc_chan; | ||
| 45 | struct iio_channel *vbat_chan; | ||
| 46 | }; | ||
| 47 | |||
| 48 | static inline int da9150_charger_supply_online(struct da9150_charger *charger, | ||
| 49 | struct power_supply *psy, | ||
| 50 | union power_supply_propval *val) | ||
| 51 | { | ||
| 52 | val->intval = (psy == charger->supply_online) ? 1 : 0; | ||
| 53 | |||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | /* Charger Properties */ | ||
| 58 | static int da9150_charger_vbus_voltage_now(struct da9150_charger *charger, | ||
| 59 | union power_supply_propval *val) | ||
| 60 | { | ||
| 61 | int v_val, ret; | ||
| 62 | |||
| 63 | /* Read processed value - mV units */ | ||
| 64 | ret = iio_read_channel_processed(charger->vbus_chan, &v_val); | ||
| 65 | if (ret < 0) | ||
| 66 | return ret; | ||
| 67 | |||
| 68 | /* Convert voltage to expected uV units */ | ||
| 69 | val->intval = v_val * 1000; | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int da9150_charger_ibus_current_avg(struct da9150_charger *charger, | ||
| 75 | union power_supply_propval *val) | ||
| 76 | { | ||
| 77 | int i_val, ret; | ||
| 78 | |||
| 79 | /* Read processed value - mA units */ | ||
| 80 | ret = iio_read_channel_processed(charger->ibus_chan, &i_val); | ||
| 81 | if (ret < 0) | ||
| 82 | return ret; | ||
| 83 | |||
| 84 | /* Convert current to expected uA units */ | ||
| 85 | val->intval = i_val * 1000; | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int da9150_charger_tjunc_temp(struct da9150_charger *charger, | ||
| 91 | union power_supply_propval *val) | ||
| 92 | { | ||
| 93 | int t_val, ret; | ||
| 94 | |||
| 95 | /* Read processed value - 0.001 degrees C units */ | ||
| 96 | ret = iio_read_channel_processed(charger->tjunc_chan, &t_val); | ||
| 97 | if (ret < 0) | ||
| 98 | return ret; | ||
| 99 | |||
| 100 | /* Convert temp to expect 0.1 degrees C units */ | ||
| 101 | val->intval = t_val / 100; | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static enum power_supply_property da9150_charger_props[] = { | ||
| 107 | POWER_SUPPLY_PROP_ONLINE, | ||
| 108 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 109 | POWER_SUPPLY_PROP_CURRENT_AVG, | ||
| 110 | POWER_SUPPLY_PROP_TEMP, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static int da9150_charger_get_prop(struct power_supply *psy, | ||
| 114 | enum power_supply_property psp, | ||
| 115 | union power_supply_propval *val) | ||
| 116 | { | ||
| 117 | struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent); | ||
| 118 | int ret; | ||
| 119 | |||
| 120 | switch (psp) { | ||
| 121 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 122 | ret = da9150_charger_supply_online(charger, psy, val); | ||
| 123 | break; | ||
| 124 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 125 | ret = da9150_charger_vbus_voltage_now(charger, val); | ||
| 126 | break; | ||
| 127 | case POWER_SUPPLY_PROP_CURRENT_AVG: | ||
| 128 | ret = da9150_charger_ibus_current_avg(charger, val); | ||
| 129 | break; | ||
| 130 | case POWER_SUPPLY_PROP_TEMP: | ||
| 131 | ret = da9150_charger_tjunc_temp(charger, val); | ||
| 132 | break; | ||
| 133 | default: | ||
| 134 | ret = -EINVAL; | ||
| 135 | break; | ||
| 136 | } | ||
| 137 | |||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Battery Properties */ | ||
| 142 | static int da9150_charger_battery_status(struct da9150_charger *charger, | ||
| 143 | union power_supply_propval *val) | ||
| 144 | { | ||
| 145 | u8 reg; | ||
| 146 | |||
| 147 | /* Check to see if battery is discharging */ | ||
| 148 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H); | ||
| 149 | |||
| 150 | if (((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_OFF) || | ||
| 151 | ((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_WAIT)) { | ||
| 152 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J); | ||
| 158 | |||
| 159 | /* Now check for other states */ | ||
| 160 | switch (reg & DA9150_CHG_STAT_MASK) { | ||
| 161 | case DA9150_CHG_STAT_ACT: | ||
| 162 | case DA9150_CHG_STAT_PRE: | ||
| 163 | case DA9150_CHG_STAT_CC: | ||
| 164 | case DA9150_CHG_STAT_CV: | ||
| 165 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | ||
| 166 | break; | ||
| 167 | case DA9150_CHG_STAT_OFF: | ||
| 168 | case DA9150_CHG_STAT_SUSP: | ||
| 169 | case DA9150_CHG_STAT_TEMP: | ||
| 170 | case DA9150_CHG_STAT_TIME: | ||
| 171 | case DA9150_CHG_STAT_BAT: | ||
| 172 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
| 173 | break; | ||
| 174 | case DA9150_CHG_STAT_FULL: | ||
| 175 | val->intval = POWER_SUPPLY_STATUS_FULL; | ||
| 176 | break; | ||
| 177 | default: | ||
| 178 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int da9150_charger_battery_health(struct da9150_charger *charger, | ||
| 186 | union power_supply_propval *val) | ||
| 187 | { | ||
| 188 | u8 reg; | ||
| 189 | |||
| 190 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J); | ||
| 191 | |||
| 192 | /* Check if temperature limit reached */ | ||
| 193 | switch (reg & DA9150_CHG_TEMP_MASK) { | ||
| 194 | case DA9150_CHG_TEMP_UNDER: | ||
| 195 | val->intval = POWER_SUPPLY_HEALTH_COLD; | ||
| 196 | return 0; | ||
| 197 | case DA9150_CHG_TEMP_OVER: | ||
| 198 | val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; | ||
| 199 | return 0; | ||
| 200 | default: | ||
| 201 | break; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* Check for other health states */ | ||
| 205 | switch (reg & DA9150_CHG_STAT_MASK) { | ||
| 206 | case DA9150_CHG_STAT_ACT: | ||
| 207 | case DA9150_CHG_STAT_PRE: | ||
| 208 | val->intval = POWER_SUPPLY_HEALTH_DEAD; | ||
| 209 | break; | ||
| 210 | case DA9150_CHG_STAT_TIME: | ||
| 211 | val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; | ||
| 212 | break; | ||
| 213 | default: | ||
| 214 | val->intval = POWER_SUPPLY_HEALTH_GOOD; | ||
| 215 | break; | ||
| 216 | } | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int da9150_charger_battery_present(struct da9150_charger *charger, | ||
| 222 | union power_supply_propval *val) | ||
| 223 | { | ||
| 224 | u8 reg; | ||
| 225 | |||
| 226 | /* Check if battery present or removed */ | ||
| 227 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J); | ||
| 228 | if ((reg & DA9150_CHG_STAT_MASK) == DA9150_CHG_STAT_BAT) | ||
| 229 | val->intval = 0; | ||
| 230 | else | ||
| 231 | val->intval = 1; | ||
| 232 | |||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | static int da9150_charger_battery_charge_type(struct da9150_charger *charger, | ||
| 237 | union power_supply_propval *val) | ||
| 238 | { | ||
| 239 | u8 reg; | ||
| 240 | |||
| 241 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J); | ||
| 242 | |||
| 243 | switch (reg & DA9150_CHG_STAT_MASK) { | ||
| 244 | case DA9150_CHG_STAT_CC: | ||
| 245 | val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; | ||
| 246 | break; | ||
| 247 | case DA9150_CHG_STAT_ACT: | ||
| 248 | case DA9150_CHG_STAT_PRE: | ||
| 249 | case DA9150_CHG_STAT_CV: | ||
| 250 | val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; | ||
| 251 | break; | ||
| 252 | default: | ||
| 253 | val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; | ||
| 254 | break; | ||
| 255 | } | ||
| 256 | |||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | static int da9150_charger_battery_voltage_min(struct da9150_charger *charger, | ||
| 261 | union power_supply_propval *val) | ||
| 262 | { | ||
| 263 | u8 reg; | ||
| 264 | |||
| 265 | reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_C); | ||
| 266 | |||
| 267 | /* Value starts at 2500 mV, 50 mV increments, presented in uV */ | ||
| 268 | val->intval = ((reg & DA9150_CHG_VFAULT_MASK) * 50000) + 2500000; | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int da9150_charger_battery_voltage_now(struct da9150_charger *charger, | ||
| 274 | union power_supply_propval *val) | ||
| 275 | { | ||
| 276 | int v_val, ret; | ||
| 277 | |||
| 278 | /* Read processed value - mV units */ | ||
| 279 | ret = iio_read_channel_processed(charger->vbat_chan, &v_val); | ||
| 280 | if (ret < 0) | ||
| 281 | return ret; | ||
| 282 | |||
| 283 | val->intval = v_val * 1000; | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int da9150_charger_battery_current_max(struct da9150_charger *charger, | ||
| 289 | union power_supply_propval *val) | ||
| 290 | { | ||
| 291 | int reg; | ||
| 292 | |||
| 293 | reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_D); | ||
| 294 | |||
| 295 | /* 25mA increments */ | ||
| 296 | val->intval = reg * 25000; | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | static int da9150_charger_battery_voltage_max(struct da9150_charger *charger, | ||
| 302 | union power_supply_propval *val) | ||
| 303 | { | ||
| 304 | u8 reg; | ||
| 305 | |||
| 306 | reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_B); | ||
| 307 | |||
| 308 | /* Value starts at 3650 mV, 25 mV increments, presented in uV */ | ||
| 309 | val->intval = ((reg & DA9150_CHG_VBAT_MASK) * 25000) + 3650000; | ||
| 310 | return 0; | ||
| 311 | } | ||
| 312 | |||
| 313 | static enum power_supply_property da9150_charger_bat_props[] = { | ||
| 314 | POWER_SUPPLY_PROP_STATUS, | ||
| 315 | POWER_SUPPLY_PROP_ONLINE, | ||
| 316 | POWER_SUPPLY_PROP_HEALTH, | ||
| 317 | POWER_SUPPLY_PROP_PRESENT, | ||
| 318 | POWER_SUPPLY_PROP_CHARGE_TYPE, | ||
| 319 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
| 320 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 321 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, | ||
| 322 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, | ||
| 323 | }; | ||
| 324 | |||
| 325 | static int da9150_charger_battery_get_prop(struct power_supply *psy, | ||
| 326 | enum power_supply_property psp, | ||
| 327 | union power_supply_propval *val) | ||
| 328 | { | ||
| 329 | struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent); | ||
| 330 | int ret; | ||
| 331 | |||
| 332 | switch (psp) { | ||
| 333 | case POWER_SUPPLY_PROP_STATUS: | ||
| 334 | ret = da9150_charger_battery_status(charger, val); | ||
| 335 | break; | ||
| 336 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 337 | ret = da9150_charger_supply_online(charger, psy, val); | ||
| 338 | break; | ||
| 339 | case POWER_SUPPLY_PROP_HEALTH: | ||
| 340 | ret = da9150_charger_battery_health(charger, val); | ||
| 341 | break; | ||
| 342 | case POWER_SUPPLY_PROP_PRESENT: | ||
| 343 | ret = da9150_charger_battery_present(charger, val); | ||
| 344 | break; | ||
| 345 | case POWER_SUPPLY_PROP_CHARGE_TYPE: | ||
| 346 | ret = da9150_charger_battery_charge_type(charger, val); | ||
| 347 | break; | ||
| 348 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | ||
| 349 | ret = da9150_charger_battery_voltage_min(charger, val); | ||
| 350 | break; | ||
| 351 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 352 | ret = da9150_charger_battery_voltage_now(charger, val); | ||
| 353 | break; | ||
| 354 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: | ||
| 355 | ret = da9150_charger_battery_current_max(charger, val); | ||
| 356 | break; | ||
| 357 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: | ||
| 358 | ret = da9150_charger_battery_voltage_max(charger, val); | ||
| 359 | break; | ||
| 360 | default: | ||
| 361 | ret = -EINVAL; | ||
| 362 | break; | ||
| 363 | } | ||
| 364 | |||
| 365 | return ret; | ||
| 366 | } | ||
| 367 | |||
| 368 | static irqreturn_t da9150_charger_chg_irq(int irq, void *data) | ||
| 369 | { | ||
| 370 | struct da9150_charger *charger = data; | ||
| 371 | |||
| 372 | power_supply_changed(charger->battery); | ||
| 373 | |||
| 374 | return IRQ_HANDLED; | ||
| 375 | } | ||
| 376 | |||
| 377 | static irqreturn_t da9150_charger_tjunc_irq(int irq, void *data) | ||
| 378 | { | ||
| 379 | struct da9150_charger *charger = data; | ||
| 380 | |||
| 381 | /* Nothing we can really do except report this. */ | ||
| 382 | dev_crit(charger->dev, "TJunc over temperature!!!\n"); | ||
| 383 | power_supply_changed(charger->usb); | ||
| 384 | |||
| 385 | return IRQ_HANDLED; | ||
| 386 | } | ||
| 387 | |||
| 388 | static irqreturn_t da9150_charger_vfault_irq(int irq, void *data) | ||
| 389 | { | ||
| 390 | struct da9150_charger *charger = data; | ||
| 391 | |||
| 392 | /* Nothing we can really do except report this. */ | ||
| 393 | dev_crit(charger->dev, "VSYS under voltage!!!\n"); | ||
| 394 | power_supply_changed(charger->usb); | ||
| 395 | power_supply_changed(charger->battery); | ||
| 396 | |||
| 397 | return IRQ_HANDLED; | ||
| 398 | } | ||
| 399 | |||
| 400 | static irqreturn_t da9150_charger_vbus_irq(int irq, void *data) | ||
| 401 | { | ||
| 402 | struct da9150_charger *charger = data; | ||
| 403 | u8 reg; | ||
| 404 | |||
| 405 | reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H); | ||
| 406 | |||
| 407 | /* Charger plugged in or battery only */ | ||
| 408 | switch (reg & DA9150_VBUS_STAT_MASK) { | ||
| 409 | case DA9150_VBUS_STAT_OFF: | ||
| 410 | case DA9150_VBUS_STAT_WAIT: | ||
| 411 | charger->supply_online = charger->battery; | ||
| 412 | break; | ||
| 413 | case DA9150_VBUS_STAT_CHG: | ||
| 414 | charger->supply_online = charger->usb; | ||
| 415 | break; | ||
| 416 | default: | ||
| 417 | dev_warn(charger->dev, "Unknown VBUS state - reg = 0x%x\n", | ||
| 418 | reg); | ||
| 419 | charger->supply_online = NULL; | ||
| 420 | break; | ||
| 421 | } | ||
| 422 | |||
| 423 | power_supply_changed(charger->usb); | ||
| 424 | power_supply_changed(charger->battery); | ||
| 425 | |||
| 426 | return IRQ_HANDLED; | ||
| 427 | } | ||
| 428 | |||
| 429 | static void da9150_charger_otg_work(struct work_struct *data) | ||
| 430 | { | ||
| 431 | struct da9150_charger *charger = | ||
| 432 | container_of(data, struct da9150_charger, otg_work); | ||
| 433 | |||
| 434 | switch (charger->usb_event) { | ||
| 435 | case USB_EVENT_ID: | ||
| 436 | /* Enable OTG Boost */ | ||
| 437 | da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A, | ||
| 438 | DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_OTG); | ||
| 439 | break; | ||
| 440 | case USB_EVENT_NONE: | ||
| 441 | /* Revert to charge mode */ | ||
| 442 | power_supply_changed(charger->usb); | ||
| 443 | power_supply_changed(charger->battery); | ||
| 444 | da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A, | ||
| 445 | DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_CHG); | ||
| 446 | break; | ||
| 447 | } | ||
| 448 | } | ||
| 449 | |||
| 450 | static int da9150_charger_otg_ncb(struct notifier_block *nb, unsigned long val, | ||
| 451 | void *priv) | ||
| 452 | { | ||
| 453 | struct da9150_charger *charger = | ||
| 454 | container_of(nb, struct da9150_charger, otg_nb); | ||
| 455 | |||
| 456 | dev_dbg(charger->dev, "DA9150 OTG notify %lu\n", val); | ||
| 457 | |||
| 458 | charger->usb_event = val; | ||
| 459 | schedule_work(&charger->otg_work); | ||
| 460 | |||
| 461 | return NOTIFY_OK; | ||
| 462 | } | ||
| 463 | |||
| 464 | static int da9150_charger_register_irq(struct platform_device *pdev, | ||
| 465 | irq_handler_t handler, | ||
| 466 | const char *irq_name) | ||
| 467 | { | ||
| 468 | struct device *dev = &pdev->dev; | ||
| 469 | struct da9150_charger *charger = platform_get_drvdata(pdev); | ||
| 470 | int irq, ret; | ||
| 471 | |||
| 472 | irq = platform_get_irq_byname(pdev, irq_name); | ||
| 473 | if (irq < 0) { | ||
| 474 | dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq); | ||
| 475 | return irq; | ||
| 476 | } | ||
| 477 | |||
| 478 | ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, irq_name, | ||
| 479 | charger); | ||
| 480 | if (ret) | ||
| 481 | dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret); | ||
| 482 | |||
| 483 | return ret; | ||
| 484 | } | ||
| 485 | |||
| 486 | static void da9150_charger_unregister_irq(struct platform_device *pdev, | ||
| 487 | const char *irq_name) | ||
| 488 | { | ||
| 489 | struct device *dev = &pdev->dev; | ||
| 490 | struct da9150_charger *charger = platform_get_drvdata(pdev); | ||
| 491 | int irq; | ||
| 492 | |||
| 493 | irq = platform_get_irq_byname(pdev, irq_name); | ||
| 494 | if (irq < 0) { | ||
| 495 | dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq); | ||
| 496 | return; | ||
| 497 | } | ||
| 498 | |||
| 499 | free_irq(irq, charger); | ||
| 500 | } | ||
| 501 | |||
| 502 | static const struct power_supply_desc usb_desc = { | ||
| 503 | .name = "da9150-usb", | ||
| 504 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 505 | .properties = da9150_charger_props, | ||
| 506 | .num_properties = ARRAY_SIZE(da9150_charger_props), | ||
| 507 | .get_property = da9150_charger_get_prop, | ||
| 508 | }; | ||
| 509 | |||
| 510 | static const struct power_supply_desc battery_desc = { | ||
| 511 | .name = "da9150-battery", | ||
| 512 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 513 | .properties = da9150_charger_bat_props, | ||
| 514 | .num_properties = ARRAY_SIZE(da9150_charger_bat_props), | ||
| 515 | .get_property = da9150_charger_battery_get_prop, | ||
| 516 | }; | ||
| 517 | |||
| 518 | static int da9150_charger_probe(struct platform_device *pdev) | ||
| 519 | { | ||
| 520 | struct device *dev = &pdev->dev; | ||
| 521 | struct da9150 *da9150 = dev_get_drvdata(dev->parent); | ||
| 522 | struct da9150_charger *charger; | ||
| 523 | u8 reg; | ||
| 524 | int ret; | ||
| 525 | |||
| 526 | charger = devm_kzalloc(dev, sizeof(struct da9150_charger), GFP_KERNEL); | ||
| 527 | if (!charger) | ||
| 528 | return -ENOMEM; | ||
| 529 | |||
| 530 | platform_set_drvdata(pdev, charger); | ||
| 531 | charger->da9150 = da9150; | ||
| 532 | charger->dev = dev; | ||
| 533 | |||
| 534 | /* Acquire ADC channels */ | ||
| 535 | charger->ibus_chan = iio_channel_get(dev, "CHAN_IBUS"); | ||
| 536 | if (IS_ERR(charger->ibus_chan)) { | ||
| 537 | ret = PTR_ERR(charger->ibus_chan); | ||
| 538 | goto ibus_chan_fail; | ||
| 539 | } | ||
| 540 | |||
| 541 | charger->vbus_chan = iio_channel_get(dev, "CHAN_VBUS"); | ||
| 542 | if (IS_ERR(charger->vbus_chan)) { | ||
| 543 | ret = PTR_ERR(charger->vbus_chan); | ||
| 544 | goto vbus_chan_fail; | ||
| 545 | } | ||
| 546 | |||
| 547 | charger->tjunc_chan = iio_channel_get(dev, "CHAN_TJUNC"); | ||
| 548 | if (IS_ERR(charger->tjunc_chan)) { | ||
| 549 | ret = PTR_ERR(charger->tjunc_chan); | ||
| 550 | goto tjunc_chan_fail; | ||
| 551 | } | ||
| 552 | |||
| 553 | charger->vbat_chan = iio_channel_get(dev, "CHAN_VBAT"); | ||
| 554 | if (IS_ERR(charger->vbat_chan)) { | ||
| 555 | ret = PTR_ERR(charger->vbat_chan); | ||
| 556 | goto vbat_chan_fail; | ||
| 557 | } | ||
| 558 | |||
| 559 | /* Register power supplies */ | ||
| 560 | charger->usb = power_supply_register(dev, &usb_desc, NULL); | ||
| 561 | if (IS_ERR(charger->usb)) { | ||
| 562 | ret = PTR_ERR(charger->usb); | ||
| 563 | goto usb_fail; | ||
| 564 | } | ||
| 565 | |||
| 566 | charger->battery = power_supply_register(dev, &battery_desc, NULL); | ||
| 567 | if (IS_ERR(charger->battery)) { | ||
| 568 | ret = PTR_ERR(charger->battery); | ||
| 569 | goto battery_fail; | ||
| 570 | } | ||
| 571 | |||
| 572 | /* Get initial online supply */ | ||
| 573 | reg = da9150_reg_read(da9150, DA9150_STATUS_H); | ||
| 574 | |||
| 575 | switch (reg & DA9150_VBUS_STAT_MASK) { | ||
| 576 | case DA9150_VBUS_STAT_OFF: | ||
| 577 | case DA9150_VBUS_STAT_WAIT: | ||
| 578 | charger->supply_online = charger->battery; | ||
| 579 | break; | ||
| 580 | case DA9150_VBUS_STAT_CHG: | ||
| 581 | charger->supply_online = charger->usb; | ||
| 582 | break; | ||
| 583 | default: | ||
| 584 | dev_warn(dev, "Unknown VBUS state - reg = 0x%x\n", reg); | ||
| 585 | charger->supply_online = NULL; | ||
| 586 | break; | ||
| 587 | } | ||
| 588 | |||
| 589 | /* Setup OTG reporting & configuration */ | ||
| 590 | charger->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
| 591 | if (!IS_ERR_OR_NULL(charger->usb_phy)) { | ||
| 592 | INIT_WORK(&charger->otg_work, da9150_charger_otg_work); | ||
| 593 | charger->otg_nb.notifier_call = da9150_charger_otg_ncb; | ||
| 594 | usb_register_notifier(charger->usb_phy, &charger->otg_nb); | ||
| 595 | } | ||
| 596 | |||
| 597 | /* Register IRQs */ | ||
| 598 | ret = da9150_charger_register_irq(pdev, da9150_charger_chg_irq, | ||
| 599 | "CHG_STATUS"); | ||
| 600 | if (ret < 0) | ||
| 601 | goto chg_irq_fail; | ||
| 602 | |||
| 603 | ret = da9150_charger_register_irq(pdev, da9150_charger_tjunc_irq, | ||
| 604 | "CHG_TJUNC"); | ||
| 605 | if (ret < 0) | ||
| 606 | goto tjunc_irq_fail; | ||
| 607 | |||
| 608 | ret = da9150_charger_register_irq(pdev, da9150_charger_vfault_irq, | ||
| 609 | "CHG_VFAULT"); | ||
| 610 | if (ret < 0) | ||
| 611 | goto vfault_irq_fail; | ||
| 612 | |||
| 613 | ret = da9150_charger_register_irq(pdev, da9150_charger_vbus_irq, | ||
| 614 | "CHG_VBUS"); | ||
| 615 | if (ret < 0) | ||
| 616 | goto vbus_irq_fail; | ||
| 617 | |||
| 618 | return 0; | ||
| 619 | |||
| 620 | |||
| 621 | vbus_irq_fail: | ||
| 622 | da9150_charger_unregister_irq(pdev, "CHG_VFAULT"); | ||
| 623 | vfault_irq_fail: | ||
| 624 | da9150_charger_unregister_irq(pdev, "CHG_TJUNC"); | ||
| 625 | tjunc_irq_fail: | ||
| 626 | da9150_charger_unregister_irq(pdev, "CHG_STATUS"); | ||
| 627 | chg_irq_fail: | ||
| 628 | if (!IS_ERR_OR_NULL(charger->usb_phy)) | ||
| 629 | usb_unregister_notifier(charger->usb_phy, &charger->otg_nb); | ||
| 630 | battery_fail: | ||
| 631 | power_supply_unregister(charger->usb); | ||
| 632 | |||
| 633 | usb_fail: | ||
| 634 | iio_channel_release(charger->vbat_chan); | ||
| 635 | |||
| 636 | vbat_chan_fail: | ||
| 637 | iio_channel_release(charger->tjunc_chan); | ||
| 638 | |||
| 639 | tjunc_chan_fail: | ||
| 640 | iio_channel_release(charger->vbus_chan); | ||
| 641 | |||
| 642 | vbus_chan_fail: | ||
| 643 | iio_channel_release(charger->ibus_chan); | ||
| 644 | |||
| 645 | ibus_chan_fail: | ||
| 646 | return ret; | ||
| 647 | } | ||
| 648 | |||
| 649 | static int da9150_charger_remove(struct platform_device *pdev) | ||
| 650 | { | ||
| 651 | struct da9150_charger *charger = platform_get_drvdata(pdev); | ||
| 652 | int irq; | ||
| 653 | |||
| 654 | /* Make sure IRQs are released before unregistering power supplies */ | ||
| 655 | irq = platform_get_irq_byname(pdev, "CHG_VBUS"); | ||
| 656 | free_irq(irq, charger); | ||
| 657 | |||
| 658 | irq = platform_get_irq_byname(pdev, "CHG_VFAULT"); | ||
| 659 | free_irq(irq, charger); | ||
| 660 | |||
| 661 | irq = platform_get_irq_byname(pdev, "CHG_TJUNC"); | ||
| 662 | free_irq(irq, charger); | ||
| 663 | |||
| 664 | irq = platform_get_irq_byname(pdev, "CHG_STATUS"); | ||
| 665 | free_irq(irq, charger); | ||
| 666 | |||
| 667 | if (!IS_ERR_OR_NULL(charger->usb_phy)) | ||
| 668 | usb_unregister_notifier(charger->usb_phy, &charger->otg_nb); | ||
| 669 | |||
| 670 | power_supply_unregister(charger->battery); | ||
| 671 | power_supply_unregister(charger->usb); | ||
| 672 | |||
| 673 | /* Release ADC channels */ | ||
| 674 | iio_channel_release(charger->ibus_chan); | ||
| 675 | iio_channel_release(charger->vbus_chan); | ||
| 676 | iio_channel_release(charger->tjunc_chan); | ||
| 677 | iio_channel_release(charger->vbat_chan); | ||
| 678 | |||
| 679 | return 0; | ||
| 680 | } | ||
| 681 | |||
| 682 | static struct platform_driver da9150_charger_driver = { | ||
| 683 | .driver = { | ||
| 684 | .name = "da9150-charger", | ||
| 685 | }, | ||
| 686 | .probe = da9150_charger_probe, | ||
| 687 | .remove = da9150_charger_remove, | ||
| 688 | }; | ||
| 689 | |||
| 690 | module_platform_driver(da9150_charger_driver); | ||
| 691 | |||
| 692 | MODULE_DESCRIPTION("Charger Driver for DA9150"); | ||
| 693 | MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); | ||
| 694 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index 85b4e6eca0b1..80f73ccb77ab 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
| @@ -53,7 +53,8 @@ struct ds2760_device_info { | |||
| 53 | int charge_status; /* POWER_SUPPLY_STATUS_* */ | 53 | int charge_status; /* POWER_SUPPLY_STATUS_* */ |
| 54 | 54 | ||
| 55 | int full_counter; | 55 | int full_counter; |
| 56 | struct power_supply bat; | 56 | struct power_supply *bat; |
| 57 | struct power_supply_desc bat_desc; | ||
| 57 | struct device *w1_dev; | 58 | struct device *w1_dev; |
| 58 | struct workqueue_struct *monitor_wqueue; | 59 | struct workqueue_struct *monitor_wqueue; |
| 59 | struct delayed_work monitor_work; | 60 | struct delayed_work monitor_work; |
| @@ -254,7 +255,7 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di) | |||
| 254 | if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) | 255 | if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN) |
| 255 | di->full_counter = 0; | 256 | di->full_counter = 0; |
| 256 | 257 | ||
| 257 | if (power_supply_am_i_supplied(&di->bat)) { | 258 | if (power_supply_am_i_supplied(di->bat)) { |
| 258 | if (di->current_uA > 10000) { | 259 | if (di->current_uA > 10000) { |
| 259 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; | 260 | di->charge_status = POWER_SUPPLY_STATUS_CHARGING; |
| 260 | di->full_counter = 0; | 261 | di->full_counter = 0; |
| @@ -287,7 +288,7 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di) | |||
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | if (di->charge_status != old_charge_status) | 290 | if (di->charge_status != old_charge_status) |
| 290 | power_supply_changed(&di->bat); | 291 | power_supply_changed(di->bat); |
| 291 | } | 292 | } |
| 292 | 293 | ||
| 293 | static void ds2760_battery_write_status(struct ds2760_device_info *di, | 294 | static void ds2760_battery_write_status(struct ds2760_device_info *di, |
| @@ -346,12 +347,9 @@ static void ds2760_battery_work(struct work_struct *work) | |||
| 346 | queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); | 347 | queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); |
| 347 | } | 348 | } |
| 348 | 349 | ||
| 349 | #define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \ | ||
| 350 | bat); | ||
| 351 | |||
| 352 | static void ds2760_battery_external_power_changed(struct power_supply *psy) | 350 | static void ds2760_battery_external_power_changed(struct power_supply *psy) |
| 353 | { | 351 | { |
| 354 | struct ds2760_device_info *di = to_ds2760_device_info(psy); | 352 | struct ds2760_device_info *di = power_supply_get_drvdata(psy); |
| 355 | 353 | ||
| 356 | dev_dbg(di->dev, "%s\n", __func__); | 354 | dev_dbg(di->dev, "%s\n", __func__); |
| 357 | 355 | ||
| @@ -377,7 +375,7 @@ static void ds2760_battery_set_charged_work(struct work_struct *work) | |||
| 377 | * that error. | 375 | * that error. |
| 378 | */ | 376 | */ |
| 379 | 377 | ||
| 380 | if (!power_supply_am_i_supplied(&di->bat)) | 378 | if (!power_supply_am_i_supplied(di->bat)) |
| 381 | return; | 379 | return; |
| 382 | 380 | ||
| 383 | bias = (signed char) di->current_raw + | 381 | bias = (signed char) di->current_raw + |
| @@ -396,7 +394,7 @@ static void ds2760_battery_set_charged_work(struct work_struct *work) | |||
| 396 | 394 | ||
| 397 | static void ds2760_battery_set_charged(struct power_supply *psy) | 395 | static void ds2760_battery_set_charged(struct power_supply *psy) |
| 398 | { | 396 | { |
| 399 | struct ds2760_device_info *di = to_ds2760_device_info(psy); | 397 | struct ds2760_device_info *di = power_supply_get_drvdata(psy); |
| 400 | 398 | ||
| 401 | /* postpone the actual work by 20 secs. This is for debouncing GPIO | 399 | /* postpone the actual work by 20 secs. This is for debouncing GPIO |
| 402 | * signals and to let the current value settle. See AN4188. */ | 400 | * signals and to let the current value settle. See AN4188. */ |
| @@ -407,7 +405,7 @@ static int ds2760_battery_get_property(struct power_supply *psy, | |||
| 407 | enum power_supply_property psp, | 405 | enum power_supply_property psp, |
| 408 | union power_supply_propval *val) | 406 | union power_supply_propval *val) |
| 409 | { | 407 | { |
| 410 | struct ds2760_device_info *di = to_ds2760_device_info(psy); | 408 | struct ds2760_device_info *di = power_supply_get_drvdata(psy); |
| 411 | 409 | ||
| 412 | switch (psp) { | 410 | switch (psp) { |
| 413 | case POWER_SUPPLY_PROP_STATUS: | 411 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -458,7 +456,7 @@ static int ds2760_battery_set_property(struct power_supply *psy, | |||
| 458 | enum power_supply_property psp, | 456 | enum power_supply_property psp, |
| 459 | const union power_supply_propval *val) | 457 | const union power_supply_propval *val) |
| 460 | { | 458 | { |
| 461 | struct ds2760_device_info *di = to_ds2760_device_info(psy); | 459 | struct ds2760_device_info *di = power_supply_get_drvdata(psy); |
| 462 | 460 | ||
| 463 | switch (psp) { | 461 | switch (psp) { |
| 464 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 462 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
| @@ -508,6 +506,7 @@ static enum power_supply_property ds2760_battery_props[] = { | |||
| 508 | 506 | ||
| 509 | static int ds2760_battery_probe(struct platform_device *pdev) | 507 | static int ds2760_battery_probe(struct platform_device *pdev) |
| 510 | { | 508 | { |
| 509 | struct power_supply_config psy_cfg = {}; | ||
| 511 | char status; | 510 | char status; |
| 512 | int retval = 0; | 511 | int retval = 0; |
| 513 | struct ds2760_device_info *di; | 512 | struct ds2760_device_info *di; |
| @@ -520,20 +519,22 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
| 520 | 519 | ||
| 521 | platform_set_drvdata(pdev, di); | 520 | platform_set_drvdata(pdev, di); |
| 522 | 521 | ||
| 523 | di->dev = &pdev->dev; | 522 | di->dev = &pdev->dev; |
| 524 | di->w1_dev = pdev->dev.parent; | 523 | di->w1_dev = pdev->dev.parent; |
| 525 | di->bat.name = dev_name(&pdev->dev); | 524 | di->bat_desc.name = dev_name(&pdev->dev); |
| 526 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 525 | di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 527 | di->bat.properties = ds2760_battery_props; | 526 | di->bat_desc.properties = ds2760_battery_props; |
| 528 | di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); | 527 | di->bat_desc.num_properties = ARRAY_SIZE(ds2760_battery_props); |
| 529 | di->bat.get_property = ds2760_battery_get_property; | 528 | di->bat_desc.get_property = ds2760_battery_get_property; |
| 530 | di->bat.set_property = ds2760_battery_set_property; | 529 | di->bat_desc.set_property = ds2760_battery_set_property; |
| 531 | di->bat.property_is_writeable = | 530 | di->bat_desc.property_is_writeable = |
| 532 | ds2760_battery_property_is_writeable; | 531 | ds2760_battery_property_is_writeable; |
| 533 | di->bat.set_charged = ds2760_battery_set_charged; | 532 | di->bat_desc.set_charged = ds2760_battery_set_charged; |
| 534 | di->bat.external_power_changed = | 533 | di->bat_desc.external_power_changed = |
| 535 | ds2760_battery_external_power_changed; | 534 | ds2760_battery_external_power_changed; |
| 536 | 535 | ||
| 536 | psy_cfg.drv_data = di; | ||
| 537 | |||
| 537 | di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; | 538 | di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; |
| 538 | 539 | ||
| 539 | /* enable sleep mode feature */ | 540 | /* enable sleep mode feature */ |
| @@ -555,9 +556,10 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
| 555 | if (current_accum) | 556 | if (current_accum) |
| 556 | ds2760_battery_set_current_accum(di, current_accum); | 557 | ds2760_battery_set_current_accum(di, current_accum); |
| 557 | 558 | ||
| 558 | retval = power_supply_register(&pdev->dev, &di->bat); | 559 | di->bat = power_supply_register(&pdev->dev, &di->bat_desc, &psy_cfg); |
| 559 | if (retval) { | 560 | if (IS_ERR(di->bat)) { |
| 560 | dev_err(di->dev, "failed to register battery\n"); | 561 | dev_err(di->dev, "failed to register battery\n"); |
| 562 | retval = PTR_ERR(di->bat); | ||
| 561 | goto batt_failed; | 563 | goto batt_failed; |
| 562 | } | 564 | } |
| 563 | 565 | ||
| @@ -574,7 +576,7 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
| 574 | goto success; | 576 | goto success; |
| 575 | 577 | ||
| 576 | workqueue_failed: | 578 | workqueue_failed: |
| 577 | power_supply_unregister(&di->bat); | 579 | power_supply_unregister(di->bat); |
| 578 | batt_failed: | 580 | batt_failed: |
| 579 | di_alloc_failed: | 581 | di_alloc_failed: |
| 580 | success: | 582 | success: |
| @@ -588,7 +590,7 @@ static int ds2760_battery_remove(struct platform_device *pdev) | |||
| 588 | cancel_delayed_work_sync(&di->monitor_work); | 590 | cancel_delayed_work_sync(&di->monitor_work); |
| 589 | cancel_delayed_work_sync(&di->set_charged_work); | 591 | cancel_delayed_work_sync(&di->set_charged_work); |
| 590 | destroy_workqueue(di->monitor_wqueue); | 592 | destroy_workqueue(di->monitor_wqueue); |
| 591 | power_supply_unregister(&di->bat); | 593 | power_supply_unregister(di->bat); |
| 592 | 594 | ||
| 593 | return 0; | 595 | return 0; |
| 594 | } | 596 | } |
| @@ -610,7 +612,7 @@ static int ds2760_battery_resume(struct platform_device *pdev) | |||
| 610 | struct ds2760_device_info *di = platform_get_drvdata(pdev); | 612 | struct ds2760_device_info *di = platform_get_drvdata(pdev); |
| 611 | 613 | ||
| 612 | di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; | 614 | di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; |
| 613 | power_supply_changed(&di->bat); | 615 | power_supply_changed(di->bat); |
| 614 | 616 | ||
| 615 | mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); | 617 | mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); |
| 616 | 618 | ||
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index 9f418fa879e5..a7a0427343f3 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c | |||
| @@ -37,7 +37,8 @@ | |||
| 37 | 37 | ||
| 38 | struct ds2780_device_info { | 38 | struct ds2780_device_info { |
| 39 | struct device *dev; | 39 | struct device *dev; |
| 40 | struct power_supply bat; | 40 | struct power_supply *bat; |
| 41 | struct power_supply_desc bat_desc; | ||
| 41 | struct device *w1_dev; | 42 | struct device *w1_dev; |
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| @@ -52,7 +53,7 @@ static const char manufacturer[] = "Maxim/Dallas"; | |||
| 52 | static inline struct ds2780_device_info * | 53 | static inline struct ds2780_device_info * |
| 53 | to_ds2780_device_info(struct power_supply *psy) | 54 | to_ds2780_device_info(struct power_supply *psy) |
| 54 | { | 55 | { |
| 55 | return container_of(psy, struct ds2780_device_info, bat); | 56 | return power_supply_get_drvdata(psy); |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | static inline struct power_supply *to_power_supply(struct device *dev) | 59 | static inline struct power_supply *to_power_supply(struct device *dev) |
| @@ -757,6 +758,7 @@ static const struct attribute_group ds2780_attr_group = { | |||
| 757 | 758 | ||
| 758 | static int ds2780_battery_probe(struct platform_device *pdev) | 759 | static int ds2780_battery_probe(struct platform_device *pdev) |
| 759 | { | 760 | { |
| 761 | struct power_supply_config psy_cfg = {}; | ||
| 760 | int ret = 0; | 762 | int ret = 0; |
| 761 | struct ds2780_device_info *dev_info; | 763 | struct ds2780_device_info *dev_info; |
| 762 | 764 | ||
| @@ -770,25 +772,29 @@ static int ds2780_battery_probe(struct platform_device *pdev) | |||
| 770 | 772 | ||
| 771 | dev_info->dev = &pdev->dev; | 773 | dev_info->dev = &pdev->dev; |
| 772 | dev_info->w1_dev = pdev->dev.parent; | 774 | dev_info->w1_dev = pdev->dev.parent; |
| 773 | dev_info->bat.name = dev_name(&pdev->dev); | 775 | dev_info->bat_desc.name = dev_name(&pdev->dev); |
| 774 | dev_info->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 776 | dev_info->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 775 | dev_info->bat.properties = ds2780_battery_props; | 777 | dev_info->bat_desc.properties = ds2780_battery_props; |
| 776 | dev_info->bat.num_properties = ARRAY_SIZE(ds2780_battery_props); | 778 | dev_info->bat_desc.num_properties = ARRAY_SIZE(ds2780_battery_props); |
| 777 | dev_info->bat.get_property = ds2780_battery_get_property; | 779 | dev_info->bat_desc.get_property = ds2780_battery_get_property; |
| 778 | 780 | ||
| 779 | ret = power_supply_register(&pdev->dev, &dev_info->bat); | 781 | psy_cfg.drv_data = dev_info; |
| 780 | if (ret) { | 782 | |
| 783 | dev_info->bat = power_supply_register(&pdev->dev, &dev_info->bat_desc, | ||
| 784 | &psy_cfg); | ||
| 785 | if (IS_ERR(dev_info->bat)) { | ||
| 781 | dev_err(dev_info->dev, "failed to register battery\n"); | 786 | dev_err(dev_info->dev, "failed to register battery\n"); |
| 787 | ret = PTR_ERR(dev_info->bat); | ||
| 782 | goto fail; | 788 | goto fail; |
| 783 | } | 789 | } |
| 784 | 790 | ||
| 785 | ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); | 791 | ret = sysfs_create_group(&dev_info->bat->dev.kobj, &ds2780_attr_group); |
| 786 | if (ret) { | 792 | if (ret) { |
| 787 | dev_err(dev_info->dev, "failed to create sysfs group\n"); | 793 | dev_err(dev_info->dev, "failed to create sysfs group\n"); |
| 788 | goto fail_unregister; | 794 | goto fail_unregister; |
| 789 | } | 795 | } |
| 790 | 796 | ||
| 791 | ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, | 797 | ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj, |
| 792 | &ds2780_param_eeprom_bin_attr); | 798 | &ds2780_param_eeprom_bin_attr); |
| 793 | if (ret) { | 799 | if (ret) { |
| 794 | dev_err(dev_info->dev, | 800 | dev_err(dev_info->dev, |
| @@ -796,7 +802,7 @@ static int ds2780_battery_probe(struct platform_device *pdev) | |||
| 796 | goto fail_remove_group; | 802 | goto fail_remove_group; |
| 797 | } | 803 | } |
| 798 | 804 | ||
| 799 | ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, | 805 | ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj, |
| 800 | &ds2780_user_eeprom_bin_attr); | 806 | &ds2780_user_eeprom_bin_attr); |
| 801 | if (ret) { | 807 | if (ret) { |
| 802 | dev_err(dev_info->dev, | 808 | dev_err(dev_info->dev, |
| @@ -807,12 +813,12 @@ static int ds2780_battery_probe(struct platform_device *pdev) | |||
| 807 | return 0; | 813 | return 0; |
| 808 | 814 | ||
| 809 | fail_remove_bin_file: | 815 | fail_remove_bin_file: |
| 810 | sysfs_remove_bin_file(&dev_info->bat.dev->kobj, | 816 | sysfs_remove_bin_file(&dev_info->bat->dev.kobj, |
| 811 | &ds2780_param_eeprom_bin_attr); | 817 | &ds2780_param_eeprom_bin_attr); |
| 812 | fail_remove_group: | 818 | fail_remove_group: |
| 813 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); | 819 | sysfs_remove_group(&dev_info->bat->dev.kobj, &ds2780_attr_group); |
| 814 | fail_unregister: | 820 | fail_unregister: |
| 815 | power_supply_unregister(&dev_info->bat); | 821 | power_supply_unregister(dev_info->bat); |
| 816 | fail: | 822 | fail: |
| 817 | return ret; | 823 | return ret; |
| 818 | } | 824 | } |
| @@ -821,10 +827,13 @@ static int ds2780_battery_remove(struct platform_device *pdev) | |||
| 821 | { | 827 | { |
| 822 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); | 828 | struct ds2780_device_info *dev_info = platform_get_drvdata(pdev); |
| 823 | 829 | ||
| 824 | /* remove attributes */ | 830 | /* |
| 825 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group); | 831 | * Remove attributes before unregistering power supply |
| 832 | * because 'bat' will be freed on power_supply_unregister() call. | ||
| 833 | */ | ||
| 834 | sysfs_remove_group(&dev_info->bat->dev.kobj, &ds2780_attr_group); | ||
| 826 | 835 | ||
| 827 | power_supply_unregister(&dev_info->bat); | 836 | power_supply_unregister(dev_info->bat); |
| 828 | 837 | ||
| 829 | return 0; | 838 | return 0; |
| 830 | } | 839 | } |
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c index 0a5acc6fc6f0..56d583dae908 100644 --- a/drivers/power/ds2781_battery.c +++ b/drivers/power/ds2781_battery.c | |||
| @@ -35,7 +35,8 @@ | |||
| 35 | 35 | ||
| 36 | struct ds2781_device_info { | 36 | struct ds2781_device_info { |
| 37 | struct device *dev; | 37 | struct device *dev; |
| 38 | struct power_supply bat; | 38 | struct power_supply *bat; |
| 39 | struct power_supply_desc bat_desc; | ||
| 39 | struct device *w1_dev; | 40 | struct device *w1_dev; |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| @@ -50,7 +51,7 @@ static const char manufacturer[] = "Maxim/Dallas"; | |||
| 50 | static inline struct ds2781_device_info * | 51 | static inline struct ds2781_device_info * |
| 51 | to_ds2781_device_info(struct power_supply *psy) | 52 | to_ds2781_device_info(struct power_supply *psy) |
| 52 | { | 53 | { |
| 53 | return container_of(psy, struct ds2781_device_info, bat); | 54 | return power_supply_get_drvdata(psy); |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | static inline struct power_supply *to_power_supply(struct device *dev) | 57 | static inline struct power_supply *to_power_supply(struct device *dev) |
| @@ -328,7 +329,7 @@ static int ds2781_get_status(struct ds2781_device_info *dev_info, int *status) | |||
| 328 | if (ret < 0) | 329 | if (ret < 0) |
| 329 | return ret; | 330 | return ret; |
| 330 | 331 | ||
| 331 | if (power_supply_am_i_supplied(&dev_info->bat)) { | 332 | if (power_supply_am_i_supplied(dev_info->bat)) { |
| 332 | if (capacity == 100) | 333 | if (capacity == 100) |
| 333 | *status = POWER_SUPPLY_STATUS_FULL; | 334 | *status = POWER_SUPPLY_STATUS_FULL; |
| 334 | else if (current_uA > 50000) | 335 | else if (current_uA > 50000) |
| @@ -752,6 +753,7 @@ static const struct attribute_group ds2781_attr_group = { | |||
| 752 | 753 | ||
| 753 | static int ds2781_battery_probe(struct platform_device *pdev) | 754 | static int ds2781_battery_probe(struct platform_device *pdev) |
| 754 | { | 755 | { |
| 756 | struct power_supply_config psy_cfg = {}; | ||
| 755 | int ret = 0; | 757 | int ret = 0; |
| 756 | struct ds2781_device_info *dev_info; | 758 | struct ds2781_device_info *dev_info; |
| 757 | 759 | ||
| @@ -763,25 +765,29 @@ static int ds2781_battery_probe(struct platform_device *pdev) | |||
| 763 | 765 | ||
| 764 | dev_info->dev = &pdev->dev; | 766 | dev_info->dev = &pdev->dev; |
| 765 | dev_info->w1_dev = pdev->dev.parent; | 767 | dev_info->w1_dev = pdev->dev.parent; |
| 766 | dev_info->bat.name = dev_name(&pdev->dev); | 768 | dev_info->bat_desc.name = dev_name(&pdev->dev); |
| 767 | dev_info->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 769 | dev_info->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 768 | dev_info->bat.properties = ds2781_battery_props; | 770 | dev_info->bat_desc.properties = ds2781_battery_props; |
| 769 | dev_info->bat.num_properties = ARRAY_SIZE(ds2781_battery_props); | 771 | dev_info->bat_desc.num_properties = ARRAY_SIZE(ds2781_battery_props); |
| 770 | dev_info->bat.get_property = ds2781_battery_get_property; | 772 | dev_info->bat_desc.get_property = ds2781_battery_get_property; |
| 771 | 773 | ||
| 772 | ret = power_supply_register(&pdev->dev, &dev_info->bat); | 774 | psy_cfg.drv_data = dev_info; |
| 773 | if (ret) { | 775 | |
| 776 | dev_info->bat = power_supply_register(&pdev->dev, &dev_info->bat_desc, | ||
| 777 | &psy_cfg); | ||
| 778 | if (IS_ERR(dev_info->bat)) { | ||
| 774 | dev_err(dev_info->dev, "failed to register battery\n"); | 779 | dev_err(dev_info->dev, "failed to register battery\n"); |
| 780 | ret = PTR_ERR(dev_info->bat); | ||
| 775 | goto fail; | 781 | goto fail; |
| 776 | } | 782 | } |
| 777 | 783 | ||
| 778 | ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); | 784 | ret = sysfs_create_group(&dev_info->bat->dev.kobj, &ds2781_attr_group); |
| 779 | if (ret) { | 785 | if (ret) { |
| 780 | dev_err(dev_info->dev, "failed to create sysfs group\n"); | 786 | dev_err(dev_info->dev, "failed to create sysfs group\n"); |
| 781 | goto fail_unregister; | 787 | goto fail_unregister; |
| 782 | } | 788 | } |
| 783 | 789 | ||
| 784 | ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, | 790 | ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj, |
| 785 | &ds2781_param_eeprom_bin_attr); | 791 | &ds2781_param_eeprom_bin_attr); |
| 786 | if (ret) { | 792 | if (ret) { |
| 787 | dev_err(dev_info->dev, | 793 | dev_err(dev_info->dev, |
| @@ -789,7 +795,7 @@ static int ds2781_battery_probe(struct platform_device *pdev) | |||
| 789 | goto fail_remove_group; | 795 | goto fail_remove_group; |
| 790 | } | 796 | } |
| 791 | 797 | ||
| 792 | ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj, | 798 | ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj, |
| 793 | &ds2781_user_eeprom_bin_attr); | 799 | &ds2781_user_eeprom_bin_attr); |
| 794 | if (ret) { | 800 | if (ret) { |
| 795 | dev_err(dev_info->dev, | 801 | dev_err(dev_info->dev, |
| @@ -800,12 +806,12 @@ static int ds2781_battery_probe(struct platform_device *pdev) | |||
| 800 | return 0; | 806 | return 0; |
| 801 | 807 | ||
| 802 | fail_remove_bin_file: | 808 | fail_remove_bin_file: |
| 803 | sysfs_remove_bin_file(&dev_info->bat.dev->kobj, | 809 | sysfs_remove_bin_file(&dev_info->bat->dev.kobj, |
| 804 | &ds2781_param_eeprom_bin_attr); | 810 | &ds2781_param_eeprom_bin_attr); |
| 805 | fail_remove_group: | 811 | fail_remove_group: |
| 806 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); | 812 | sysfs_remove_group(&dev_info->bat->dev.kobj, &ds2781_attr_group); |
| 807 | fail_unregister: | 813 | fail_unregister: |
| 808 | power_supply_unregister(&dev_info->bat); | 814 | power_supply_unregister(dev_info->bat); |
| 809 | fail: | 815 | fail: |
| 810 | return ret; | 816 | return ret; |
| 811 | } | 817 | } |
| @@ -814,10 +820,13 @@ static int ds2781_battery_remove(struct platform_device *pdev) | |||
| 814 | { | 820 | { |
| 815 | struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); | 821 | struct ds2781_device_info *dev_info = platform_get_drvdata(pdev); |
| 816 | 822 | ||
| 817 | /* remove attributes */ | 823 | /* |
| 818 | sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); | 824 | * Remove attributes before unregistering power supply |
| 825 | * because 'bat' will be freed on power_supply_unregister() call. | ||
| 826 | */ | ||
| 827 | sysfs_remove_group(&dev_info->bat->dev.kobj, &ds2781_attr_group); | ||
| 819 | 828 | ||
| 820 | power_supply_unregister(&dev_info->bat); | 829 | power_supply_unregister(dev_info->bat); |
| 821 | 830 | ||
| 822 | return 0; | 831 | return 0; |
| 823 | } | 832 | } |
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index 39694883d3bf..ed4d756d21e4 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c | |||
| @@ -53,11 +53,12 @@ struct ds278x_battery_ops { | |||
| 53 | int (*get_battery_capacity)(struct ds278x_info *info, int *capacity); | 53 | int (*get_battery_capacity)(struct ds278x_info *info, int *capacity); |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | #define to_ds278x_info(x) container_of(x, struct ds278x_info, battery) | 56 | #define to_ds278x_info(x) power_supply_get_drvdata(x) |
| 57 | 57 | ||
| 58 | struct ds278x_info { | 58 | struct ds278x_info { |
| 59 | struct i2c_client *client; | 59 | struct i2c_client *client; |
| 60 | struct power_supply battery; | 60 | struct power_supply *battery; |
| 61 | struct power_supply_desc battery_desc; | ||
| 61 | struct ds278x_battery_ops *ops; | 62 | struct ds278x_battery_ops *ops; |
| 62 | struct delayed_work bat_work; | 63 | struct delayed_work bat_work; |
| 63 | int id; | 64 | int id; |
| @@ -285,7 +286,7 @@ static void ds278x_bat_update(struct ds278x_info *info) | |||
| 285 | ds278x_get_status(info, &info->status); | 286 | ds278x_get_status(info, &info->status); |
| 286 | 287 | ||
| 287 | if ((old_status != info->status) || (old_capacity != info->capacity)) | 288 | if ((old_status != info->status) || (old_capacity != info->capacity)) |
| 288 | power_supply_changed(&info->battery); | 289 | power_supply_changed(info->battery); |
| 289 | } | 290 | } |
| 290 | 291 | ||
| 291 | static void ds278x_bat_work(struct work_struct *work) | 292 | static void ds278x_bat_work(struct work_struct *work) |
| @@ -306,7 +307,7 @@ static enum power_supply_property ds278x_battery_props[] = { | |||
| 306 | POWER_SUPPLY_PROP_TEMP, | 307 | POWER_SUPPLY_PROP_TEMP, |
| 307 | }; | 308 | }; |
| 308 | 309 | ||
| 309 | static void ds278x_power_supply_init(struct power_supply *battery) | 310 | static void ds278x_power_supply_init(struct power_supply_desc *battery) |
| 310 | { | 311 | { |
| 311 | battery->type = POWER_SUPPLY_TYPE_BATTERY; | 312 | battery->type = POWER_SUPPLY_TYPE_BATTERY; |
| 312 | battery->properties = ds278x_battery_props; | 313 | battery->properties = ds278x_battery_props; |
| @@ -319,8 +320,8 @@ static int ds278x_battery_remove(struct i2c_client *client) | |||
| 319 | { | 320 | { |
| 320 | struct ds278x_info *info = i2c_get_clientdata(client); | 321 | struct ds278x_info *info = i2c_get_clientdata(client); |
| 321 | 322 | ||
| 322 | power_supply_unregister(&info->battery); | 323 | power_supply_unregister(info->battery); |
| 323 | kfree(info->battery.name); | 324 | kfree(info->battery_desc.name); |
| 324 | 325 | ||
| 325 | mutex_lock(&battery_lock); | 326 | mutex_lock(&battery_lock); |
| 326 | idr_remove(&battery_id, info->id); | 327 | idr_remove(&battery_id, info->id); |
| @@ -377,6 +378,7 @@ static int ds278x_battery_probe(struct i2c_client *client, | |||
| 377 | const struct i2c_device_id *id) | 378 | const struct i2c_device_id *id) |
| 378 | { | 379 | { |
| 379 | struct ds278x_platform_data *pdata = client->dev.platform_data; | 380 | struct ds278x_platform_data *pdata = client->dev.platform_data; |
| 381 | struct power_supply_config psy_cfg = {}; | ||
| 380 | struct ds278x_info *info; | 382 | struct ds278x_info *info; |
| 381 | int ret; | 383 | int ret; |
| 382 | int num; | 384 | int num; |
| @@ -404,8 +406,9 @@ static int ds278x_battery_probe(struct i2c_client *client, | |||
| 404 | goto fail_info; | 406 | goto fail_info; |
| 405 | } | 407 | } |
| 406 | 408 | ||
| 407 | info->battery.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, num); | 409 | info->battery_desc.name = kasprintf(GFP_KERNEL, "%s-%d", |
| 408 | if (!info->battery.name) { | 410 | client->name, num); |
| 411 | if (!info->battery_desc.name) { | ||
| 409 | ret = -ENOMEM; | 412 | ret = -ENOMEM; |
| 410 | goto fail_name; | 413 | goto fail_name; |
| 411 | } | 414 | } |
| @@ -417,16 +420,19 @@ static int ds278x_battery_probe(struct i2c_client *client, | |||
| 417 | info->client = client; | 420 | info->client = client; |
| 418 | info->id = num; | 421 | info->id = num; |
| 419 | info->ops = &ds278x_ops[id->driver_data]; | 422 | info->ops = &ds278x_ops[id->driver_data]; |
| 420 | ds278x_power_supply_init(&info->battery); | 423 | ds278x_power_supply_init(&info->battery_desc); |
| 424 | psy_cfg.drv_data = info; | ||
| 421 | 425 | ||
| 422 | info->capacity = 100; | 426 | info->capacity = 100; |
| 423 | info->status = POWER_SUPPLY_STATUS_FULL; | 427 | info->status = POWER_SUPPLY_STATUS_FULL; |
| 424 | 428 | ||
| 425 | INIT_DELAYED_WORK(&info->bat_work, ds278x_bat_work); | 429 | INIT_DELAYED_WORK(&info->bat_work, ds278x_bat_work); |
| 426 | 430 | ||
| 427 | ret = power_supply_register(&client->dev, &info->battery); | 431 | info->battery = power_supply_register(&client->dev, |
| 428 | if (ret) { | 432 | &info->battery_desc, &psy_cfg); |
| 433 | if (IS_ERR(info->battery)) { | ||
| 429 | dev_err(&client->dev, "failed to register battery\n"); | 434 | dev_err(&client->dev, "failed to register battery\n"); |
| 435 | ret = PTR_ERR(info->battery); | ||
| 430 | goto fail_register; | 436 | goto fail_register; |
| 431 | } else { | 437 | } else { |
| 432 | schedule_delayed_work(&info->bat_work, DS278x_DELAY); | 438 | schedule_delayed_work(&info->bat_work, DS278x_DELAY); |
| @@ -435,7 +441,7 @@ static int ds278x_battery_probe(struct i2c_client *client, | |||
| 435 | return 0; | 441 | return 0; |
| 436 | 442 | ||
| 437 | fail_register: | 443 | fail_register: |
| 438 | kfree(info->battery.name); | 444 | kfree(info->battery_desc.name); |
| 439 | fail_name: | 445 | fail_name: |
| 440 | kfree(info); | 446 | kfree(info); |
| 441 | fail_info: | 447 | fail_info: |
diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index d72733e4f93a..fedc5818fab7 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c | |||
| @@ -44,7 +44,8 @@ static const char *const gab_chan_name[] = { | |||
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | struct gab { | 46 | struct gab { |
| 47 | struct power_supply psy; | 47 | struct power_supply *psy; |
| 48 | struct power_supply_desc psy_desc; | ||
| 48 | struct iio_channel *channel[GAB_MAX_CHAN_TYPE]; | 49 | struct iio_channel *channel[GAB_MAX_CHAN_TYPE]; |
| 49 | struct gab_platform_data *pdata; | 50 | struct gab_platform_data *pdata; |
| 50 | struct delayed_work bat_work; | 51 | struct delayed_work bat_work; |
| @@ -55,7 +56,7 @@ struct gab { | |||
| 55 | 56 | ||
| 56 | static struct gab *to_generic_bat(struct power_supply *psy) | 57 | static struct gab *to_generic_bat(struct power_supply *psy) |
| 57 | { | 58 | { |
| 58 | return container_of(psy, struct gab, psy); | 59 | return power_supply_get_drvdata(psy); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static void gab_ext_power_changed(struct power_supply *psy) | 62 | static void gab_ext_power_changed(struct power_supply *psy) |
| @@ -151,7 +152,7 @@ static int gab_get_property(struct power_supply *psy, | |||
| 151 | 152 | ||
| 152 | adc_bat = to_generic_bat(psy); | 153 | adc_bat = to_generic_bat(psy); |
| 153 | if (!adc_bat) { | 154 | if (!adc_bat) { |
| 154 | dev_err(psy->dev, "no battery infos ?!\n"); | 155 | dev_err(&psy->dev, "no battery infos ?!\n"); |
| 155 | return -EINVAL; | 156 | return -EINVAL; |
| 156 | } | 157 | } |
| 157 | pdata = adc_bat->pdata; | 158 | pdata = adc_bat->pdata; |
| @@ -159,7 +160,7 @@ static int gab_get_property(struct power_supply *psy, | |||
| 159 | 160 | ||
| 160 | switch (psp) { | 161 | switch (psp) { |
| 161 | case POWER_SUPPLY_PROP_STATUS: | 162 | case POWER_SUPPLY_PROP_STATUS: |
| 162 | gab_get_status(adc_bat); | 163 | val->intval = gab_get_status(adc_bat); |
| 163 | break; | 164 | break; |
| 164 | case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: | 165 | case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: |
| 165 | val->intval = 0; | 166 | val->intval = 0; |
| @@ -210,7 +211,7 @@ static void gab_work(struct work_struct *work) | |||
| 210 | pdata = adc_bat->pdata; | 211 | pdata = adc_bat->pdata; |
| 211 | status = adc_bat->status; | 212 | status = adc_bat->status; |
| 212 | 213 | ||
| 213 | is_plugged = power_supply_am_i_supplied(&adc_bat->psy); | 214 | is_plugged = power_supply_am_i_supplied(adc_bat->psy); |
| 214 | adc_bat->cable_plugged = is_plugged; | 215 | adc_bat->cable_plugged = is_plugged; |
| 215 | 216 | ||
| 216 | if (!is_plugged) | 217 | if (!is_plugged) |
| @@ -221,7 +222,7 @@ static void gab_work(struct work_struct *work) | |||
| 221 | adc_bat->status = POWER_SUPPLY_STATUS_CHARGING; | 222 | adc_bat->status = POWER_SUPPLY_STATUS_CHARGING; |
| 222 | 223 | ||
| 223 | if (status != adc_bat->status) | 224 | if (status != adc_bat->status) |
| 224 | power_supply_changed(&adc_bat->psy); | 225 | power_supply_changed(adc_bat->psy); |
| 225 | } | 226 | } |
| 226 | 227 | ||
| 227 | static irqreturn_t gab_charged(int irq, void *dev_id) | 228 | static irqreturn_t gab_charged(int irq, void *dev_id) |
| @@ -239,7 +240,8 @@ static irqreturn_t gab_charged(int irq, void *dev_id) | |||
| 239 | static int gab_probe(struct platform_device *pdev) | 240 | static int gab_probe(struct platform_device *pdev) |
| 240 | { | 241 | { |
| 241 | struct gab *adc_bat; | 242 | struct gab *adc_bat; |
| 242 | struct power_supply *psy; | 243 | struct power_supply_desc *psy_desc; |
| 244 | struct power_supply_config psy_cfg = {}; | ||
| 243 | struct gab_platform_data *pdata = pdev->dev.platform_data; | 245 | struct gab_platform_data *pdata = pdev->dev.platform_data; |
| 244 | enum power_supply_property *properties; | 246 | enum power_supply_property *properties; |
| 245 | int ret = 0; | 247 | int ret = 0; |
| @@ -252,32 +254,34 @@ static int gab_probe(struct platform_device *pdev) | |||
| 252 | return -ENOMEM; | 254 | return -ENOMEM; |
| 253 | } | 255 | } |
| 254 | 256 | ||
| 255 | psy = &adc_bat->psy; | 257 | psy_cfg.drv_data = adc_bat; |
| 256 | psy->name = pdata->battery_info.name; | 258 | psy_desc = &adc_bat->psy_desc; |
| 259 | psy_desc->name = pdata->battery_info.name; | ||
| 257 | 260 | ||
| 258 | /* bootup default values for the battery */ | 261 | /* bootup default values for the battery */ |
| 259 | adc_bat->cable_plugged = false; | 262 | adc_bat->cable_plugged = false; |
| 260 | adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; | 263 | adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; |
| 261 | psy->type = POWER_SUPPLY_TYPE_BATTERY; | 264 | psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; |
| 262 | psy->get_property = gab_get_property; | 265 | psy_desc->get_property = gab_get_property; |
| 263 | psy->external_power_changed = gab_ext_power_changed; | 266 | psy_desc->external_power_changed = gab_ext_power_changed; |
| 264 | adc_bat->pdata = pdata; | 267 | adc_bat->pdata = pdata; |
| 265 | 268 | ||
| 266 | /* | 269 | /* |
| 267 | * copying the static properties and allocating extra memory for holding | 270 | * copying the static properties and allocating extra memory for holding |
| 268 | * the extra configurable properties received from platform data. | 271 | * the extra configurable properties received from platform data. |
| 269 | */ | 272 | */ |
| 270 | psy->properties = kcalloc(ARRAY_SIZE(gab_props) + | 273 | psy_desc->properties = kcalloc(ARRAY_SIZE(gab_props) + |
| 271 | ARRAY_SIZE(gab_chan_name), | 274 | ARRAY_SIZE(gab_chan_name), |
| 272 | sizeof(*psy->properties), GFP_KERNEL); | 275 | sizeof(*psy_desc->properties), |
| 273 | if (!psy->properties) { | 276 | GFP_KERNEL); |
| 277 | if (!psy_desc->properties) { | ||
| 274 | ret = -ENOMEM; | 278 | ret = -ENOMEM; |
| 275 | goto first_mem_fail; | 279 | goto first_mem_fail; |
| 276 | } | 280 | } |
| 277 | 281 | ||
| 278 | memcpy(psy->properties, gab_props, sizeof(gab_props)); | 282 | memcpy(psy_desc->properties, gab_props, sizeof(gab_props)); |
| 279 | properties = (enum power_supply_property *) | 283 | properties = (enum power_supply_property *) |
| 280 | ((char *)psy->properties + sizeof(gab_props)); | 284 | ((char *)psy_desc->properties + sizeof(gab_props)); |
| 281 | 285 | ||
| 282 | /* | 286 | /* |
| 283 | * getting channel from iio and copying the battery properties | 287 | * getting channel from iio and copying the battery properties |
| @@ -291,7 +295,7 @@ static int gab_probe(struct platform_device *pdev) | |||
| 291 | adc_bat->channel[chan] = NULL; | 295 | adc_bat->channel[chan] = NULL; |
| 292 | } else { | 296 | } else { |
| 293 | /* copying properties for supported channels only */ | 297 | /* copying properties for supported channels only */ |
| 294 | memcpy(properties + sizeof(*(psy->properties)) * index, | 298 | memcpy(properties + sizeof(*(psy_desc->properties)) * index, |
| 295 | &gab_dyn_props[chan], | 299 | &gab_dyn_props[chan], |
| 296 | sizeof(gab_dyn_props[chan])); | 300 | sizeof(gab_dyn_props[chan])); |
| 297 | index++; | 301 | index++; |
| @@ -310,11 +314,13 @@ static int gab_probe(struct platform_device *pdev) | |||
| 310 | * as come channels may be not be supported by the device.So | 314 | * as come channels may be not be supported by the device.So |
| 311 | * we need to take care of that. | 315 | * we need to take care of that. |
| 312 | */ | 316 | */ |
| 313 | psy->num_properties = ARRAY_SIZE(gab_props) + index; | 317 | psy_desc->num_properties = ARRAY_SIZE(gab_props) + index; |
| 314 | 318 | ||
| 315 | ret = power_supply_register(&pdev->dev, psy); | 319 | adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg); |
| 316 | if (ret) | 320 | if (IS_ERR(adc_bat->psy)) { |
| 321 | ret = PTR_ERR(adc_bat->psy); | ||
| 317 | goto err_reg_fail; | 322 | goto err_reg_fail; |
| 323 | } | ||
| 318 | 324 | ||
| 319 | INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work); | 325 | INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work); |
| 320 | 326 | ||
| @@ -342,14 +348,14 @@ static int gab_probe(struct platform_device *pdev) | |||
| 342 | err_gpio: | 348 | err_gpio: |
| 343 | gpio_free(pdata->gpio_charge_finished); | 349 | gpio_free(pdata->gpio_charge_finished); |
| 344 | gpio_req_fail: | 350 | gpio_req_fail: |
| 345 | power_supply_unregister(psy); | 351 | power_supply_unregister(adc_bat->psy); |
| 346 | err_reg_fail: | 352 | err_reg_fail: |
| 347 | for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { | 353 | for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { |
| 348 | if (adc_bat->channel[chan]) | 354 | if (adc_bat->channel[chan]) |
| 349 | iio_channel_release(adc_bat->channel[chan]); | 355 | iio_channel_release(adc_bat->channel[chan]); |
| 350 | } | 356 | } |
| 351 | second_mem_fail: | 357 | second_mem_fail: |
| 352 | kfree(psy->properties); | 358 | kfree(psy_desc->properties); |
| 353 | first_mem_fail: | 359 | first_mem_fail: |
| 354 | return ret; | 360 | return ret; |
| 355 | } | 361 | } |
| @@ -360,7 +366,7 @@ static int gab_remove(struct platform_device *pdev) | |||
| 360 | struct gab *adc_bat = platform_get_drvdata(pdev); | 366 | struct gab *adc_bat = platform_get_drvdata(pdev); |
| 361 | struct gab_platform_data *pdata = adc_bat->pdata; | 367 | struct gab_platform_data *pdata = adc_bat->pdata; |
| 362 | 368 | ||
| 363 | power_supply_unregister(&adc_bat->psy); | 369 | power_supply_unregister(adc_bat->psy); |
| 364 | 370 | ||
| 365 | if (gpio_is_valid(pdata->gpio_charge_finished)) { | 371 | if (gpio_is_valid(pdata->gpio_charge_finished)) { |
| 366 | free_irq(gpio_to_irq(pdata->gpio_charge_finished), adc_bat); | 372 | free_irq(gpio_to_irq(pdata->gpio_charge_finished), adc_bat); |
| @@ -372,7 +378,7 @@ static int gab_remove(struct platform_device *pdev) | |||
| 372 | iio_channel_release(adc_bat->channel[chan]); | 378 | iio_channel_release(adc_bat->channel[chan]); |
| 373 | } | 379 | } |
| 374 | 380 | ||
| 375 | kfree(adc_bat->psy.properties); | 381 | kfree(adc_bat->psy_desc.properties); |
| 376 | cancel_delayed_work(&adc_bat->bat_work); | 382 | cancel_delayed_work(&adc_bat->bat_work); |
| 377 | return 0; | 383 | return 0; |
| 378 | } | 384 | } |
diff --git a/drivers/power/goldfish_battery.c b/drivers/power/goldfish_battery.c index 29eba88a2963..a50bb988c69a 100644 --- a/drivers/power/goldfish_battery.c +++ b/drivers/power/goldfish_battery.c | |||
| @@ -30,8 +30,8 @@ struct goldfish_battery_data { | |||
| 30 | int irq; | 30 | int irq; |
| 31 | spinlock_t lock; | 31 | spinlock_t lock; |
| 32 | 32 | ||
| 33 | struct power_supply battery; | 33 | struct power_supply *battery; |
| 34 | struct power_supply ac; | 34 | struct power_supply *ac; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | #define GOLDFISH_BATTERY_READ(data, addr) \ | 37 | #define GOLDFISH_BATTERY_READ(data, addr) \ |
| @@ -67,8 +67,7 @@ static int goldfish_ac_get_property(struct power_supply *psy, | |||
| 67 | enum power_supply_property psp, | 67 | enum power_supply_property psp, |
| 68 | union power_supply_propval *val) | 68 | union power_supply_propval *val) |
| 69 | { | 69 | { |
| 70 | struct goldfish_battery_data *data = container_of(psy, | 70 | struct goldfish_battery_data *data = power_supply_get_drvdata(psy); |
| 71 | struct goldfish_battery_data, ac); | ||
| 72 | int ret = 0; | 71 | int ret = 0; |
| 73 | 72 | ||
| 74 | switch (psp) { | 73 | switch (psp) { |
| @@ -86,8 +85,7 @@ static int goldfish_battery_get_property(struct power_supply *psy, | |||
| 86 | enum power_supply_property psp, | 85 | enum power_supply_property psp, |
| 87 | union power_supply_propval *val) | 86 | union power_supply_propval *val) |
| 88 | { | 87 | { |
| 89 | struct goldfish_battery_data *data = container_of(psy, | 88 | struct goldfish_battery_data *data = power_supply_get_drvdata(psy); |
| 90 | struct goldfish_battery_data, battery); | ||
| 91 | int ret = 0; | 89 | int ret = 0; |
| 92 | 90 | ||
| 93 | switch (psp) { | 91 | switch (psp) { |
| @@ -139,20 +137,36 @@ static irqreturn_t goldfish_battery_interrupt(int irq, void *dev_id) | |||
| 139 | status &= BATTERY_INT_MASK; | 137 | status &= BATTERY_INT_MASK; |
| 140 | 138 | ||
| 141 | if (status & BATTERY_STATUS_CHANGED) | 139 | if (status & BATTERY_STATUS_CHANGED) |
| 142 | power_supply_changed(&data->battery); | 140 | power_supply_changed(data->battery); |
| 143 | if (status & AC_STATUS_CHANGED) | 141 | if (status & AC_STATUS_CHANGED) |
| 144 | power_supply_changed(&data->ac); | 142 | power_supply_changed(data->ac); |
| 145 | 143 | ||
| 146 | spin_unlock_irqrestore(&data->lock, irq_flags); | 144 | spin_unlock_irqrestore(&data->lock, irq_flags); |
| 147 | return status ? IRQ_HANDLED : IRQ_NONE; | 145 | return status ? IRQ_HANDLED : IRQ_NONE; |
| 148 | } | 146 | } |
| 149 | 147 | ||
| 148 | static const struct power_supply_desc battery_desc = { | ||
| 149 | .properties = goldfish_battery_props, | ||
| 150 | .num_properties = ARRAY_SIZE(goldfish_battery_props), | ||
| 151 | .get_property = goldfish_battery_get_property, | ||
| 152 | .name = "battery", | ||
| 153 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static const struct power_supply_desc ac_desc = { | ||
| 157 | .properties = goldfish_ac_props, | ||
| 158 | .num_properties = ARRAY_SIZE(goldfish_ac_props), | ||
| 159 | .get_property = goldfish_ac_get_property, | ||
| 160 | .name = "ac", | ||
| 161 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 162 | }; | ||
| 150 | 163 | ||
| 151 | static int goldfish_battery_probe(struct platform_device *pdev) | 164 | static int goldfish_battery_probe(struct platform_device *pdev) |
| 152 | { | 165 | { |
| 153 | int ret; | 166 | int ret; |
| 154 | struct resource *r; | 167 | struct resource *r; |
| 155 | struct goldfish_battery_data *data; | 168 | struct goldfish_battery_data *data; |
| 169 | struct power_supply_config psy_cfg = {}; | ||
| 156 | 170 | ||
| 157 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 171 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
| 158 | if (data == NULL) | 172 | if (data == NULL) |
| @@ -160,18 +174,6 @@ static int goldfish_battery_probe(struct platform_device *pdev) | |||
| 160 | 174 | ||
| 161 | spin_lock_init(&data->lock); | 175 | spin_lock_init(&data->lock); |
| 162 | 176 | ||
| 163 | data->battery.properties = goldfish_battery_props; | ||
| 164 | data->battery.num_properties = ARRAY_SIZE(goldfish_battery_props); | ||
| 165 | data->battery.get_property = goldfish_battery_get_property; | ||
| 166 | data->battery.name = "battery"; | ||
| 167 | data->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 168 | |||
| 169 | data->ac.properties = goldfish_ac_props; | ||
| 170 | data->ac.num_properties = ARRAY_SIZE(goldfish_ac_props); | ||
| 171 | data->ac.get_property = goldfish_ac_get_property; | ||
| 172 | data->ac.name = "ac"; | ||
| 173 | data->ac.type = POWER_SUPPLY_TYPE_MAINS; | ||
| 174 | |||
| 175 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 177 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 176 | if (r == NULL) { | 178 | if (r == NULL) { |
| 177 | dev_err(&pdev->dev, "platform_get_resource failed\n"); | 179 | dev_err(&pdev->dev, "platform_get_resource failed\n"); |
| @@ -195,14 +197,17 @@ static int goldfish_battery_probe(struct platform_device *pdev) | |||
| 195 | if (ret) | 197 | if (ret) |
| 196 | return ret; | 198 | return ret; |
| 197 | 199 | ||
| 198 | ret = power_supply_register(&pdev->dev, &data->ac); | 200 | psy_cfg.drv_data = data; |
| 199 | if (ret) | ||
| 200 | return ret; | ||
| 201 | 201 | ||
| 202 | ret = power_supply_register(&pdev->dev, &data->battery); | 202 | data->ac = power_supply_register(&pdev->dev, &ac_desc, &psy_cfg); |
| 203 | if (ret) { | 203 | if (IS_ERR(data->ac)) |
| 204 | power_supply_unregister(&data->ac); | 204 | return PTR_ERR(data->ac); |
| 205 | return ret; | 205 | |
| 206 | data->battery = power_supply_register(&pdev->dev, &battery_desc, | ||
| 207 | &psy_cfg); | ||
| 208 | if (IS_ERR(data->battery)) { | ||
| 209 | power_supply_unregister(data->ac); | ||
| 210 | return PTR_ERR(data->battery); | ||
| 206 | } | 211 | } |
| 207 | 212 | ||
| 208 | platform_set_drvdata(pdev, data); | 213 | platform_set_drvdata(pdev, data); |
| @@ -216,8 +221,8 @@ static int goldfish_battery_remove(struct platform_device *pdev) | |||
| 216 | { | 221 | { |
| 217 | struct goldfish_battery_data *data = platform_get_drvdata(pdev); | 222 | struct goldfish_battery_data *data = platform_get_drvdata(pdev); |
| 218 | 223 | ||
| 219 | power_supply_unregister(&data->battery); | 224 | power_supply_unregister(data->battery); |
| 220 | power_supply_unregister(&data->ac); | 225 | power_supply_unregister(data->ac); |
| 221 | battery_data = NULL; | 226 | battery_data = NULL; |
| 222 | return 0; | 227 | return 0; |
| 223 | } | 228 | } |
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index b7424c8501f1..c5869b1941ac 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c | |||
| @@ -32,7 +32,8 @@ struct gpio_charger { | |||
| 32 | unsigned int irq; | 32 | unsigned int irq; |
| 33 | bool wakeup_enabled; | 33 | bool wakeup_enabled; |
| 34 | 34 | ||
| 35 | struct power_supply charger; | 35 | struct power_supply *charger; |
| 36 | struct power_supply_desc charger_desc; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | static irqreturn_t gpio_charger_irq(int irq, void *devid) | 39 | static irqreturn_t gpio_charger_irq(int irq, void *devid) |
| @@ -46,7 +47,7 @@ static irqreturn_t gpio_charger_irq(int irq, void *devid) | |||
| 46 | 47 | ||
| 47 | static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) | 48 | static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) |
| 48 | { | 49 | { |
| 49 | return container_of(psy, struct gpio_charger, charger); | 50 | return power_supply_get_drvdata(psy); |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 52 | static int gpio_charger_get_property(struct power_supply *psy, | 53 | static int gpio_charger_get_property(struct power_supply *psy, |
| @@ -127,8 +128,9 @@ struct gpio_charger_platform_data *gpio_charger_parse_dt(struct device *dev) | |||
| 127 | static int gpio_charger_probe(struct platform_device *pdev) | 128 | static int gpio_charger_probe(struct platform_device *pdev) |
| 128 | { | 129 | { |
| 129 | const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; | 130 | const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; |
| 131 | struct power_supply_config psy_cfg = {}; | ||
| 130 | struct gpio_charger *gpio_charger; | 132 | struct gpio_charger *gpio_charger; |
| 131 | struct power_supply *charger; | 133 | struct power_supply_desc *charger_desc; |
| 132 | int ret; | 134 | int ret; |
| 133 | int irq; | 135 | int irq; |
| 134 | 136 | ||
| @@ -154,16 +156,18 @@ static int gpio_charger_probe(struct platform_device *pdev) | |||
| 154 | return -ENOMEM; | 156 | return -ENOMEM; |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | charger = &gpio_charger->charger; | 159 | charger_desc = &gpio_charger->charger_desc; |
| 160 | |||
| 161 | charger_desc->name = pdata->name ? pdata->name : "gpio-charger"; | ||
| 162 | charger_desc->type = pdata->type; | ||
| 163 | charger_desc->properties = gpio_charger_properties; | ||
| 164 | charger_desc->num_properties = ARRAY_SIZE(gpio_charger_properties); | ||
| 165 | charger_desc->get_property = gpio_charger_get_property; | ||
| 158 | 166 | ||
| 159 | charger->name = pdata->name ? pdata->name : "gpio-charger"; | 167 | psy_cfg.supplied_to = pdata->supplied_to; |
| 160 | charger->type = pdata->type; | 168 | psy_cfg.num_supplicants = pdata->num_supplicants; |
| 161 | charger->properties = gpio_charger_properties; | 169 | psy_cfg.of_node = pdev->dev.of_node; |
| 162 | charger->num_properties = ARRAY_SIZE(gpio_charger_properties); | 170 | psy_cfg.drv_data = gpio_charger; |
| 163 | charger->get_property = gpio_charger_get_property; | ||
| 164 | charger->supplied_to = pdata->supplied_to; | ||
| 165 | charger->num_supplicants = pdata->num_supplicants; | ||
| 166 | charger->of_node = pdev->dev.of_node; | ||
| 167 | 171 | ||
| 168 | ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); | 172 | ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); |
| 169 | if (ret) { | 173 | if (ret) { |
| @@ -178,8 +182,10 @@ static int gpio_charger_probe(struct platform_device *pdev) | |||
| 178 | 182 | ||
| 179 | gpio_charger->pdata = pdata; | 183 | gpio_charger->pdata = pdata; |
| 180 | 184 | ||
| 181 | ret = power_supply_register(&pdev->dev, charger); | 185 | gpio_charger->charger = power_supply_register(&pdev->dev, |
| 182 | if (ret < 0) { | 186 | charger_desc, &psy_cfg); |
| 187 | if (IS_ERR(gpio_charger->charger)) { | ||
| 188 | ret = PTR_ERR(gpio_charger->charger); | ||
| 183 | dev_err(&pdev->dev, "Failed to register power supply: %d\n", | 189 | dev_err(&pdev->dev, "Failed to register power supply: %d\n", |
| 184 | ret); | 190 | ret); |
| 185 | goto err_gpio_free; | 191 | goto err_gpio_free; |
| @@ -189,7 +195,7 @@ static int gpio_charger_probe(struct platform_device *pdev) | |||
| 189 | if (irq > 0) { | 195 | if (irq > 0) { |
| 190 | ret = request_any_context_irq(irq, gpio_charger_irq, | 196 | ret = request_any_context_irq(irq, gpio_charger_irq, |
| 191 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 197 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 192 | dev_name(&pdev->dev), charger); | 198 | dev_name(&pdev->dev), gpio_charger->charger); |
| 193 | if (ret < 0) | 199 | if (ret < 0) |
| 194 | dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); | 200 | dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); |
| 195 | else | 201 | else |
| @@ -213,9 +219,9 @@ static int gpio_charger_remove(struct platform_device *pdev) | |||
| 213 | struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); | 219 | struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); |
| 214 | 220 | ||
| 215 | if (gpio_charger->irq) | 221 | if (gpio_charger->irq) |
| 216 | free_irq(gpio_charger->irq, &gpio_charger->charger); | 222 | free_irq(gpio_charger->irq, gpio_charger->charger); |
| 217 | 223 | ||
| 218 | power_supply_unregister(&gpio_charger->charger); | 224 | power_supply_unregister(gpio_charger->charger); |
| 219 | 225 | ||
| 220 | gpio_free(gpio_charger->pdata->gpio); | 226 | gpio_free(gpio_charger->pdata->gpio); |
| 221 | 227 | ||
| @@ -241,7 +247,7 @@ static int gpio_charger_resume(struct device *dev) | |||
| 241 | 247 | ||
| 242 | if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled) | 248 | if (device_may_wakeup(dev) && gpio_charger->wakeup_enabled) |
| 243 | disable_irq_wake(gpio_charger->irq); | 249 | disable_irq_wake(gpio_charger->irq); |
| 244 | power_supply_changed(&gpio_charger->charger); | 250 | power_supply_changed(gpio_charger->charger); |
| 245 | 251 | ||
| 246 | return 0; | 252 | return 0; |
| 247 | } | 253 | } |
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index de3f39e6fa8e..9fa4acc107ca 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
| @@ -107,8 +107,8 @@ struct pmic_power_module_info { | |||
| 107 | unsigned int batt_prev_charge_full; /* in mAS */ | 107 | unsigned int batt_prev_charge_full; /* in mAS */ |
| 108 | unsigned int batt_charge_rate; /* in units per second */ | 108 | unsigned int batt_charge_rate; /* in units per second */ |
| 109 | 109 | ||
| 110 | struct power_supply usb; | 110 | struct power_supply *usb; |
| 111 | struct power_supply batt; | 111 | struct power_supply *batt; |
| 112 | int irq; /* GPE_ID or IRQ# */ | 112 | int irq; /* GPE_ID or IRQ# */ |
| 113 | struct workqueue_struct *monitor_wqueue; | 113 | struct workqueue_struct *monitor_wqueue; |
| 114 | struct delayed_work monitor_battery; | 114 | struct delayed_work monitor_battery; |
| @@ -404,8 +404,7 @@ static int pmic_usb_get_property(struct power_supply *psy, | |||
| 404 | enum power_supply_property psp, | 404 | enum power_supply_property psp, |
| 405 | union power_supply_propval *val) | 405 | union power_supply_propval *val) |
| 406 | { | 406 | { |
| 407 | struct pmic_power_module_info *pbi = container_of(psy, | 407 | struct pmic_power_module_info *pbi = power_supply_get_drvdata(psy); |
| 408 | struct pmic_power_module_info, usb); | ||
| 409 | 408 | ||
| 410 | /* update pmic_power_module_info members */ | 409 | /* update pmic_power_module_info members */ |
| 411 | pmic_battery_read_status(pbi); | 410 | pmic_battery_read_status(pbi); |
| @@ -444,8 +443,7 @@ static int pmic_battery_get_property(struct power_supply *psy, | |||
| 444 | enum power_supply_property psp, | 443 | enum power_supply_property psp, |
| 445 | union power_supply_propval *val) | 444 | union power_supply_propval *val) |
| 446 | { | 445 | { |
| 447 | struct pmic_power_module_info *pbi = container_of(psy, | 446 | struct pmic_power_module_info *pbi = power_supply_get_drvdata(psy); |
| 448 | struct pmic_power_module_info, batt); | ||
| 449 | 447 | ||
| 450 | /* update pmic_power_module_info members */ | 448 | /* update pmic_power_module_info members */ |
| 451 | pmic_battery_read_status(pbi); | 449 | pmic_battery_read_status(pbi); |
| @@ -640,6 +638,25 @@ static void pmic_battery_handle_intrpt(struct work_struct *work) | |||
| 640 | __func__); | 638 | __func__); |
| 641 | } | 639 | } |
| 642 | 640 | ||
| 641 | /* | ||
| 642 | * Description of power supplies | ||
| 643 | */ | ||
| 644 | static const struct power_supply_desc pmic_usb_desc = { | ||
| 645 | .name = "pmic-usb", | ||
| 646 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 647 | .properties = pmic_usb_props, | ||
| 648 | .num_properties = ARRAY_SIZE(pmic_usb_props), | ||
| 649 | .get_property = pmic_usb_get_property, | ||
| 650 | }; | ||
| 651 | |||
| 652 | static const struct power_supply_desc pmic_batt_desc = { | ||
| 653 | .name = "pmic-batt", | ||
| 654 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 655 | .properties = pmic_battery_props, | ||
| 656 | .num_properties = ARRAY_SIZE(pmic_battery_props), | ||
| 657 | .get_property = pmic_battery_get_property, | ||
| 658 | }; | ||
| 659 | |||
| 643 | /** | 660 | /** |
| 644 | * pmic_battery_probe - pmic battery initialize | 661 | * pmic_battery_probe - pmic battery initialize |
| 645 | * @irq: pmic battery device irq | 662 | * @irq: pmic battery device irq |
| @@ -653,6 +670,7 @@ static int probe(int irq, struct device *dev) | |||
| 653 | { | 670 | { |
| 654 | int retval = 0; | 671 | int retval = 0; |
| 655 | struct pmic_power_module_info *pbi; | 672 | struct pmic_power_module_info *pbi; |
| 673 | struct power_supply_config psy_cfg = {}; | ||
| 656 | 674 | ||
| 657 | dev_dbg(dev, "pmic-battery: found pmic battery device\n"); | 675 | dev_dbg(dev, "pmic-battery: found pmic battery device\n"); |
| 658 | 676 | ||
| @@ -666,6 +684,7 @@ static int probe(int irq, struct device *dev) | |||
| 666 | pbi->dev = dev; | 684 | pbi->dev = dev; |
| 667 | pbi->irq = irq; | 685 | pbi->irq = irq; |
| 668 | dev_set_drvdata(dev, pbi); | 686 | dev_set_drvdata(dev, pbi); |
| 687 | psy_cfg.drv_data = pbi; | ||
| 669 | 688 | ||
| 670 | /* initialize all required framework before enabling interrupts */ | 689 | /* initialize all required framework before enabling interrupts */ |
| 671 | INIT_WORK(&pbi->handler, pmic_battery_handle_intrpt); | 690 | INIT_WORK(&pbi->handler, pmic_battery_handle_intrpt); |
| @@ -687,16 +706,12 @@ static int probe(int irq, struct device *dev) | |||
| 687 | } | 706 | } |
| 688 | 707 | ||
| 689 | /* register pmic-batt with power supply subsystem */ | 708 | /* register pmic-batt with power supply subsystem */ |
| 690 | pbi->batt.name = "pmic-batt"; | 709 | pbi->batt = power_supply_register(dev, &pmic_usb_desc, &psy_cfg); |
| 691 | pbi->batt.type = POWER_SUPPLY_TYPE_BATTERY; | 710 | if (IS_ERR(pbi->batt)) { |
| 692 | pbi->batt.properties = pmic_battery_props; | ||
| 693 | pbi->batt.num_properties = ARRAY_SIZE(pmic_battery_props); | ||
| 694 | pbi->batt.get_property = pmic_battery_get_property; | ||
| 695 | retval = power_supply_register(dev, &pbi->batt); | ||
| 696 | if (retval) { | ||
| 697 | dev_err(dev, | 711 | dev_err(dev, |
| 698 | "%s(): failed to register pmic battery device with power supply subsystem\n", | 712 | "%s(): failed to register pmic battery device with power supply subsystem\n", |
| 699 | __func__); | 713 | __func__); |
| 714 | retval = PTR_ERR(pbi->batt); | ||
| 700 | goto power_reg_failed; | 715 | goto power_reg_failed; |
| 701 | } | 716 | } |
| 702 | 717 | ||
| @@ -707,16 +722,12 @@ static int probe(int irq, struct device *dev) | |||
| 707 | queue_delayed_work(pbi->monitor_wqueue, &pbi->monitor_battery, HZ * 1); | 722 | queue_delayed_work(pbi->monitor_wqueue, &pbi->monitor_battery, HZ * 1); |
| 708 | 723 | ||
| 709 | /* register pmic-usb with power supply subsystem */ | 724 | /* register pmic-usb with power supply subsystem */ |
| 710 | pbi->usb.name = "pmic-usb"; | 725 | pbi->usb = power_supply_register(dev, &pmic_batt_desc, &psy_cfg); |
| 711 | pbi->usb.type = POWER_SUPPLY_TYPE_USB; | 726 | if (IS_ERR(pbi->usb)) { |
| 712 | pbi->usb.properties = pmic_usb_props; | ||
| 713 | pbi->usb.num_properties = ARRAY_SIZE(pmic_usb_props); | ||
| 714 | pbi->usb.get_property = pmic_usb_get_property; | ||
| 715 | retval = power_supply_register(dev, &pbi->usb); | ||
| 716 | if (retval) { | ||
| 717 | dev_err(dev, | 727 | dev_err(dev, |
| 718 | "%s(): failed to register pmic usb device with power supply subsystem\n", | 728 | "%s(): failed to register pmic usb device with power supply subsystem\n", |
| 719 | __func__); | 729 | __func__); |
| 730 | retval = PTR_ERR(pbi->usb); | ||
| 720 | goto power_reg_failed_1; | 731 | goto power_reg_failed_1; |
| 721 | } | 732 | } |
| 722 | 733 | ||
| @@ -728,7 +739,7 @@ static int probe(int irq, struct device *dev) | |||
| 728 | return retval; | 739 | return retval; |
| 729 | 740 | ||
| 730 | power_reg_failed_1: | 741 | power_reg_failed_1: |
| 731 | power_supply_unregister(&pbi->batt); | 742 | power_supply_unregister(pbi->batt); |
| 732 | power_reg_failed: | 743 | power_reg_failed: |
| 733 | cancel_delayed_work_sync(&pbi->monitor_battery); | 744 | cancel_delayed_work_sync(&pbi->monitor_battery); |
| 734 | requestirq_failed: | 745 | requestirq_failed: |
| @@ -762,8 +773,8 @@ static int platform_pmic_battery_remove(struct platform_device *pdev) | |||
| 762 | cancel_delayed_work_sync(&pbi->monitor_battery); | 773 | cancel_delayed_work_sync(&pbi->monitor_battery); |
| 763 | destroy_workqueue(pbi->monitor_wqueue); | 774 | destroy_workqueue(pbi->monitor_wqueue); |
| 764 | 775 | ||
| 765 | power_supply_unregister(&pbi->usb); | 776 | power_supply_unregister(pbi->usb); |
| 766 | power_supply_unregister(&pbi->batt); | 777 | power_supply_unregister(pbi->batt); |
| 767 | 778 | ||
| 768 | cancel_work_sync(&pbi->handler); | 779 | cancel_work_sync(&pbi->handler); |
| 769 | kfree(pbi); | 780 | kfree(pbi); |
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) | |||
| 93 | 93 | ||
| 94 | static int get_capacity(struct power_supply *b) | 94 | static int get_capacity(struct power_supply *b) |
| 95 | { | 95 | { |
| 96 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | 96 | struct micro_battery *mb = dev_get_drvdata(b->dev.parent); |
| 97 | 97 | ||
| 98 | switch (mb->flag & 0x07) { | 98 | switch (mb->flag & 0x07) { |
| 99 | case MICRO_BATT_STATUS_HIGH: | 99 | case MICRO_BATT_STATUS_HIGH: |
| @@ -113,7 +113,7 @@ static int get_capacity(struct power_supply *b) | |||
| 113 | 113 | ||
| 114 | static int get_status(struct power_supply *b) | 114 | static int get_status(struct power_supply *b) |
| 115 | { | 115 | { |
| 116 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | 116 | struct micro_battery *mb = dev_get_drvdata(b->dev.parent); |
| 117 | 117 | ||
| 118 | if (mb->flag == MICRO_BATT_STATUS_UNKNOWN) | 118 | if (mb->flag == MICRO_BATT_STATUS_UNKNOWN) |
| 119 | return POWER_SUPPLY_STATUS_UNKNOWN; | 119 | return POWER_SUPPLY_STATUS_UNKNOWN; |
| @@ -132,7 +132,7 @@ static int micro_batt_get_property(struct power_supply *b, | |||
| 132 | enum power_supply_property psp, | 132 | enum power_supply_property psp, |
| 133 | union power_supply_propval *val) | 133 | union power_supply_propval *val) |
| 134 | { | 134 | { |
| 135 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | 135 | struct micro_battery *mb = dev_get_drvdata(b->dev.parent); |
| 136 | 136 | ||
| 137 | switch (psp) { | 137 | switch (psp) { |
| 138 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 138 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| @@ -180,7 +180,7 @@ static int micro_ac_get_property(struct power_supply *b, | |||
| 180 | enum power_supply_property psp, | 180 | enum power_supply_property psp, |
| 181 | union power_supply_propval *val) | 181 | union power_supply_propval *val) |
| 182 | { | 182 | { |
| 183 | struct micro_battery *mb = dev_get_drvdata(b->dev->parent); | 183 | struct micro_battery *mb = dev_get_drvdata(b->dev.parent); |
| 184 | 184 | ||
| 185 | switch (psp) { | 185 | switch (psp) { |
| 186 | case POWER_SUPPLY_PROP_ONLINE: | 186 | case POWER_SUPPLY_PROP_ONLINE: |
| @@ -202,7 +202,7 @@ static enum power_supply_property micro_batt_power_props[] = { | |||
| 202 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 202 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
| 203 | }; | 203 | }; |
| 204 | 204 | ||
| 205 | static struct power_supply micro_batt_power = { | 205 | static const struct power_supply_desc micro_batt_power_desc = { |
| 206 | .name = "main-battery", | 206 | .name = "main-battery", |
| 207 | .type = POWER_SUPPLY_TYPE_BATTERY, | 207 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 208 | .properties = micro_batt_power_props, | 208 | .properties = micro_batt_power_props, |
| @@ -215,7 +215,7 @@ static enum power_supply_property micro_ac_power_props[] = { | |||
| 215 | POWER_SUPPLY_PROP_ONLINE, | 215 | POWER_SUPPLY_PROP_ONLINE, |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
| 218 | static struct power_supply micro_ac_power = { | 218 | static const struct power_supply_desc micro_ac_power_desc = { |
| 219 | .name = "ac", | 219 | .name = "ac", |
| 220 | .type = POWER_SUPPLY_TYPE_MAINS, | 220 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 221 | .properties = micro_ac_power_props, | 221 | .properties = micro_ac_power_props, |
| @@ -223,9 +223,12 @@ static struct power_supply micro_ac_power = { | |||
| 223 | .get_property = micro_ac_get_property, | 223 | .get_property = micro_ac_get_property, |
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | static struct power_supply *micro_batt_power, *micro_ac_power; | ||
| 227 | |||
| 226 | static int micro_batt_probe(struct platform_device *pdev) | 228 | static int micro_batt_probe(struct platform_device *pdev) |
| 227 | { | 229 | { |
| 228 | struct micro_battery *mb; | 230 | struct micro_battery *mb; |
| 231 | int ret; | ||
| 229 | 232 | ||
| 230 | mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL); | 233 | mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL); |
| 231 | if (!mb) | 234 | if (!mb) |
| @@ -233,14 +236,36 @@ static int micro_batt_probe(struct platform_device *pdev) | |||
| 233 | 236 | ||
| 234 | mb->micro = dev_get_drvdata(pdev->dev.parent); | 237 | mb->micro = dev_get_drvdata(pdev->dev.parent); |
| 235 | mb->wq = create_singlethread_workqueue("ipaq-battery-wq"); | 238 | mb->wq = create_singlethread_workqueue("ipaq-battery-wq"); |
| 239 | if (!mb->wq) | ||
| 240 | return -ENOMEM; | ||
| 241 | |||
| 236 | INIT_DELAYED_WORK(&mb->update, micro_battery_work); | 242 | INIT_DELAYED_WORK(&mb->update, micro_battery_work); |
| 237 | platform_set_drvdata(pdev, mb); | 243 | platform_set_drvdata(pdev, mb); |
| 238 | queue_delayed_work(mb->wq, &mb->update, 1); | 244 | queue_delayed_work(mb->wq, &mb->update, 1); |
| 239 | power_supply_register(&pdev->dev, µ_batt_power); | 245 | |
| 240 | power_supply_register(&pdev->dev, µ_ac_power); | 246 | micro_batt_power = power_supply_register(&pdev->dev, |
| 247 | µ_batt_power_desc, NULL); | ||
| 248 | if (IS_ERR(micro_batt_power)) { | ||
| 249 | ret = PTR_ERR(micro_batt_power); | ||
| 250 | goto batt_err; | ||
| 251 | } | ||
| 252 | |||
| 253 | micro_ac_power = power_supply_register(&pdev->dev, | ||
| 254 | µ_ac_power_desc, NULL); | ||
| 255 | if (IS_ERR(micro_ac_power)) { | ||
| 256 | ret = PTR_ERR(micro_ac_power); | ||
| 257 | goto ac_err; | ||
| 258 | } | ||
| 241 | 259 | ||
| 242 | dev_info(&pdev->dev, "iPAQ micro battery driver\n"); | 260 | dev_info(&pdev->dev, "iPAQ micro battery driver\n"); |
| 243 | return 0; | 261 | return 0; |
| 262 | |||
| 263 | ac_err: | ||
| 264 | power_supply_unregister(micro_ac_power); | ||
| 265 | batt_err: | ||
| 266 | cancel_delayed_work_sync(&mb->update); | ||
| 267 | destroy_workqueue(mb->wq); | ||
| 268 | return ret; | ||
| 244 | } | 269 | } |
| 245 | 270 | ||
| 246 | static int micro_batt_remove(struct platform_device *pdev) | 271 | static int micro_batt_remove(struct platform_device *pdev) |
| @@ -248,9 +273,10 @@ static int micro_batt_remove(struct platform_device *pdev) | |||
| 248 | { | 273 | { |
| 249 | struct micro_battery *mb = platform_get_drvdata(pdev); | 274 | struct micro_battery *mb = platform_get_drvdata(pdev); |
| 250 | 275 | ||
| 251 | power_supply_unregister(µ_ac_power); | 276 | power_supply_unregister(micro_ac_power); |
| 252 | power_supply_unregister(µ_batt_power); | 277 | power_supply_unregister(micro_batt_power); |
| 253 | cancel_delayed_work_sync(&mb->update); | 278 | cancel_delayed_work_sync(&mb->update); |
| 279 | destroy_workqueue(mb->wq); | ||
| 254 | 280 | ||
| 255 | return 0; | 281 | return 0; |
| 256 | } | 282 | } |
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 0b4cf9d63291..f2a7d970388f 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c | |||
| @@ -57,11 +57,12 @@ static u16 isp170x_id[] = { | |||
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | struct isp1704_charger { | 59 | struct isp1704_charger { |
| 60 | struct device *dev; | 60 | struct device *dev; |
| 61 | struct power_supply psy; | 61 | struct power_supply *psy; |
| 62 | struct usb_phy *phy; | 62 | struct power_supply_desc psy_desc; |
| 63 | struct notifier_block nb; | 63 | struct usb_phy *phy; |
| 64 | struct work_struct work; | 64 | struct notifier_block nb; |
| 65 | struct work_struct work; | ||
| 65 | 66 | ||
| 66 | /* properties */ | 67 | /* properties */ |
| 67 | char model[8]; | 68 | char model[8]; |
| @@ -259,10 +260,10 @@ static void isp1704_charger_work(struct work_struct *data) | |||
| 259 | 260 | ||
| 260 | /* detect wall charger */ | 261 | /* detect wall charger */ |
| 261 | if (isp1704_charger_detect_dcp(isp)) { | 262 | if (isp1704_charger_detect_dcp(isp)) { |
| 262 | isp->psy.type = POWER_SUPPLY_TYPE_USB_DCP; | 263 | isp->psy_desc.type = POWER_SUPPLY_TYPE_USB_DCP; |
| 263 | isp->current_max = 1800; | 264 | isp->current_max = 1800; |
| 264 | } else { | 265 | } else { |
| 265 | isp->psy.type = POWER_SUPPLY_TYPE_USB; | 266 | isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; |
| 266 | isp->current_max = 500; | 267 | isp->current_max = 500; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| @@ -271,7 +272,7 @@ static void isp1704_charger_work(struct work_struct *data) | |||
| 271 | usb_gadget_connect(isp->phy->otg->gadget); | 272 | usb_gadget_connect(isp->phy->otg->gadget); |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 274 | if (isp->psy.type != POWER_SUPPLY_TYPE_USB_DCP) { | 275 | if (isp->psy_desc.type != POWER_SUPPLY_TYPE_USB_DCP) { |
| 275 | /* | 276 | /* |
| 276 | * Only 500mA here or high speed chirp | 277 | * Only 500mA here or high speed chirp |
| 277 | * handshaking may break | 278 | * handshaking may break |
| @@ -280,14 +281,14 @@ static void isp1704_charger_work(struct work_struct *data) | |||
| 280 | isp->current_max = 500; | 281 | isp->current_max = 500; |
| 281 | 282 | ||
| 282 | if (isp->current_max > 100) | 283 | if (isp->current_max > 100) |
| 283 | isp->psy.type = POWER_SUPPLY_TYPE_USB_CDP; | 284 | isp->psy_desc.type = POWER_SUPPLY_TYPE_USB_CDP; |
| 284 | } | 285 | } |
| 285 | break; | 286 | break; |
| 286 | case USB_EVENT_NONE: | 287 | case USB_EVENT_NONE: |
| 287 | isp->online = false; | 288 | isp->online = false; |
| 288 | isp->present = 0; | 289 | isp->present = 0; |
| 289 | isp->current_max = 0; | 290 | isp->current_max = 0; |
| 290 | isp->psy.type = POWER_SUPPLY_TYPE_USB; | 291 | isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; |
| 291 | 292 | ||
| 292 | /* | 293 | /* |
| 293 | * Disable data pullups. We need to prevent the controller from | 294 | * Disable data pullups. We need to prevent the controller from |
| @@ -306,7 +307,7 @@ static void isp1704_charger_work(struct work_struct *data) | |||
| 306 | goto out; | 307 | goto out; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | power_supply_changed(&isp->psy); | 310 | power_supply_changed(isp->psy); |
| 310 | out: | 311 | out: |
| 311 | mutex_unlock(&lock); | 312 | mutex_unlock(&lock); |
| 312 | } | 313 | } |
| @@ -326,8 +327,7 @@ static int isp1704_charger_get_property(struct power_supply *psy, | |||
| 326 | enum power_supply_property psp, | 327 | enum power_supply_property psp, |
| 327 | union power_supply_propval *val) | 328 | union power_supply_propval *val) |
| 328 | { | 329 | { |
| 329 | struct isp1704_charger *isp = | 330 | struct isp1704_charger *isp = power_supply_get_drvdata(psy); |
| 330 | container_of(psy, struct isp1704_charger, psy); | ||
| 331 | 331 | ||
| 332 | switch (psp) { | 332 | switch (psp) { |
| 333 | case POWER_SUPPLY_PROP_PRESENT: | 333 | case POWER_SUPPLY_PROP_PRESENT: |
| @@ -403,6 +403,7 @@ static int isp1704_charger_probe(struct platform_device *pdev) | |||
| 403 | { | 403 | { |
| 404 | struct isp1704_charger *isp; | 404 | struct isp1704_charger *isp; |
| 405 | int ret = -ENODEV; | 405 | int ret = -ENODEV; |
| 406 | struct power_supply_config psy_cfg = {}; | ||
| 406 | 407 | ||
| 407 | struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev); | 408 | struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev); |
| 408 | struct device_node *np = pdev->dev.of_node; | 409 | struct device_node *np = pdev->dev.of_node; |
| @@ -454,15 +455,19 @@ static int isp1704_charger_probe(struct platform_device *pdev) | |||
| 454 | if (ret < 0) | 455 | if (ret < 0) |
| 455 | goto fail1; | 456 | goto fail1; |
| 456 | 457 | ||
| 457 | isp->psy.name = "isp1704"; | 458 | isp->psy_desc.name = "isp1704"; |
| 458 | isp->psy.type = POWER_SUPPLY_TYPE_USB; | 459 | isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; |
| 459 | isp->psy.properties = power_props; | 460 | isp->psy_desc.properties = power_props; |
| 460 | isp->psy.num_properties = ARRAY_SIZE(power_props); | 461 | isp->psy_desc.num_properties = ARRAY_SIZE(power_props); |
| 461 | isp->psy.get_property = isp1704_charger_get_property; | 462 | isp->psy_desc.get_property = isp1704_charger_get_property; |
| 462 | 463 | ||
| 463 | ret = power_supply_register(isp->dev, &isp->psy); | 464 | psy_cfg.drv_data = isp; |
| 464 | if (ret) | 465 | |
| 466 | isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg); | ||
| 467 | if (IS_ERR(isp->psy)) { | ||
| 468 | ret = PTR_ERR(isp->psy); | ||
| 465 | goto fail1; | 469 | goto fail1; |
| 470 | } | ||
| 466 | 471 | ||
| 467 | /* | 472 | /* |
| 468 | * REVISIT: using work in order to allow the usb notifications to be | 473 | * REVISIT: using work in order to allow the usb notifications to be |
| @@ -498,7 +503,7 @@ static int isp1704_charger_probe(struct platform_device *pdev) | |||
| 498 | 503 | ||
| 499 | return 0; | 504 | return 0; |
| 500 | fail2: | 505 | fail2: |
| 501 | power_supply_unregister(&isp->psy); | 506 | power_supply_unregister(isp->psy); |
| 502 | fail1: | 507 | fail1: |
| 503 | isp1704_charger_set_power(isp, 0); | 508 | isp1704_charger_set_power(isp, 0); |
| 504 | fail0: | 509 | fail0: |
| @@ -512,7 +517,7 @@ static int isp1704_charger_remove(struct platform_device *pdev) | |||
| 512 | struct isp1704_charger *isp = platform_get_drvdata(pdev); | 517 | struct isp1704_charger *isp = platform_get_drvdata(pdev); |
| 513 | 518 | ||
| 514 | usb_unregister_notifier(isp->phy, &isp->nb); | 519 | usb_unregister_notifier(isp->phy, &isp->nb); |
| 515 | power_supply_unregister(&isp->psy); | 520 | power_supply_unregister(isp->psy); |
| 516 | isp1704_charger_set_power(isp, 0); | 521 | isp1704_charger_set_power(isp, 0); |
| 517 | 522 | ||
| 518 | return 0; | 523 | return 0; |
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index 9cd391d61819..abdfc21ec13f 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c | |||
| @@ -46,7 +46,8 @@ struct jz_battery { | |||
| 46 | 46 | ||
| 47 | struct completion read_completion; | 47 | struct completion read_completion; |
| 48 | 48 | ||
| 49 | struct power_supply battery; | 49 | struct power_supply *battery; |
| 50 | struct power_supply_desc battery_desc; | ||
| 50 | struct delayed_work work; | 51 | struct delayed_work work; |
| 51 | 52 | ||
| 52 | struct mutex lock; | 53 | struct mutex lock; |
| @@ -54,7 +55,7 @@ struct jz_battery { | |||
| 54 | 55 | ||
| 55 | static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) | 56 | static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) |
| 56 | { | 57 | { |
| 57 | return container_of(psy, struct jz_battery, battery); | 58 | return power_supply_get_drvdata(psy); |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | static irqreturn_t jz_battery_irq_handler(int irq, void *devid) | 61 | static irqreturn_t jz_battery_irq_handler(int irq, void *devid) |
| @@ -213,7 +214,7 @@ static void jz_battery_update(struct jz_battery *jz_battery) | |||
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | if (has_changed) | 216 | if (has_changed) |
| 216 | power_supply_changed(&jz_battery->battery); | 217 | power_supply_changed(jz_battery->battery); |
| 217 | } | 218 | } |
| 218 | 219 | ||
| 219 | static enum power_supply_property jz_battery_properties[] = { | 220 | static enum power_supply_property jz_battery_properties[] = { |
| @@ -242,8 +243,9 @@ static int jz_battery_probe(struct platform_device *pdev) | |||
| 242 | { | 243 | { |
| 243 | int ret = 0; | 244 | int ret = 0; |
| 244 | struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data; | 245 | struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data; |
| 246 | struct power_supply_config psy_cfg = {}; | ||
| 245 | struct jz_battery *jz_battery; | 247 | struct jz_battery *jz_battery; |
| 246 | struct power_supply *battery; | 248 | struct power_supply_desc *battery_desc; |
| 247 | struct resource *mem; | 249 | struct resource *mem; |
| 248 | 250 | ||
| 249 | if (!pdata) { | 251 | if (!pdata) { |
| @@ -271,14 +273,17 @@ static int jz_battery_probe(struct platform_device *pdev) | |||
| 271 | if (IS_ERR(jz_battery->base)) | 273 | if (IS_ERR(jz_battery->base)) |
| 272 | return PTR_ERR(jz_battery->base); | 274 | return PTR_ERR(jz_battery->base); |
| 273 | 275 | ||
| 274 | battery = &jz_battery->battery; | 276 | battery_desc = &jz_battery->battery_desc; |
| 275 | battery->name = pdata->info.name; | 277 | battery_desc->name = pdata->info.name; |
| 276 | battery->type = POWER_SUPPLY_TYPE_BATTERY; | 278 | battery_desc->type = POWER_SUPPLY_TYPE_BATTERY; |
| 277 | battery->properties = jz_battery_properties; | 279 | battery_desc->properties = jz_battery_properties; |
| 278 | battery->num_properties = ARRAY_SIZE(jz_battery_properties); | 280 | battery_desc->num_properties = ARRAY_SIZE(jz_battery_properties); |
| 279 | battery->get_property = jz_battery_get_property; | 281 | battery_desc->get_property = jz_battery_get_property; |
| 280 | battery->external_power_changed = jz_battery_external_power_changed; | 282 | battery_desc->external_power_changed = |
| 281 | battery->use_for_apm = 1; | 283 | jz_battery_external_power_changed; |
| 284 | battery_desc->use_for_apm = 1; | ||
| 285 | |||
| 286 | psy_cfg.drv_data = jz_battery; | ||
| 282 | 287 | ||
| 283 | jz_battery->pdata = pdata; | 288 | jz_battery->pdata = pdata; |
| 284 | jz_battery->pdev = pdev; | 289 | jz_battery->pdev = pdev; |
| @@ -330,9 +335,11 @@ static int jz_battery_probe(struct platform_device *pdev) | |||
| 330 | else | 335 | else |
| 331 | jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 0); | 336 | jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 0); |
| 332 | 337 | ||
| 333 | ret = power_supply_register(&pdev->dev, &jz_battery->battery); | 338 | jz_battery->battery = power_supply_register(&pdev->dev, battery_desc, |
| 334 | if (ret) { | 339 | &psy_cfg); |
| 340 | if (IS_ERR(jz_battery->battery)) { | ||
| 335 | dev_err(&pdev->dev, "power supply battery register failed.\n"); | 341 | dev_err(&pdev->dev, "power supply battery register failed.\n"); |
| 342 | ret = PTR_ERR(jz_battery->battery); | ||
| 336 | goto err_free_charge_irq; | 343 | goto err_free_charge_irq; |
| 337 | } | 344 | } |
| 338 | 345 | ||
| @@ -364,7 +371,7 @@ static int jz_battery_remove(struct platform_device *pdev) | |||
| 364 | gpio_free(jz_battery->pdata->gpio_charge); | 371 | gpio_free(jz_battery->pdata->gpio_charge); |
| 365 | } | 372 | } |
| 366 | 373 | ||
| 367 | power_supply_unregister(&jz_battery->battery); | 374 | power_supply_unregister(jz_battery->battery); |
| 368 | 375 | ||
| 369 | free_irq(jz_battery->irq, jz_battery); | 376 | free_irq(jz_battery->irq, jz_battery); |
| 370 | 377 | ||
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c index 32de636dcd73..7e741f1d3cd5 100644 --- a/drivers/power/lp8727_charger.c +++ b/drivers/power/lp8727_charger.c | |||
| @@ -80,9 +80,9 @@ enum lp8727_die_temp { | |||
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | struct lp8727_psy { | 82 | struct lp8727_psy { |
| 83 | struct power_supply ac; | 83 | struct power_supply *ac; |
| 84 | struct power_supply usb; | 84 | struct power_supply *usb; |
| 85 | struct power_supply batt; | 85 | struct power_supply *batt; |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | struct lp8727_chg { | 88 | struct lp8727_chg { |
| @@ -242,9 +242,9 @@ static void lp8727_delayed_func(struct work_struct *_work) | |||
| 242 | lp8727_id_detection(pchg, idno, vbus); | 242 | lp8727_id_detection(pchg, idno, vbus); |
| 243 | lp8727_enable_chgdet(pchg); | 243 | lp8727_enable_chgdet(pchg); |
| 244 | 244 | ||
| 245 | power_supply_changed(&pchg->psy->ac); | 245 | power_supply_changed(pchg->psy->ac); |
| 246 | power_supply_changed(&pchg->psy->usb); | 246 | power_supply_changed(pchg->psy->usb); |
| 247 | power_supply_changed(&pchg->psy->batt); | 247 | power_supply_changed(pchg->psy->batt); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static irqreturn_t lp8727_isr_func(int irq, void *ptr) | 250 | static irqreturn_t lp8727_isr_func(int irq, void *ptr) |
| @@ -311,12 +311,12 @@ static int lp8727_charger_get_property(struct power_supply *psy, | |||
| 311 | enum power_supply_property psp, | 311 | enum power_supply_property psp, |
| 312 | union power_supply_propval *val) | 312 | union power_supply_propval *val) |
| 313 | { | 313 | { |
| 314 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); | 314 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent); |
| 315 | 315 | ||
| 316 | if (psp != POWER_SUPPLY_PROP_ONLINE) | 316 | if (psp != POWER_SUPPLY_PROP_ONLINE) |
| 317 | return -EINVAL; | 317 | return -EINVAL; |
| 318 | 318 | ||
| 319 | val->intval = lp8727_is_charger_attached(psy->name, pchg->devid); | 319 | val->intval = lp8727_is_charger_attached(psy->desc->name, pchg->devid); |
| 320 | 320 | ||
| 321 | return 0; | 321 | return 0; |
| 322 | } | 322 | } |
| @@ -337,14 +337,14 @@ static int lp8727_battery_get_property(struct power_supply *psy, | |||
| 337 | enum power_supply_property psp, | 337 | enum power_supply_property psp, |
| 338 | union power_supply_propval *val) | 338 | union power_supply_propval *val) |
| 339 | { | 339 | { |
| 340 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); | 340 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent); |
| 341 | struct lp8727_platform_data *pdata = pchg->pdata; | 341 | struct lp8727_platform_data *pdata = pchg->pdata; |
| 342 | enum lp8727_die_temp temp; | 342 | enum lp8727_die_temp temp; |
| 343 | u8 read; | 343 | u8 read; |
| 344 | 344 | ||
| 345 | switch (psp) { | 345 | switch (psp) { |
| 346 | case POWER_SUPPLY_PROP_STATUS: | 346 | case POWER_SUPPLY_PROP_STATUS: |
| 347 | if (!lp8727_is_charger_attached(psy->name, pchg->devid)) { | 347 | if (!lp8727_is_charger_attached(psy->desc->name, pchg->devid)) { |
| 348 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 348 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
| 349 | return 0; | 349 | return 0; |
| 350 | } | 350 | } |
| @@ -400,13 +400,13 @@ static int lp8727_battery_get_property(struct power_supply *psy, | |||
| 400 | 400 | ||
| 401 | static void lp8727_charger_changed(struct power_supply *psy) | 401 | static void lp8727_charger_changed(struct power_supply *psy) |
| 402 | { | 402 | { |
| 403 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); | 403 | struct lp8727_chg *pchg = dev_get_drvdata(psy->dev.parent); |
| 404 | u8 eoc_level; | 404 | u8 eoc_level; |
| 405 | u8 ichg; | 405 | u8 ichg; |
| 406 | u8 val; | 406 | u8 val; |
| 407 | 407 | ||
| 408 | /* skip if no charger exists */ | 408 | /* skip if no charger exists */ |
| 409 | if (!lp8727_is_charger_attached(psy->name, pchg->devid)) | 409 | if (!lp8727_is_charger_attached(psy->desc->name, pchg->devid)) |
| 410 | return; | 410 | return; |
| 411 | 411 | ||
| 412 | /* update charging parameters */ | 412 | /* update charging parameters */ |
| @@ -418,8 +418,34 @@ static void lp8727_charger_changed(struct power_supply *psy) | |||
| 418 | } | 418 | } |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | static const struct power_supply_desc lp8727_ac_desc = { | ||
| 422 | .name = "ac", | ||
| 423 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 424 | .properties = lp8727_charger_prop, | ||
| 425 | .num_properties = ARRAY_SIZE(lp8727_charger_prop), | ||
| 426 | .get_property = lp8727_charger_get_property, | ||
| 427 | }; | ||
| 428 | |||
| 429 | static const struct power_supply_desc lp8727_usb_desc = { | ||
| 430 | .name = "usb", | ||
| 431 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 432 | .properties = lp8727_charger_prop, | ||
| 433 | .num_properties = ARRAY_SIZE(lp8727_charger_prop), | ||
| 434 | .get_property = lp8727_charger_get_property, | ||
| 435 | }; | ||
| 436 | |||
| 437 | static const struct power_supply_desc lp8727_batt_desc = { | ||
| 438 | .name = "main_batt", | ||
| 439 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 440 | .properties = lp8727_battery_prop, | ||
| 441 | .num_properties = ARRAY_SIZE(lp8727_battery_prop), | ||
| 442 | .get_property = lp8727_battery_get_property, | ||
| 443 | .external_power_changed = lp8727_charger_changed, | ||
| 444 | }; | ||
| 445 | |||
| 421 | static int lp8727_register_psy(struct lp8727_chg *pchg) | 446 | static int lp8727_register_psy(struct lp8727_chg *pchg) |
| 422 | { | 447 | { |
| 448 | struct power_supply_config psy_cfg = {}; /* Only for ac and usb */ | ||
| 423 | struct lp8727_psy *psy; | 449 | struct lp8727_psy *psy; |
| 424 | 450 | ||
| 425 | psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL); | 451 | psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL); |
| @@ -428,44 +454,28 @@ static int lp8727_register_psy(struct lp8727_chg *pchg) | |||
| 428 | 454 | ||
| 429 | pchg->psy = psy; | 455 | pchg->psy = psy; |
| 430 | 456 | ||
| 431 | psy->ac.name = "ac"; | 457 | psy_cfg.supplied_to = battery_supplied_to; |
| 432 | psy->ac.type = POWER_SUPPLY_TYPE_MAINS; | 458 | psy_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to); |
| 433 | psy->ac.properties = lp8727_charger_prop; | ||
| 434 | psy->ac.num_properties = ARRAY_SIZE(lp8727_charger_prop); | ||
| 435 | psy->ac.get_property = lp8727_charger_get_property; | ||
| 436 | psy->ac.supplied_to = battery_supplied_to; | ||
| 437 | psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to); | ||
| 438 | 459 | ||
| 439 | if (power_supply_register(pchg->dev, &psy->ac)) | 460 | psy->ac = power_supply_register(pchg->dev, &lp8727_ac_desc, &psy_cfg); |
| 461 | if (IS_ERR(psy->ac)) | ||
| 440 | goto err_psy_ac; | 462 | goto err_psy_ac; |
| 441 | 463 | ||
| 442 | psy->usb.name = "usb"; | 464 | psy->usb = power_supply_register(pchg->dev, &lp8727_usb_desc, |
| 443 | psy->usb.type = POWER_SUPPLY_TYPE_USB; | 465 | &psy_cfg); |
| 444 | psy->usb.properties = lp8727_charger_prop; | 466 | if (IS_ERR(psy->usb)) |
| 445 | psy->usb.num_properties = ARRAY_SIZE(lp8727_charger_prop); | ||
| 446 | psy->usb.get_property = lp8727_charger_get_property; | ||
| 447 | psy->usb.supplied_to = battery_supplied_to; | ||
| 448 | psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to); | ||
| 449 | |||
| 450 | if (power_supply_register(pchg->dev, &psy->usb)) | ||
| 451 | goto err_psy_usb; | 467 | goto err_psy_usb; |
| 452 | 468 | ||
| 453 | psy->batt.name = "main_batt"; | 469 | psy->batt = power_supply_register(pchg->dev, &lp8727_batt_desc, NULL); |
| 454 | psy->batt.type = POWER_SUPPLY_TYPE_BATTERY; | 470 | if (IS_ERR(psy->batt)) |
| 455 | psy->batt.properties = lp8727_battery_prop; | ||
| 456 | psy->batt.num_properties = ARRAY_SIZE(lp8727_battery_prop); | ||
| 457 | psy->batt.get_property = lp8727_battery_get_property; | ||
| 458 | psy->batt.external_power_changed = lp8727_charger_changed; | ||
| 459 | |||
| 460 | if (power_supply_register(pchg->dev, &psy->batt)) | ||
| 461 | goto err_psy_batt; | 471 | goto err_psy_batt; |
| 462 | 472 | ||
| 463 | return 0; | 473 | return 0; |
| 464 | 474 | ||
| 465 | err_psy_batt: | 475 | err_psy_batt: |
| 466 | power_supply_unregister(&psy->usb); | 476 | power_supply_unregister(psy->usb); |
| 467 | err_psy_usb: | 477 | err_psy_usb: |
| 468 | power_supply_unregister(&psy->ac); | 478 | power_supply_unregister(psy->ac); |
| 469 | err_psy_ac: | 479 | err_psy_ac: |
| 470 | return -EPERM; | 480 | return -EPERM; |
| 471 | } | 481 | } |
| @@ -477,9 +487,9 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg) | |||
| 477 | if (!psy) | 487 | if (!psy) |
| 478 | return; | 488 | return; |
| 479 | 489 | ||
| 480 | power_supply_unregister(&psy->ac); | 490 | power_supply_unregister(psy->ac); |
| 481 | power_supply_unregister(&psy->usb); | 491 | power_supply_unregister(psy->usb); |
| 482 | power_supply_unregister(&psy->batt); | 492 | power_supply_unregister(psy->batt); |
| 483 | } | 493 | } |
| 484 | 494 | ||
| 485 | #ifdef CONFIG_OF | 495 | #ifdef CONFIG_OF |
diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c index 21fc233c7d61..f5a48fd68b01 100644 --- a/drivers/power/lp8788-charger.c +++ b/drivers/power/lp8788-charger.c | |||
| @@ -105,8 +105,8 @@ struct lp8788_chg_irq { | |||
| 105 | */ | 105 | */ |
| 106 | struct lp8788_charger { | 106 | struct lp8788_charger { |
| 107 | struct lp8788 *lp; | 107 | struct lp8788 *lp; |
| 108 | struct power_supply charger; | 108 | struct power_supply *charger; |
| 109 | struct power_supply battery; | 109 | struct power_supply *battery; |
| 110 | struct work_struct charger_work; | 110 | struct work_struct charger_work; |
| 111 | struct iio_channel *chan[LP8788_NUM_CHG_ADC]; | 111 | struct iio_channel *chan[LP8788_NUM_CHG_ADC]; |
| 112 | struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS]; | 112 | struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS]; |
| @@ -148,7 +148,7 @@ static int lp8788_charger_get_property(struct power_supply *psy, | |||
| 148 | enum power_supply_property psp, | 148 | enum power_supply_property psp, |
| 149 | union power_supply_propval *val) | 149 | union power_supply_propval *val) |
| 150 | { | 150 | { |
| 151 | struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent); | 151 | struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent); |
| 152 | u8 read; | 152 | u8 read; |
| 153 | 153 | ||
| 154 | switch (psp) { | 154 | switch (psp) { |
| @@ -337,7 +337,7 @@ static int lp8788_battery_get_property(struct power_supply *psy, | |||
| 337 | enum power_supply_property psp, | 337 | enum power_supply_property psp, |
| 338 | union power_supply_propval *val) | 338 | union power_supply_propval *val) |
| 339 | { | 339 | { |
| 340 | struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent); | 340 | struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent); |
| 341 | 341 | ||
| 342 | switch (psp) { | 342 | switch (psp) { |
| 343 | case POWER_SUPPLY_PROP_STATUS: | 343 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -397,36 +397,50 @@ static int lp8788_update_charger_params(struct platform_device *pdev, | |||
| 397 | return 0; | 397 | return 0; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | static const struct power_supply_desc lp8788_psy_charger_desc = { | ||
| 401 | .name = LP8788_CHARGER_NAME, | ||
| 402 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 403 | .properties = lp8788_charger_prop, | ||
| 404 | .num_properties = ARRAY_SIZE(lp8788_charger_prop), | ||
| 405 | .get_property = lp8788_charger_get_property, | ||
| 406 | }; | ||
| 407 | |||
| 408 | static const struct power_supply_desc lp8788_psy_battery_desc = { | ||
| 409 | .name = LP8788_BATTERY_NAME, | ||
| 410 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 411 | .properties = lp8788_battery_prop, | ||
| 412 | .num_properties = ARRAY_SIZE(lp8788_battery_prop), | ||
| 413 | .get_property = lp8788_battery_get_property, | ||
| 414 | }; | ||
| 415 | |||
| 400 | static int lp8788_psy_register(struct platform_device *pdev, | 416 | static int lp8788_psy_register(struct platform_device *pdev, |
| 401 | struct lp8788_charger *pchg) | 417 | struct lp8788_charger *pchg) |
| 402 | { | 418 | { |
| 403 | pchg->charger.name = LP8788_CHARGER_NAME; | 419 | struct power_supply_config charger_cfg = {}; |
| 404 | pchg->charger.type = POWER_SUPPLY_TYPE_MAINS; | 420 | |
| 405 | pchg->charger.properties = lp8788_charger_prop; | 421 | charger_cfg.supplied_to = battery_supplied_to; |
| 406 | pchg->charger.num_properties = ARRAY_SIZE(lp8788_charger_prop); | 422 | charger_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to); |
| 407 | pchg->charger.get_property = lp8788_charger_get_property; | ||
| 408 | pchg->charger.supplied_to = battery_supplied_to; | ||
| 409 | pchg->charger.num_supplicants = ARRAY_SIZE(battery_supplied_to); | ||
| 410 | |||
| 411 | if (power_supply_register(&pdev->dev, &pchg->charger)) | ||
| 412 | return -EPERM; | ||
| 413 | 423 | ||
| 414 | pchg->battery.name = LP8788_BATTERY_NAME; | 424 | pchg->charger = power_supply_register(&pdev->dev, |
| 415 | pchg->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 425 | &lp8788_psy_charger_desc, |
| 416 | pchg->battery.properties = lp8788_battery_prop; | 426 | &charger_cfg); |
| 417 | pchg->battery.num_properties = ARRAY_SIZE(lp8788_battery_prop); | 427 | if (IS_ERR(pchg->charger)) |
| 418 | pchg->battery.get_property = lp8788_battery_get_property; | 428 | return -EPERM; |
| 419 | 429 | ||
| 420 | if (power_supply_register(&pdev->dev, &pchg->battery)) | 430 | pchg->battery = power_supply_register(&pdev->dev, |
| 431 | &lp8788_psy_battery_desc, NULL); | ||
| 432 | if (IS_ERR(pchg->battery)) { | ||
| 433 | power_supply_unregister(pchg->charger); | ||
| 421 | return -EPERM; | 434 | return -EPERM; |
| 435 | } | ||
| 422 | 436 | ||
| 423 | return 0; | 437 | return 0; |
| 424 | } | 438 | } |
| 425 | 439 | ||
| 426 | static void lp8788_psy_unregister(struct lp8788_charger *pchg) | 440 | static void lp8788_psy_unregister(struct lp8788_charger *pchg) |
| 427 | { | 441 | { |
| 428 | power_supply_unregister(&pchg->battery); | 442 | power_supply_unregister(pchg->battery); |
| 429 | power_supply_unregister(&pchg->charger); | 443 | power_supply_unregister(pchg->charger); |
| 430 | } | 444 | } |
| 431 | 445 | ||
| 432 | static void lp8788_charger_event(struct work_struct *work) | 446 | static void lp8788_charger_event(struct work_struct *work) |
| @@ -470,8 +484,8 @@ static irqreturn_t lp8788_charger_irq_thread(int virq, void *ptr) | |||
| 470 | case LP8788_INT_EOC: | 484 | case LP8788_INT_EOC: |
| 471 | case LP8788_INT_BATT_LOW: | 485 | case LP8788_INT_BATT_LOW: |
| 472 | case LP8788_INT_NO_BATT: | 486 | case LP8788_INT_NO_BATT: |
| 473 | power_supply_changed(&pchg->charger); | 487 | power_supply_changed(pchg->charger); |
| 474 | power_supply_changed(&pchg->battery); | 488 | power_supply_changed(pchg->battery); |
| 475 | break; | 489 | break; |
| 476 | default: | 490 | default: |
| 477 | break; | 491 | break; |
diff --git a/drivers/power/ltc2941-battery-gauge.c b/drivers/power/ltc2941-battery-gauge.c index e31c927a6d16..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 | } |
| @@ -440,30 +441,32 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
| 440 | } else { | 441 | } else { |
| 441 | if (prescaler_exp > LTC2941_MAX_PRESCALER_EXP) | 442 | if (prescaler_exp > LTC2941_MAX_PRESCALER_EXP) |
| 442 | prescaler_exp = LTC2941_MAX_PRESCALER_EXP; | 443 | prescaler_exp = LTC2941_MAX_PRESCALER_EXP; |
| 443 | info->Qlsb = ((58 * 50000) / r_sense) / | 444 | info->Qlsb = ((85 * 50000) / r_sense) / |
| 444 | (128 / (1 << prescaler_exp)); | 445 | (128 / (1 << prescaler_exp)); |
| 445 | } | 446 | } |
| 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); | 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: |
diff --git a/drivers/power/max14577_charger.c b/drivers/power/max14577_charger.c index ef4103ee6021..a36bcaf62dd4 100644 --- a/drivers/power/max14577_charger.c +++ b/drivers/power/max14577_charger.c | |||
| @@ -22,12 +22,9 @@ | |||
| 22 | #include <linux/mfd/max14577.h> | 22 | #include <linux/mfd/max14577.h> |
| 23 | 23 | ||
| 24 | struct max14577_charger { | 24 | struct max14577_charger { |
| 25 | struct device *dev; | 25 | struct device *dev; |
| 26 | struct max14577 *max14577; | 26 | struct max14577 *max14577; |
| 27 | struct power_supply charger; | 27 | struct power_supply *charger; |
| 28 | |||
| 29 | unsigned int charging_state; | ||
| 30 | unsigned int battery_state; | ||
| 31 | 28 | ||
| 32 | struct max14577_charger_platform_data *pdata; | 29 | struct max14577_charger_platform_data *pdata; |
| 33 | }; | 30 | }; |
| @@ -57,10 +54,10 @@ static enum max14577_muic_charger_type maxim_get_charger_type( | |||
| 57 | } | 54 | } |
| 58 | } | 55 | } |
| 59 | 56 | ||
| 60 | static int max14577_get_charger_state(struct max14577_charger *chg) | 57 | static int max14577_get_charger_state(struct max14577_charger *chg, int *val) |
| 61 | { | 58 | { |
| 62 | struct regmap *rmap = chg->max14577->regmap; | 59 | struct regmap *rmap = chg->max14577->regmap; |
| 63 | int state = POWER_SUPPLY_STATUS_DISCHARGING; | 60 | int ret; |
| 64 | u8 reg_data; | 61 | u8 reg_data; |
| 65 | 62 | ||
| 66 | /* | 63 | /* |
| @@ -74,23 +71,32 @@ static int max14577_get_charger_state(struct max14577_charger *chg) | |||
| 74 | * - handle properly dead-battery charging (respect timer) | 71 | * - handle properly dead-battery charging (respect timer) |
| 75 | * - handle timers (fast-charge and prequal) /MBCCHGERR/ | 72 | * - handle timers (fast-charge and prequal) /MBCCHGERR/ |
| 76 | */ | 73 | */ |
| 77 | max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, ®_data); | 74 | ret = max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, ®_data); |
| 78 | if ((reg_data & CHGCTRL2_MBCHOSTEN_MASK) == 0) | 75 | if (ret < 0) |
| 79 | goto state_set; | 76 | goto out; |
| 77 | |||
| 78 | if ((reg_data & CHGCTRL2_MBCHOSTEN_MASK) == 0) { | ||
| 79 | *val = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 80 | goto out; | ||
| 81 | } | ||
| 82 | |||
| 83 | ret = max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data); | ||
| 84 | if (ret < 0) | ||
| 85 | goto out; | ||
| 80 | 86 | ||
| 81 | max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data); | ||
| 82 | if (reg_data & STATUS3_CGMBC_MASK) { | 87 | if (reg_data & STATUS3_CGMBC_MASK) { |
| 83 | /* Charger or USB-cable is connected */ | 88 | /* Charger or USB-cable is connected */ |
| 84 | if (reg_data & STATUS3_EOC_MASK) | 89 | if (reg_data & STATUS3_EOC_MASK) |
| 85 | state = POWER_SUPPLY_STATUS_FULL; | 90 | *val = POWER_SUPPLY_STATUS_FULL; |
| 86 | else | 91 | else |
| 87 | state = POWER_SUPPLY_STATUS_CHARGING; | 92 | *val = POWER_SUPPLY_STATUS_CHARGING; |
| 88 | goto state_set; | 93 | goto out; |
| 89 | } | 94 | } |
| 90 | 95 | ||
| 91 | state_set: | 96 | *val = POWER_SUPPLY_STATUS_DISCHARGING; |
| 92 | chg->charging_state = state; | 97 | |
| 93 | return state; | 98 | out: |
| 99 | return ret; | ||
| 94 | } | 100 | } |
| 95 | 101 | ||
| 96 | /* | 102 | /* |
| @@ -98,8 +104,10 @@ state_set: | |||
| 98 | * - POWER_SUPPLY_CHARGE_TYPE_NONE | 104 | * - POWER_SUPPLY_CHARGE_TYPE_NONE |
| 99 | * - POWER_SUPPLY_CHARGE_TYPE_FAST | 105 | * - POWER_SUPPLY_CHARGE_TYPE_FAST |
| 100 | */ | 106 | */ |
| 101 | static int max14577_get_charge_type(struct max14577_charger *chg) | 107 | static int max14577_get_charge_type(struct max14577_charger *chg, int *val) |
| 102 | { | 108 | { |
| 109 | int ret, charging; | ||
| 110 | |||
| 103 | /* | 111 | /* |
| 104 | * TODO: CHARGE_TYPE_TRICKLE (VCHGR_RC or EOC)? | 112 | * TODO: CHARGE_TYPE_TRICKLE (VCHGR_RC or EOC)? |
| 105 | * As spec says: | 113 | * As spec says: |
| @@ -108,18 +116,29 @@ static int max14577_get_charge_type(struct max14577_charger *chg) | |||
| 108 | * top-off timer starts. The device continues to trickle | 116 | * top-off timer starts. The device continues to trickle |
| 109 | * charge the battery until the top-off timer runs out." | 117 | * charge the battery until the top-off timer runs out." |
| 110 | */ | 118 | */ |
| 111 | if (max14577_get_charger_state(chg) == POWER_SUPPLY_STATUS_CHARGING) | 119 | ret = max14577_get_charger_state(chg, &charging); |
| 112 | return POWER_SUPPLY_CHARGE_TYPE_FAST; | 120 | if (ret < 0) |
| 113 | return POWER_SUPPLY_CHARGE_TYPE_NONE; | 121 | return ret; |
| 122 | |||
| 123 | if (charging == POWER_SUPPLY_STATUS_CHARGING) | ||
| 124 | *val = POWER_SUPPLY_CHARGE_TYPE_FAST; | ||
| 125 | else | ||
| 126 | *val = POWER_SUPPLY_CHARGE_TYPE_NONE; | ||
| 127 | |||
| 128 | return 0; | ||
| 114 | } | 129 | } |
| 115 | 130 | ||
| 116 | static int max14577_get_online(struct max14577_charger *chg) | 131 | static int max14577_get_online(struct max14577_charger *chg, int *val) |
| 117 | { | 132 | { |
| 118 | struct regmap *rmap = chg->max14577->regmap; | 133 | struct regmap *rmap = chg->max14577->regmap; |
| 119 | u8 reg_data; | 134 | u8 reg_data; |
| 135 | int ret; | ||
| 120 | enum max14577_muic_charger_type chg_type; | 136 | enum max14577_muic_charger_type chg_type; |
| 121 | 137 | ||
| 122 | max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data); | 138 | ret = max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data); |
| 139 | if (ret < 0) | ||
| 140 | return ret; | ||
| 141 | |||
| 123 | reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT); | 142 | reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT); |
| 124 | chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data); | 143 | chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data); |
| 125 | switch (chg_type) { | 144 | switch (chg_type) { |
| @@ -129,14 +148,17 @@ static int max14577_get_online(struct max14577_charger *chg) | |||
| 129 | case MAX14577_CHARGER_TYPE_SPECIAL_1A: | 148 | case MAX14577_CHARGER_TYPE_SPECIAL_1A: |
| 130 | case MAX14577_CHARGER_TYPE_DEAD_BATTERY: | 149 | case MAX14577_CHARGER_TYPE_DEAD_BATTERY: |
| 131 | case MAX77836_CHARGER_TYPE_SPECIAL_BIAS: | 150 | case MAX77836_CHARGER_TYPE_SPECIAL_BIAS: |
| 132 | return 1; | 151 | *val = 1; |
| 152 | break; | ||
| 133 | case MAX14577_CHARGER_TYPE_NONE: | 153 | case MAX14577_CHARGER_TYPE_NONE: |
| 134 | case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: | 154 | case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: |
| 135 | case MAX14577_CHARGER_TYPE_RESERVED: | 155 | case MAX14577_CHARGER_TYPE_RESERVED: |
| 136 | case MAX77836_CHARGER_TYPE_RESERVED: | 156 | case MAX77836_CHARGER_TYPE_RESERVED: |
| 137 | default: | 157 | default: |
| 138 | return 0; | 158 | *val = 0; |
| 139 | } | 159 | } |
| 160 | |||
| 161 | return 0; | ||
| 140 | } | 162 | } |
| 141 | 163 | ||
| 142 | /* | 164 | /* |
| @@ -145,30 +167,38 @@ static int max14577_get_online(struct max14577_charger *chg) | |||
| 145 | * - POWER_SUPPLY_HEALTH_OVERVOLTAGE | 167 | * - POWER_SUPPLY_HEALTH_OVERVOLTAGE |
| 146 | * - POWER_SUPPLY_HEALTH_GOOD | 168 | * - POWER_SUPPLY_HEALTH_GOOD |
| 147 | */ | 169 | */ |
| 148 | static int max14577_get_battery_health(struct max14577_charger *chg) | 170 | static int max14577_get_battery_health(struct max14577_charger *chg, int *val) |
| 149 | { | 171 | { |
| 150 | struct regmap *rmap = chg->max14577->regmap; | 172 | struct regmap *rmap = chg->max14577->regmap; |
| 151 | int state = POWER_SUPPLY_HEALTH_GOOD; | 173 | int ret; |
| 152 | u8 reg_data; | 174 | u8 reg_data; |
| 153 | enum max14577_muic_charger_type chg_type; | 175 | enum max14577_muic_charger_type chg_type; |
| 154 | 176 | ||
| 155 | max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data); | 177 | ret = max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data); |
| 178 | if (ret < 0) | ||
| 179 | goto out; | ||
| 180 | |||
| 156 | reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT); | 181 | reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT); |
| 157 | chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data); | 182 | chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data); |
| 158 | if (chg_type == MAX14577_CHARGER_TYPE_DEAD_BATTERY) { | 183 | if (chg_type == MAX14577_CHARGER_TYPE_DEAD_BATTERY) { |
| 159 | state = POWER_SUPPLY_HEALTH_DEAD; | 184 | *val = POWER_SUPPLY_HEALTH_DEAD; |
| 160 | goto state_set; | 185 | goto out; |
| 161 | } | 186 | } |
| 162 | 187 | ||
| 163 | max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data); | 188 | ret = max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data); |
| 189 | if (ret < 0) | ||
| 190 | goto out; | ||
| 191 | |||
| 164 | if (reg_data & STATUS3_OVP_MASK) { | 192 | if (reg_data & STATUS3_OVP_MASK) { |
| 165 | state = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | 193 | *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; |
| 166 | goto state_set; | 194 | goto out; |
| 167 | } | 195 | } |
| 168 | 196 | ||
| 169 | state_set: | 197 | /* Not dead, not overvoltage */ |
| 170 | chg->battery_state = state; | 198 | *val = POWER_SUPPLY_HEALTH_GOOD; |
| 171 | return state; | 199 | |
| 200 | out: | ||
| 201 | return ret; | ||
| 172 | } | 202 | } |
| 173 | 203 | ||
| 174 | /* | 204 | /* |
| @@ -176,9 +206,11 @@ state_set: | |||
| 176 | * The max14577 chip doesn't report any status of battery presence. | 206 | * The max14577 chip doesn't report any status of battery presence. |
| 177 | * Lets assume that it will always be used with some battery. | 207 | * Lets assume that it will always be used with some battery. |
| 178 | */ | 208 | */ |
| 179 | static int max14577_get_present(struct max14577_charger *chg) | 209 | static int max14577_get_present(struct max14577_charger *chg, int *val) |
| 180 | { | 210 | { |
| 181 | return 1; | 211 | *val = 1; |
| 212 | |||
| 213 | return 0; | ||
| 182 | } | 214 | } |
| 183 | 215 | ||
| 184 | static int max14577_set_fast_charge_timer(struct max14577_charger *chg, | 216 | static int max14577_set_fast_charge_timer(struct max14577_charger *chg, |
| @@ -389,26 +421,24 @@ static int max14577_charger_get_property(struct power_supply *psy, | |||
| 389 | enum power_supply_property psp, | 421 | enum power_supply_property psp, |
| 390 | union power_supply_propval *val) | 422 | union power_supply_propval *val) |
| 391 | { | 423 | { |
| 392 | struct max14577_charger *chg = container_of(psy, | 424 | struct max14577_charger *chg = power_supply_get_drvdata(psy); |
| 393 | struct max14577_charger, | ||
| 394 | charger); | ||
| 395 | int ret = 0; | 425 | int ret = 0; |
| 396 | 426 | ||
| 397 | switch (psp) { | 427 | switch (psp) { |
| 398 | case POWER_SUPPLY_PROP_STATUS: | 428 | case POWER_SUPPLY_PROP_STATUS: |
| 399 | val->intval = max14577_get_charger_state(chg); | 429 | ret = max14577_get_charger_state(chg, &val->intval); |
| 400 | break; | 430 | break; |
| 401 | case POWER_SUPPLY_PROP_CHARGE_TYPE: | 431 | case POWER_SUPPLY_PROP_CHARGE_TYPE: |
| 402 | val->intval = max14577_get_charge_type(chg); | 432 | ret = max14577_get_charge_type(chg, &val->intval); |
| 403 | break; | 433 | break; |
| 404 | case POWER_SUPPLY_PROP_HEALTH: | 434 | case POWER_SUPPLY_PROP_HEALTH: |
| 405 | val->intval = max14577_get_battery_health(chg); | 435 | ret = max14577_get_battery_health(chg, &val->intval); |
| 406 | break; | 436 | break; |
| 407 | case POWER_SUPPLY_PROP_PRESENT: | 437 | case POWER_SUPPLY_PROP_PRESENT: |
| 408 | val->intval = max14577_get_present(chg); | 438 | ret = max14577_get_present(chg, &val->intval); |
| 409 | break; | 439 | break; |
| 410 | case POWER_SUPPLY_PROP_ONLINE: | 440 | case POWER_SUPPLY_PROP_ONLINE: |
| 411 | val->intval = max14577_get_online(chg); | 441 | ret = max14577_get_online(chg, &val->intval); |
| 412 | break; | 442 | break; |
| 413 | case POWER_SUPPLY_PROP_MODEL_NAME: | 443 | case POWER_SUPPLY_PROP_MODEL_NAME: |
| 414 | BUILD_BUG_ON(ARRAY_SIZE(model_names) != MAXIM_DEVICE_TYPE_NUM); | 444 | BUILD_BUG_ON(ARRAY_SIZE(model_names) != MAXIM_DEVICE_TYPE_NUM); |
| @@ -424,6 +454,14 @@ static int max14577_charger_get_property(struct power_supply *psy, | |||
| 424 | return ret; | 454 | return ret; |
| 425 | } | 455 | } |
| 426 | 456 | ||
| 457 | static const struct power_supply_desc max14577_charger_desc = { | ||
| 458 | .name = "max14577-charger", | ||
| 459 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 460 | .properties = max14577_charger_props, | ||
| 461 | .num_properties = ARRAY_SIZE(max14577_charger_props), | ||
| 462 | .get_property = max14577_charger_get_property, | ||
| 463 | }; | ||
| 464 | |||
| 427 | #ifdef CONFIG_OF | 465 | #ifdef CONFIG_OF |
| 428 | static struct max14577_charger_platform_data *max14577_charger_dt_init( | 466 | static struct max14577_charger_platform_data *max14577_charger_dt_init( |
| 429 | struct platform_device *pdev) | 467 | struct platform_device *pdev) |
| @@ -531,6 +569,7 @@ static DEVICE_ATTR(fast_charge_timer, S_IRUGO | S_IWUSR, | |||
| 531 | static int max14577_charger_probe(struct platform_device *pdev) | 569 | static int max14577_charger_probe(struct platform_device *pdev) |
| 532 | { | 570 | { |
| 533 | struct max14577_charger *chg; | 571 | struct max14577_charger *chg; |
| 572 | struct power_supply_config psy_cfg = {}; | ||
| 534 | struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent); | 573 | struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent); |
| 535 | int ret; | 574 | int ret; |
| 536 | 575 | ||
| @@ -550,21 +589,18 @@ static int max14577_charger_probe(struct platform_device *pdev) | |||
| 550 | if (ret) | 589 | if (ret) |
| 551 | return ret; | 590 | return ret; |
| 552 | 591 | ||
| 553 | chg->charger.name = "max14577-charger", | ||
| 554 | chg->charger.type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 555 | chg->charger.properties = max14577_charger_props, | ||
| 556 | chg->charger.num_properties = ARRAY_SIZE(max14577_charger_props), | ||
| 557 | chg->charger.get_property = max14577_charger_get_property, | ||
| 558 | |||
| 559 | ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); | 592 | ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); |
| 560 | if (ret) { | 593 | if (ret) { |
| 561 | dev_err(&pdev->dev, "failed: create sysfs entry\n"); | 594 | dev_err(&pdev->dev, "failed: create sysfs entry\n"); |
| 562 | return ret; | 595 | return ret; |
| 563 | } | 596 | } |
| 564 | 597 | ||
| 565 | ret = power_supply_register(&pdev->dev, &chg->charger); | 598 | psy_cfg.drv_data = chg; |
| 566 | if (ret) { | 599 | chg->charger = power_supply_register(&pdev->dev, &max14577_charger_desc, |
| 600 | &psy_cfg); | ||
| 601 | if (IS_ERR(chg->charger)) { | ||
| 567 | dev_err(&pdev->dev, "failed: power supply register\n"); | 602 | dev_err(&pdev->dev, "failed: power supply register\n"); |
| 603 | ret = PTR_ERR(chg->charger); | ||
| 568 | goto err; | 604 | goto err; |
| 569 | } | 605 | } |
| 570 | 606 | ||
| @@ -585,7 +621,7 @@ static int max14577_charger_remove(struct platform_device *pdev) | |||
| 585 | struct max14577_charger *chg = platform_get_drvdata(pdev); | 621 | struct max14577_charger *chg = platform_get_drvdata(pdev); |
| 586 | 622 | ||
| 587 | device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); | 623 | device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); |
| 588 | power_supply_unregister(&chg->charger); | 624 | power_supply_unregister(chg->charger); |
| 589 | 625 | ||
| 590 | return 0; | 626 | return 0; |
| 591 | } | 627 | } |
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c index 14d44706327b..8689c80202b5 100644 --- a/drivers/power/max17040_battery.c +++ b/drivers/power/max17040_battery.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | struct max17040_chip { | 40 | struct max17040_chip { |
| 41 | struct i2c_client *client; | 41 | struct i2c_client *client; |
| 42 | struct delayed_work work; | 42 | struct delayed_work work; |
| 43 | struct power_supply battery; | 43 | struct power_supply *battery; |
| 44 | struct max17040_platform_data *pdata; | 44 | struct max17040_platform_data *pdata; |
| 45 | 45 | ||
| 46 | /* State Of Connect */ | 46 | /* State Of Connect */ |
| @@ -57,8 +57,7 @@ static int max17040_get_property(struct power_supply *psy, | |||
| 57 | enum power_supply_property psp, | 57 | enum power_supply_property psp, |
| 58 | union power_supply_propval *val) | 58 | union power_supply_propval *val) |
| 59 | { | 59 | { |
| 60 | struct max17040_chip *chip = container_of(psy, | 60 | struct max17040_chip *chip = power_supply_get_drvdata(psy); |
| 61 | struct max17040_chip, battery); | ||
| 62 | 61 | ||
| 63 | switch (psp) { | 62 | switch (psp) { |
| 64 | case POWER_SUPPLY_PROP_STATUS: | 63 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -188,7 +187,8 @@ static void max17040_work(struct work_struct *work) | |||
| 188 | max17040_get_online(chip->client); | 187 | max17040_get_online(chip->client); |
| 189 | max17040_get_status(chip->client); | 188 | max17040_get_status(chip->client); |
| 190 | 189 | ||
| 191 | schedule_delayed_work(&chip->work, MAX17040_DELAY); | 190 | queue_delayed_work(system_power_efficient_wq, &chip->work, |
| 191 | MAX17040_DELAY); | ||
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | static enum power_supply_property max17040_battery_props[] = { | 194 | static enum power_supply_property max17040_battery_props[] = { |
| @@ -198,12 +198,20 @@ static enum power_supply_property max17040_battery_props[] = { | |||
| 198 | POWER_SUPPLY_PROP_CAPACITY, | 198 | POWER_SUPPLY_PROP_CAPACITY, |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | static const struct power_supply_desc max17040_battery_desc = { | ||
| 202 | .name = "battery", | ||
| 203 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 204 | .get_property = max17040_get_property, | ||
| 205 | .properties = max17040_battery_props, | ||
| 206 | .num_properties = ARRAY_SIZE(max17040_battery_props), | ||
| 207 | }; | ||
| 208 | |||
| 201 | static int max17040_probe(struct i2c_client *client, | 209 | static int max17040_probe(struct i2c_client *client, |
| 202 | const struct i2c_device_id *id) | 210 | const struct i2c_device_id *id) |
| 203 | { | 211 | { |
| 204 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 212 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 213 | struct power_supply_config psy_cfg = {}; | ||
| 205 | struct max17040_chip *chip; | 214 | struct max17040_chip *chip; |
| 206 | int ret; | ||
| 207 | 215 | ||
| 208 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | 216 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) |
| 209 | return -EIO; | 217 | return -EIO; |
| @@ -216,24 +224,21 @@ static int max17040_probe(struct i2c_client *client, | |||
| 216 | chip->pdata = client->dev.platform_data; | 224 | chip->pdata = client->dev.platform_data; |
| 217 | 225 | ||
| 218 | i2c_set_clientdata(client, chip); | 226 | i2c_set_clientdata(client, chip); |
| 227 | psy_cfg.drv_data = chip; | ||
| 219 | 228 | ||
| 220 | chip->battery.name = "battery"; | 229 | chip->battery = power_supply_register(&client->dev, |
| 221 | chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 230 | &max17040_battery_desc, &psy_cfg); |
| 222 | chip->battery.get_property = max17040_get_property; | 231 | if (IS_ERR(chip->battery)) { |
| 223 | chip->battery.properties = max17040_battery_props; | ||
| 224 | chip->battery.num_properties = ARRAY_SIZE(max17040_battery_props); | ||
| 225 | |||
| 226 | ret = power_supply_register(&client->dev, &chip->battery); | ||
| 227 | if (ret) { | ||
| 228 | dev_err(&client->dev, "failed: power supply register\n"); | 232 | dev_err(&client->dev, "failed: power supply register\n"); |
| 229 | return ret; | 233 | return PTR_ERR(chip->battery); |
| 230 | } | 234 | } |
| 231 | 235 | ||
| 232 | max17040_reset(client); | 236 | max17040_reset(client); |
| 233 | max17040_get_version(client); | 237 | max17040_get_version(client); |
| 234 | 238 | ||
| 235 | INIT_DEFERRABLE_WORK(&chip->work, max17040_work); | 239 | INIT_DEFERRABLE_WORK(&chip->work, max17040_work); |
| 236 | schedule_delayed_work(&chip->work, MAX17040_DELAY); | 240 | queue_delayed_work(system_power_efficient_wq, &chip->work, |
| 241 | MAX17040_DELAY); | ||
| 237 | 242 | ||
| 238 | return 0; | 243 | return 0; |
| 239 | } | 244 | } |
| @@ -242,7 +247,7 @@ static int max17040_remove(struct i2c_client *client) | |||
| 242 | { | 247 | { |
| 243 | struct max17040_chip *chip = i2c_get_clientdata(client); | 248 | struct max17040_chip *chip = i2c_get_clientdata(client); |
| 244 | 249 | ||
| 245 | power_supply_unregister(&chip->battery); | 250 | power_supply_unregister(chip->battery); |
| 246 | cancel_delayed_work(&chip->work); | 251 | cancel_delayed_work(&chip->work); |
| 247 | return 0; | 252 | return 0; |
| 248 | } | 253 | } |
| @@ -263,7 +268,8 @@ static int max17040_resume(struct device *dev) | |||
| 263 | struct i2c_client *client = to_i2c_client(dev); | 268 | struct i2c_client *client = to_i2c_client(dev); |
| 264 | struct max17040_chip *chip = i2c_get_clientdata(client); | 269 | struct max17040_chip *chip = i2c_get_clientdata(client); |
| 265 | 270 | ||
| 266 | schedule_delayed_work(&chip->work, MAX17040_DELAY); | 271 | queue_delayed_work(system_power_efficient_wq, &chip->work, |
| 272 | MAX17040_DELAY); | ||
| 267 | return 0; | 273 | return 0; |
| 268 | } | 274 | } |
| 269 | 275 | ||
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c index 1da6c5fbdff5..6cc5e87ec031 100644 --- a/drivers/power/max17042_battery.c +++ b/drivers/power/max17042_battery.c | |||
| @@ -63,13 +63,10 @@ | |||
| 63 | #define dP_ACC_100 0x1900 | 63 | #define dP_ACC_100 0x1900 |
| 64 | #define dP_ACC_200 0x3200 | 64 | #define dP_ACC_200 0x3200 |
| 65 | 65 | ||
| 66 | #define MAX17042_IC_VERSION 0x0092 | ||
| 67 | #define MAX17047_IC_VERSION 0x00AC /* same for max17050 */ | ||
| 68 | |||
| 69 | struct max17042_chip { | 66 | struct max17042_chip { |
| 70 | struct i2c_client *client; | 67 | struct i2c_client *client; |
| 71 | struct regmap *regmap; | 68 | struct regmap *regmap; |
| 72 | struct power_supply battery; | 69 | struct power_supply *battery; |
| 73 | enum max170xx_chip_type chip_type; | 70 | enum max170xx_chip_type chip_type; |
| 74 | struct max17042_platform_data *pdata; | 71 | struct max17042_platform_data *pdata; |
| 75 | struct work_struct work; | 72 | struct work_struct work; |
| @@ -96,8 +93,7 @@ static int max17042_get_property(struct power_supply *psy, | |||
| 96 | enum power_supply_property psp, | 93 | enum power_supply_property psp, |
| 97 | union power_supply_propval *val) | 94 | union power_supply_propval *val) |
| 98 | { | 95 | { |
| 99 | struct max17042_chip *chip = container_of(psy, | 96 | struct max17042_chip *chip = power_supply_get_drvdata(psy); |
| 100 | struct max17042_chip, battery); | ||
| 101 | struct regmap *map = chip->regmap; | 97 | struct regmap *map = chip->regmap; |
| 102 | int ret; | 98 | int ret; |
| 103 | u32 data; | 99 | u32 data; |
| @@ -132,7 +128,7 @@ static int max17042_get_property(struct power_supply *psy, | |||
| 132 | val->intval *= 20000; /* Units of LSB = 20mV */ | 128 | val->intval *= 20000; /* Units of LSB = 20mV */ |
| 133 | break; | 129 | break; |
| 134 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 130 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
| 135 | if (chip->chip_type == MAX17042) | 131 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) |
| 136 | ret = regmap_read(map, MAX17042_V_empty, &data); | 132 | ret = regmap_read(map, MAX17042_V_empty, &data); |
| 137 | else | 133 | else |
| 138 | ret = regmap_read(map, MAX17047_V_empty, &data); | 134 | ret = regmap_read(map, MAX17047_V_empty, &data); |
| @@ -272,6 +268,7 @@ static inline void max17042_override_por(struct regmap *map, | |||
| 272 | static inline void max10742_unlock_model(struct max17042_chip *chip) | 268 | static inline void max10742_unlock_model(struct max17042_chip *chip) |
| 273 | { | 269 | { |
| 274 | struct regmap *map = chip->regmap; | 270 | struct regmap *map = chip->regmap; |
| 271 | |||
| 275 | regmap_write(map, MAX17042_MLOCKReg1, MODEL_UNLOCK1); | 272 | regmap_write(map, MAX17042_MLOCKReg1, MODEL_UNLOCK1); |
| 276 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2); | 273 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2); |
| 277 | } | 274 | } |
| @@ -289,6 +286,7 @@ static inline void max17042_write_model_data(struct max17042_chip *chip, | |||
| 289 | { | 286 | { |
| 290 | struct regmap *map = chip->regmap; | 287 | struct regmap *map = chip->regmap; |
| 291 | int i; | 288 | int i; |
| 289 | |||
| 292 | for (i = 0; i < size; i++) | 290 | for (i = 0; i < size; i++) |
| 293 | regmap_write(map, addr + i, | 291 | regmap_write(map, addr + i, |
| 294 | chip->pdata->config_data->cell_char_tbl[i]); | 292 | chip->pdata->config_data->cell_char_tbl[i]); |
| @@ -379,7 +377,8 @@ static void max17042_write_config_regs(struct max17042_chip *chip) | |||
| 379 | regmap_write(map, MAX17042_FilterCFG, | 377 | regmap_write(map, MAX17042_FilterCFG, |
| 380 | config->filter_cfg); | 378 | config->filter_cfg); |
| 381 | regmap_write(map, MAX17042_RelaxCFG, config->relax_cfg); | 379 | regmap_write(map, MAX17042_RelaxCFG, config->relax_cfg); |
| 382 | if (chip->chip_type == MAX17047) | 380 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047 || |
| 381 | chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050) | ||
| 383 | regmap_write(map, MAX17047_FullSOCThr, | 382 | regmap_write(map, MAX17047_FullSOCThr, |
| 384 | config->full_soc_thresh); | 383 | config->full_soc_thresh); |
| 385 | } | 384 | } |
| @@ -392,7 +391,7 @@ static void max17042_write_custom_regs(struct max17042_chip *chip) | |||
| 392 | max17042_write_verify_reg(map, MAX17042_RCOMP0, config->rcomp0); | 391 | max17042_write_verify_reg(map, MAX17042_RCOMP0, config->rcomp0); |
| 393 | max17042_write_verify_reg(map, MAX17042_TempCo, config->tcompc0); | 392 | max17042_write_verify_reg(map, MAX17042_TempCo, config->tcompc0); |
| 394 | max17042_write_verify_reg(map, MAX17042_ICHGTerm, config->ichgt_term); | 393 | max17042_write_verify_reg(map, MAX17042_ICHGTerm, config->ichgt_term); |
| 395 | if (chip->chip_type == MAX17042) { | 394 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) { |
| 396 | regmap_write(map, MAX17042_EmptyTempCo, config->empty_tempco); | 395 | regmap_write(map, MAX17042_EmptyTempCo, config->empty_tempco); |
| 397 | max17042_write_verify_reg(map, MAX17042_K_empty0, | 396 | max17042_write_verify_reg(map, MAX17042_K_empty0, |
| 398 | config->kempty0); | 397 | config->kempty0); |
| @@ -501,14 +500,14 @@ static inline void max17042_override_por_values(struct max17042_chip *chip) | |||
| 501 | 500 | ||
| 502 | max17042_override_por(map, MAX17042_FullCAP, config->fullcap); | 501 | max17042_override_por(map, MAX17042_FullCAP, config->fullcap); |
| 503 | max17042_override_por(map, MAX17042_FullCAPNom, config->fullcapnom); | 502 | max17042_override_por(map, MAX17042_FullCAPNom, config->fullcapnom); |
| 504 | if (chip->chip_type == MAX17042) | 503 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) |
| 505 | max17042_override_por(map, MAX17042_SOC_empty, | 504 | max17042_override_por(map, MAX17042_SOC_empty, |
| 506 | config->socempty); | 505 | config->socempty); |
| 507 | max17042_override_por(map, MAX17042_LAvg_empty, config->lavg_empty); | 506 | max17042_override_por(map, MAX17042_LAvg_empty, config->lavg_empty); |
| 508 | max17042_override_por(map, MAX17042_dQacc, config->dqacc); | 507 | max17042_override_por(map, MAX17042_dQacc, config->dqacc); |
| 509 | max17042_override_por(map, MAX17042_dPacc, config->dpacc); | 508 | max17042_override_por(map, MAX17042_dPacc, config->dpacc); |
| 510 | 509 | ||
| 511 | if (chip->chip_type == MAX17042) | 510 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) |
| 512 | max17042_override_por(map, MAX17042_V_empty, config->vempty); | 511 | max17042_override_por(map, MAX17042_V_empty, config->vempty); |
| 513 | else | 512 | else |
| 514 | max17042_override_por(map, MAX17047_V_empty, config->vempty); | 513 | max17042_override_por(map, MAX17047_V_empty, config->vempty); |
| @@ -529,7 +528,6 @@ static int max17042_init_chip(struct max17042_chip *chip) | |||
| 529 | { | 528 | { |
| 530 | struct regmap *map = chip->regmap; | 529 | struct regmap *map = chip->regmap; |
| 531 | int ret; | 530 | int ret; |
| 532 | int val; | ||
| 533 | 531 | ||
| 534 | max17042_override_por_values(chip); | 532 | max17042_override_por_values(chip); |
| 535 | /* After Power up, the MAX17042 requires 500mS in order | 533 | /* After Power up, the MAX17042 requires 500mS in order |
| @@ -572,8 +570,7 @@ static int max17042_init_chip(struct max17042_chip *chip) | |||
| 572 | max17042_load_new_capacity_params(chip); | 570 | max17042_load_new_capacity_params(chip); |
| 573 | 571 | ||
| 574 | /* Init complete, Clear the POR bit */ | 572 | /* Init complete, Clear the POR bit */ |
| 575 | regmap_read(map, MAX17042_STATUS, &val); | 573 | regmap_update_bits(map, MAX17042_STATUS, STATUS_POR_BIT, 0x0); |
| 576 | regmap_write(map, MAX17042_STATUS, val & (~STATUS_POR_BIT)); | ||
| 577 | return 0; | 574 | return 0; |
| 578 | } | 575 | } |
| 579 | 576 | ||
| @@ -604,7 +601,7 @@ static irqreturn_t max17042_thread_handler(int id, void *dev) | |||
| 604 | max17042_set_soc_threshold(chip, 1); | 601 | max17042_set_soc_threshold(chip, 1); |
| 605 | } | 602 | } |
| 606 | 603 | ||
| 607 | power_supply_changed(&chip->battery); | 604 | power_supply_changed(chip->battery); |
| 608 | return IRQ_HANDLED; | 605 | return IRQ_HANDLED; |
| 609 | } | 606 | } |
| 610 | 607 | ||
| @@ -664,10 +661,28 @@ static const struct regmap_config max17042_regmap_config = { | |||
| 664 | .val_format_endian = REGMAP_ENDIAN_NATIVE, | 661 | .val_format_endian = REGMAP_ENDIAN_NATIVE, |
| 665 | }; | 662 | }; |
| 666 | 663 | ||
| 664 | static const struct power_supply_desc max17042_psy_desc = { | ||
| 665 | .name = "max170xx_battery", | ||
| 666 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 667 | .get_property = max17042_get_property, | ||
| 668 | .properties = max17042_battery_props, | ||
| 669 | .num_properties = ARRAY_SIZE(max17042_battery_props), | ||
| 670 | }; | ||
| 671 | |||
| 672 | static const struct power_supply_desc max17042_no_current_sense_psy_desc = { | ||
| 673 | .name = "max170xx_battery", | ||
| 674 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 675 | .get_property = max17042_get_property, | ||
| 676 | .properties = max17042_battery_props, | ||
| 677 | .num_properties = ARRAY_SIZE(max17042_battery_props) - 2, | ||
| 678 | }; | ||
| 679 | |||
| 667 | static int max17042_probe(struct i2c_client *client, | 680 | static int max17042_probe(struct i2c_client *client, |
| 668 | const struct i2c_device_id *id) | 681 | const struct i2c_device_id *id) |
| 669 | { | 682 | { |
| 670 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 683 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 684 | const struct power_supply_desc *max17042_desc = &max17042_psy_desc; | ||
| 685 | struct power_supply_config psy_cfg = {}; | ||
| 671 | struct max17042_chip *chip; | 686 | struct max17042_chip *chip; |
| 672 | int ret; | 687 | int ret; |
| 673 | int i; | 688 | int i; |
| @@ -694,29 +709,13 @@ static int max17042_probe(struct i2c_client *client, | |||
| 694 | } | 709 | } |
| 695 | 710 | ||
| 696 | i2c_set_clientdata(client, chip); | 711 | i2c_set_clientdata(client, chip); |
| 697 | 712 | chip->chip_type = id->driver_data; | |
| 698 | regmap_read(chip->regmap, MAX17042_DevName, &val); | 713 | psy_cfg.drv_data = chip; |
| 699 | if (val == MAX17042_IC_VERSION) { | ||
| 700 | dev_dbg(&client->dev, "chip type max17042 detected\n"); | ||
| 701 | chip->chip_type = MAX17042; | ||
| 702 | } else if (val == MAX17047_IC_VERSION) { | ||
| 703 | dev_dbg(&client->dev, "chip type max17047/50 detected\n"); | ||
| 704 | chip->chip_type = MAX17047; | ||
| 705 | } else { | ||
| 706 | dev_err(&client->dev, "device version mismatch: %x\n", val); | ||
| 707 | return -EIO; | ||
| 708 | } | ||
| 709 | |||
| 710 | chip->battery.name = "max170xx_battery"; | ||
| 711 | chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 712 | chip->battery.get_property = max17042_get_property; | ||
| 713 | chip->battery.properties = max17042_battery_props; | ||
| 714 | chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props); | ||
| 715 | 714 | ||
| 716 | /* When current is not measured, | 715 | /* When current is not measured, |
| 717 | * CURRENT_NOW and CURRENT_AVG properties should be invisible. */ | 716 | * CURRENT_NOW and CURRENT_AVG properties should be invisible. */ |
| 718 | if (!chip->pdata->enable_current_sense) | 717 | if (!chip->pdata->enable_current_sense) |
| 719 | chip->battery.num_properties -= 2; | 718 | max17042_desc = &max17042_no_current_sense_psy_desc; |
| 720 | 719 | ||
| 721 | if (chip->pdata->r_sns == 0) | 720 | if (chip->pdata->r_sns == 0) |
| 722 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; | 721 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; |
| @@ -733,21 +732,22 @@ static int max17042_probe(struct i2c_client *client, | |||
| 733 | regmap_write(chip->regmap, MAX17042_LearnCFG, 0x0007); | 732 | regmap_write(chip->regmap, MAX17042_LearnCFG, 0x0007); |
| 734 | } | 733 | } |
| 735 | 734 | ||
| 736 | ret = power_supply_register(&client->dev, &chip->battery); | 735 | chip->battery = power_supply_register(&client->dev, max17042_desc, |
| 737 | if (ret) { | 736 | &psy_cfg); |
| 737 | if (IS_ERR(chip->battery)) { | ||
| 738 | dev_err(&client->dev, "failed: power supply register\n"); | 738 | dev_err(&client->dev, "failed: power supply register\n"); |
| 739 | return ret; | 739 | return PTR_ERR(chip->battery); |
| 740 | } | 740 | } |
| 741 | 741 | ||
| 742 | if (client->irq) { | 742 | if (client->irq) { |
| 743 | ret = request_threaded_irq(client->irq, NULL, | 743 | ret = request_threaded_irq(client->irq, NULL, |
| 744 | max17042_thread_handler, | 744 | max17042_thread_handler, |
| 745 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 745 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
| 746 | chip->battery.name, chip); | 746 | chip->battery->desc->name, chip); |
| 747 | if (!ret) { | 747 | if (!ret) { |
| 748 | regmap_read(chip->regmap, MAX17042_CONFIG, &val); | 748 | regmap_update_bits(chip->regmap, MAX17042_CONFIG, |
| 749 | val |= CONFIG_ALRT_BIT_ENBL; | 749 | CONFIG_ALRT_BIT_ENBL, |
| 750 | regmap_write(chip->regmap, MAX17042_CONFIG, val); | 750 | CONFIG_ALRT_BIT_ENBL); |
| 751 | max17042_set_soc_threshold(chip, 1); | 751 | max17042_set_soc_threshold(chip, 1); |
| 752 | } else { | 752 | } else { |
| 753 | client->irq = 0; | 753 | client->irq = 0; |
| @@ -773,7 +773,7 @@ static int max17042_remove(struct i2c_client *client) | |||
| 773 | 773 | ||
| 774 | if (client->irq) | 774 | if (client->irq) |
| 775 | free_irq(client->irq, chip); | 775 | free_irq(client->irq, chip); |
| 776 | power_supply_unregister(&chip->battery); | 776 | power_supply_unregister(chip->battery); |
| 777 | return 0; | 777 | return 0; |
| 778 | } | 778 | } |
| 779 | 779 | ||
| @@ -823,9 +823,9 @@ MODULE_DEVICE_TABLE(of, max17042_dt_match); | |||
| 823 | #endif | 823 | #endif |
| 824 | 824 | ||
| 825 | static const struct i2c_device_id max17042_id[] = { | 825 | static const struct i2c_device_id max17042_id[] = { |
| 826 | { "max17042", 0 }, | 826 | { "max17042", MAXIM_DEVICE_TYPE_MAX17042 }, |
| 827 | { "max17047", 1 }, | 827 | { "max17047", MAXIM_DEVICE_TYPE_MAX17047 }, |
| 828 | { "max17050", 2 }, | 828 | { "max17050", MAXIM_DEVICE_TYPE_MAX17050 }, |
| 829 | { } | 829 | { } |
| 830 | }; | 830 | }; |
| 831 | MODULE_DEVICE_TABLE(i2c, max17042_id); | 831 | MODULE_DEVICE_TABLE(i2c, max17042_id); |
diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c index b042970fdeaf..754879eb59f6 100644 --- a/drivers/power/max77693_charger.c +++ b/drivers/power/max77693_charger.c | |||
| @@ -22,14 +22,14 @@ | |||
| 22 | #include <linux/mfd/max77693.h> | 22 | #include <linux/mfd/max77693.h> |
| 23 | #include <linux/mfd/max77693-private.h> | 23 | #include <linux/mfd/max77693-private.h> |
| 24 | 24 | ||
| 25 | static const char *max77693_charger_name = "max77693-charger"; | 25 | #define MAX77693_CHARGER_NAME "max77693-charger" |
| 26 | static const char *max77693_charger_model = "MAX77693"; | 26 | static const char *max77693_charger_model = "MAX77693"; |
| 27 | static const char *max77693_charger_manufacturer = "Maxim Integrated"; | 27 | static const char *max77693_charger_manufacturer = "Maxim Integrated"; |
| 28 | 28 | ||
| 29 | struct max77693_charger { | 29 | struct max77693_charger { |
| 30 | struct device *dev; | 30 | struct device *dev; |
| 31 | struct max77693_dev *max77693; | 31 | struct max77693_dev *max77693; |
| 32 | struct power_supply charger; | 32 | struct power_supply *charger; |
| 33 | 33 | ||
| 34 | u32 constant_volt; | 34 | u32 constant_volt; |
| 35 | u32 min_system_volt; | 35 | u32 min_system_volt; |
| @@ -38,13 +38,14 @@ struct max77693_charger { | |||
| 38 | u32 charge_input_threshold_volt; | 38 | u32 charge_input_threshold_volt; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static int max77693_get_charger_state(struct regmap *regmap) | 41 | static int max77693_get_charger_state(struct regmap *regmap, int *val) |
| 42 | { | 42 | { |
| 43 | int state; | 43 | int ret; |
| 44 | unsigned int data; | 44 | unsigned int data; |
| 45 | 45 | ||
| 46 | if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) | 46 | ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); |
| 47 | return POWER_SUPPLY_STATUS_UNKNOWN; | 47 | if (ret < 0) |
| 48 | return ret; | ||
| 48 | 49 | ||
| 49 | data &= CHG_DETAILS_01_CHG_MASK; | 50 | data &= CHG_DETAILS_01_CHG_MASK; |
| 50 | data >>= CHG_DETAILS_01_CHG_SHIFT; | 51 | data >>= CHG_DETAILS_01_CHG_SHIFT; |
| @@ -56,35 +57,36 @@ static int max77693_get_charger_state(struct regmap *regmap) | |||
| 56 | case MAX77693_CHARGING_TOP_OFF: | 57 | case MAX77693_CHARGING_TOP_OFF: |
| 57 | /* In high temp the charging current is reduced, but still charging */ | 58 | /* In high temp the charging current is reduced, but still charging */ |
| 58 | case MAX77693_CHARGING_HIGH_TEMP: | 59 | case MAX77693_CHARGING_HIGH_TEMP: |
| 59 | state = POWER_SUPPLY_STATUS_CHARGING; | 60 | *val = POWER_SUPPLY_STATUS_CHARGING; |
| 60 | break; | 61 | break; |
| 61 | case MAX77693_CHARGING_DONE: | 62 | case MAX77693_CHARGING_DONE: |
| 62 | state = POWER_SUPPLY_STATUS_FULL; | 63 | *val = POWER_SUPPLY_STATUS_FULL; |
| 63 | break; | 64 | break; |
| 64 | case MAX77693_CHARGING_TIMER_EXPIRED: | 65 | case MAX77693_CHARGING_TIMER_EXPIRED: |
| 65 | case MAX77693_CHARGING_THERMISTOR_SUSPEND: | 66 | case MAX77693_CHARGING_THERMISTOR_SUSPEND: |
| 66 | state = POWER_SUPPLY_STATUS_NOT_CHARGING; | 67 | *val = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| 67 | break; | 68 | break; |
| 68 | case MAX77693_CHARGING_OFF: | 69 | case MAX77693_CHARGING_OFF: |
| 69 | case MAX77693_CHARGING_OVER_TEMP: | 70 | case MAX77693_CHARGING_OVER_TEMP: |
| 70 | case MAX77693_CHARGING_WATCHDOG_EXPIRED: | 71 | case MAX77693_CHARGING_WATCHDOG_EXPIRED: |
| 71 | state = POWER_SUPPLY_STATUS_DISCHARGING; | 72 | *val = POWER_SUPPLY_STATUS_DISCHARGING; |
| 72 | break; | 73 | break; |
| 73 | case MAX77693_CHARGING_RESERVED: | 74 | case MAX77693_CHARGING_RESERVED: |
| 74 | default: | 75 | default: |
| 75 | state = POWER_SUPPLY_STATUS_UNKNOWN; | 76 | *val = POWER_SUPPLY_STATUS_UNKNOWN; |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | return state; | 79 | return 0; |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | static int max77693_get_charge_type(struct regmap *regmap) | 82 | static int max77693_get_charge_type(struct regmap *regmap, int *val) |
| 82 | { | 83 | { |
| 83 | int state; | 84 | int ret; |
| 84 | unsigned int data; | 85 | unsigned int data; |
| 85 | 86 | ||
| 86 | if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) | 87 | ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); |
| 87 | return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; | 88 | if (ret < 0) |
| 89 | return ret; | ||
| 88 | 90 | ||
| 89 | data &= CHG_DETAILS_01_CHG_MASK; | 91 | data &= CHG_DETAILS_01_CHG_MASK; |
| 90 | data >>= CHG_DETAILS_01_CHG_SHIFT; | 92 | data >>= CHG_DETAILS_01_CHG_SHIFT; |
| @@ -96,13 +98,13 @@ static int max77693_get_charge_type(struct regmap *regmap) | |||
| 96 | * 100 and 250 mA. It is higher than prequalification current. | 98 | * 100 and 250 mA. It is higher than prequalification current. |
| 97 | */ | 99 | */ |
| 98 | case MAX77693_CHARGING_TOP_OFF: | 100 | case MAX77693_CHARGING_TOP_OFF: |
| 99 | state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; | 101 | *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; |
| 100 | break; | 102 | break; |
| 101 | case MAX77693_CHARGING_FAST_CONST_CURRENT: | 103 | case MAX77693_CHARGING_FAST_CONST_CURRENT: |
| 102 | case MAX77693_CHARGING_FAST_CONST_VOLTAGE: | 104 | case MAX77693_CHARGING_FAST_CONST_VOLTAGE: |
| 103 | /* In high temp the charging current is reduced, but still charging */ | 105 | /* In high temp the charging current is reduced, but still charging */ |
| 104 | case MAX77693_CHARGING_HIGH_TEMP: | 106 | case MAX77693_CHARGING_HIGH_TEMP: |
| 105 | state = POWER_SUPPLY_CHARGE_TYPE_FAST; | 107 | *val = POWER_SUPPLY_CHARGE_TYPE_FAST; |
| 106 | break; | 108 | break; |
| 107 | case MAX77693_CHARGING_DONE: | 109 | case MAX77693_CHARGING_DONE: |
| 108 | case MAX77693_CHARGING_TIMER_EXPIRED: | 110 | case MAX77693_CHARGING_TIMER_EXPIRED: |
| @@ -110,14 +112,14 @@ static int max77693_get_charge_type(struct regmap *regmap) | |||
| 110 | case MAX77693_CHARGING_OFF: | 112 | case MAX77693_CHARGING_OFF: |
| 111 | case MAX77693_CHARGING_OVER_TEMP: | 113 | case MAX77693_CHARGING_OVER_TEMP: |
| 112 | case MAX77693_CHARGING_WATCHDOG_EXPIRED: | 114 | case MAX77693_CHARGING_WATCHDOG_EXPIRED: |
| 113 | state = POWER_SUPPLY_CHARGE_TYPE_NONE; | 115 | *val = POWER_SUPPLY_CHARGE_TYPE_NONE; |
| 114 | break; | 116 | break; |
| 115 | case MAX77693_CHARGING_RESERVED: | 117 | case MAX77693_CHARGING_RESERVED: |
| 116 | default: | 118 | default: |
| 117 | state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; | 119 | *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | return state; | 122 | return 0; |
| 121 | } | 123 | } |
| 122 | 124 | ||
| 123 | /* | 125 | /* |
| @@ -129,69 +131,78 @@ static int max77693_get_charge_type(struct regmap *regmap) | |||
| 129 | * - POWER_SUPPLY_HEALTH_UNKNOWN | 131 | * - POWER_SUPPLY_HEALTH_UNKNOWN |
| 130 | * - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE | 132 | * - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE |
| 131 | */ | 133 | */ |
| 132 | static int max77693_get_battery_health(struct regmap *regmap) | 134 | static int max77693_get_battery_health(struct regmap *regmap, int *val) |
| 133 | { | 135 | { |
| 134 | int state; | 136 | int ret; |
| 135 | unsigned int data; | 137 | unsigned int data; |
| 136 | 138 | ||
| 137 | if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) | 139 | ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); |
| 138 | return POWER_SUPPLY_HEALTH_UNKNOWN; | 140 | if (ret < 0) |
| 141 | return ret; | ||
| 139 | 142 | ||
| 140 | data &= CHG_DETAILS_01_BAT_MASK; | 143 | data &= CHG_DETAILS_01_BAT_MASK; |
| 141 | data >>= CHG_DETAILS_01_BAT_SHIFT; | 144 | data >>= CHG_DETAILS_01_BAT_SHIFT; |
| 142 | 145 | ||
| 143 | switch (data) { | 146 | switch (data) { |
| 144 | case MAX77693_BATTERY_NOBAT: | 147 | case MAX77693_BATTERY_NOBAT: |
| 145 | state = POWER_SUPPLY_HEALTH_DEAD; | 148 | *val = POWER_SUPPLY_HEALTH_DEAD; |
| 146 | break; | 149 | break; |
| 147 | case MAX77693_BATTERY_PREQUALIFICATION: | 150 | case MAX77693_BATTERY_PREQUALIFICATION: |
| 148 | case MAX77693_BATTERY_GOOD: | 151 | case MAX77693_BATTERY_GOOD: |
| 149 | case MAX77693_BATTERY_LOWVOLTAGE: | 152 | case MAX77693_BATTERY_LOWVOLTAGE: |
| 150 | state = POWER_SUPPLY_HEALTH_GOOD; | 153 | *val = POWER_SUPPLY_HEALTH_GOOD; |
| 151 | break; | 154 | break; |
| 152 | case MAX77693_BATTERY_TIMER_EXPIRED: | 155 | case MAX77693_BATTERY_TIMER_EXPIRED: |
| 153 | /* | 156 | /* |
| 154 | * Took longer to charge than expected, charging suspended. | 157 | * Took longer to charge than expected, charging suspended. |
| 155 | * Damaged battery? | 158 | * Damaged battery? |
| 156 | */ | 159 | */ |
| 157 | state = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; | 160 | *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; |
| 158 | break; | 161 | break; |
| 159 | case MAX77693_BATTERY_OVERVOLTAGE: | 162 | case MAX77693_BATTERY_OVERVOLTAGE: |
| 160 | state = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | 163 | *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; |
| 161 | break; | 164 | break; |
| 162 | case MAX77693_BATTERY_OVERCURRENT: | 165 | case MAX77693_BATTERY_OVERCURRENT: |
| 163 | state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; | 166 | *val = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; |
| 164 | break; | 167 | break; |
| 165 | case MAX77693_BATTERY_RESERVED: | 168 | case MAX77693_BATTERY_RESERVED: |
| 166 | default: | 169 | default: |
| 167 | state = POWER_SUPPLY_HEALTH_UNKNOWN; | 170 | *val = POWER_SUPPLY_HEALTH_UNKNOWN; |
| 168 | break; | 171 | break; |
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | return state; | 174 | return 0; |
| 172 | } | 175 | } |
| 173 | 176 | ||
| 174 | static int max77693_get_present(struct regmap *regmap) | 177 | static int max77693_get_present(struct regmap *regmap, int *val) |
| 175 | { | 178 | { |
| 176 | unsigned int data; | 179 | unsigned int data; |
| 180 | int ret; | ||
| 177 | 181 | ||
| 178 | /* | 182 | /* |
| 179 | * Read CHG_INT_OK register. High DETBAT bit here should be | 183 | * Read CHG_INT_OK register. High DETBAT bit here should be |
| 180 | * equal to value 0x0 in CHG_DETAILS_01/BAT field. | 184 | * equal to value 0x0 in CHG_DETAILS_01/BAT field. |
| 181 | */ | 185 | */ |
| 182 | regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); | 186 | ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); |
| 183 | if (data & CHG_INT_OK_DETBAT_MASK) | 187 | if (ret < 0) |
| 184 | return 0; | 188 | return ret; |
| 185 | return 1; | 189 | |
| 190 | *val = (data & CHG_INT_OK_DETBAT_MASK) ? 0 : 1; | ||
| 191 | |||
| 192 | return 0; | ||
| 186 | } | 193 | } |
| 187 | 194 | ||
| 188 | static int max77693_get_online(struct regmap *regmap) | 195 | static int max77693_get_online(struct regmap *regmap, int *val) |
| 189 | { | 196 | { |
| 190 | unsigned int data; | 197 | unsigned int data; |
| 198 | int ret; | ||
| 199 | |||
| 200 | ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); | ||
| 201 | if (ret < 0) | ||
| 202 | return ret; | ||
| 203 | |||
| 204 | *val = (data & CHG_INT_OK_CHGIN_MASK) ? 1 : 0; | ||
| 191 | 205 | ||
| 192 | regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); | ||
| 193 | if (data & CHG_INT_OK_CHGIN_MASK) | ||
| 194 | return 1; | ||
| 195 | return 0; | 206 | return 0; |
| 196 | } | 207 | } |
| 197 | 208 | ||
| @@ -209,27 +220,25 @@ static int max77693_charger_get_property(struct power_supply *psy, | |||
| 209 | enum power_supply_property psp, | 220 | enum power_supply_property psp, |
| 210 | union power_supply_propval *val) | 221 | union power_supply_propval *val) |
| 211 | { | 222 | { |
| 212 | struct max77693_charger *chg = container_of(psy, | 223 | struct max77693_charger *chg = power_supply_get_drvdata(psy); |
| 213 | struct max77693_charger, | ||
| 214 | charger); | ||
| 215 | struct regmap *regmap = chg->max77693->regmap; | 224 | struct regmap *regmap = chg->max77693->regmap; |
| 216 | int ret = 0; | 225 | int ret = 0; |
| 217 | 226 | ||
| 218 | switch (psp) { | 227 | switch (psp) { |
| 219 | case POWER_SUPPLY_PROP_STATUS: | 228 | case POWER_SUPPLY_PROP_STATUS: |
| 220 | val->intval = max77693_get_charger_state(regmap); | 229 | ret = max77693_get_charger_state(regmap, &val->intval); |
| 221 | break; | 230 | break; |
| 222 | case POWER_SUPPLY_PROP_CHARGE_TYPE: | 231 | case POWER_SUPPLY_PROP_CHARGE_TYPE: |
| 223 | val->intval = max77693_get_charge_type(regmap); | 232 | ret = max77693_get_charge_type(regmap, &val->intval); |
| 224 | break; | 233 | break; |
| 225 | case POWER_SUPPLY_PROP_HEALTH: | 234 | case POWER_SUPPLY_PROP_HEALTH: |
| 226 | val->intval = max77693_get_battery_health(regmap); | 235 | ret = max77693_get_battery_health(regmap, &val->intval); |
| 227 | break; | 236 | break; |
| 228 | case POWER_SUPPLY_PROP_PRESENT: | 237 | case POWER_SUPPLY_PROP_PRESENT: |
| 229 | val->intval = max77693_get_present(regmap); | 238 | ret = max77693_get_present(regmap, &val->intval); |
| 230 | break; | 239 | break; |
| 231 | case POWER_SUPPLY_PROP_ONLINE: | 240 | case POWER_SUPPLY_PROP_ONLINE: |
| 232 | val->intval = max77693_get_online(regmap); | 241 | ret = max77693_get_online(regmap, &val->intval); |
| 233 | break; | 242 | break; |
| 234 | case POWER_SUPPLY_PROP_MODEL_NAME: | 243 | case POWER_SUPPLY_PROP_MODEL_NAME: |
| 235 | val->strval = max77693_charger_model; | 244 | val->strval = max77693_charger_model; |
| @@ -244,6 +253,14 @@ static int max77693_charger_get_property(struct power_supply *psy, | |||
| 244 | return ret; | 253 | return ret; |
| 245 | } | 254 | } |
| 246 | 255 | ||
| 256 | static const struct power_supply_desc max77693_charger_desc = { | ||
| 257 | .name = MAX77693_CHARGER_NAME, | ||
| 258 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 259 | .properties = max77693_charger_props, | ||
| 260 | .num_properties = ARRAY_SIZE(max77693_charger_props), | ||
| 261 | .get_property = max77693_charger_get_property, | ||
| 262 | }; | ||
| 263 | |||
| 247 | static ssize_t device_attr_store(struct device *dev, | 264 | static ssize_t device_attr_store(struct device *dev, |
| 248 | struct device_attribute *attr, const char *buf, size_t count, | 265 | struct device_attribute *attr, const char *buf, size_t count, |
| 249 | int (*fn)(struct max77693_charger *, unsigned long)) | 266 | int (*fn)(struct max77693_charger *, unsigned long)) |
| @@ -659,6 +676,7 @@ static int max77693_dt_init(struct device *dev, struct max77693_charger *chg) | |||
| 659 | static int max77693_charger_probe(struct platform_device *pdev) | 676 | static int max77693_charger_probe(struct platform_device *pdev) |
| 660 | { | 677 | { |
| 661 | struct max77693_charger *chg; | 678 | struct max77693_charger *chg; |
| 679 | struct power_supply_config psy_cfg = {}; | ||
| 662 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); | 680 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); |
| 663 | int ret; | 681 | int ret; |
| 664 | 682 | ||
| @@ -678,11 +696,7 @@ static int max77693_charger_probe(struct platform_device *pdev) | |||
| 678 | if (ret) | 696 | if (ret) |
| 679 | return ret; | 697 | return ret; |
| 680 | 698 | ||
| 681 | chg->charger.name = max77693_charger_name; | 699 | psy_cfg.drv_data = chg; |
| 682 | chg->charger.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 683 | chg->charger.properties = max77693_charger_props; | ||
| 684 | chg->charger.num_properties = ARRAY_SIZE(max77693_charger_props); | ||
| 685 | chg->charger.get_property = max77693_charger_get_property; | ||
| 686 | 700 | ||
| 687 | ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); | 701 | ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); |
| 688 | if (ret) { | 702 | if (ret) { |
| @@ -703,9 +717,12 @@ static int max77693_charger_probe(struct platform_device *pdev) | |||
| 703 | goto err; | 717 | goto err; |
| 704 | } | 718 | } |
| 705 | 719 | ||
| 706 | ret = power_supply_register(&pdev->dev, &chg->charger); | 720 | chg->charger = power_supply_register(&pdev->dev, |
| 707 | if (ret) { | 721 | &max77693_charger_desc, |
| 722 | &psy_cfg); | ||
| 723 | if (IS_ERR(chg->charger)) { | ||
| 708 | dev_err(&pdev->dev, "failed: power supply register\n"); | 724 | dev_err(&pdev->dev, "failed: power supply register\n"); |
| 725 | ret = PTR_ERR(chg->charger); | ||
| 709 | goto err; | 726 | goto err; |
| 710 | } | 727 | } |
| 711 | 728 | ||
| @@ -727,7 +744,7 @@ static int max77693_charger_remove(struct platform_device *pdev) | |||
| 727 | device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current); | 744 | device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current); |
| 728 | device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); | 745 | device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer); |
| 729 | 746 | ||
| 730 | power_supply_unregister(&chg->charger); | 747 | power_supply_unregister(chg->charger); |
| 731 | 748 | ||
| 732 | return 0; | 749 | return 0; |
| 733 | } | 750 | } |
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c index 99e3cdcd3e11..bf2b4b3a7cae 100644 --- a/drivers/power/max8903_charger.c +++ b/drivers/power/max8903_charger.c | |||
| @@ -31,7 +31,8 @@ | |||
| 31 | struct max8903_data { | 31 | struct max8903_data { |
| 32 | struct max8903_pdata pdata; | 32 | struct max8903_pdata pdata; |
| 33 | struct device *dev; | 33 | struct device *dev; |
| 34 | struct power_supply psy; | 34 | struct power_supply *psy; |
| 35 | struct power_supply_desc psy_desc; | ||
| 35 | bool fault; | 36 | bool fault; |
| 36 | bool usb_in; | 37 | bool usb_in; |
| 37 | bool ta_in; | 38 | bool ta_in; |
| @@ -47,8 +48,7 @@ static int max8903_get_property(struct power_supply *psy, | |||
| 47 | enum power_supply_property psp, | 48 | enum power_supply_property psp, |
| 48 | union power_supply_propval *val) | 49 | union power_supply_propval *val) |
| 49 | { | 50 | { |
| 50 | struct max8903_data *data = container_of(psy, | 51 | struct max8903_data *data = power_supply_get_drvdata(psy); |
| 51 | struct max8903_data, psy); | ||
| 52 | 52 | ||
| 53 | switch (psp) { | 53 | switch (psp) { |
| 54 | case POWER_SUPPLY_PROP_STATUS: | 54 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -104,17 +104,17 @@ static irqreturn_t max8903_dcin(int irq, void *_data) | |||
| 104 | dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ? | 104 | dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ? |
| 105 | "Connected" : "Disconnected"); | 105 | "Connected" : "Disconnected"); |
| 106 | 106 | ||
| 107 | old_type = data->psy.type; | 107 | old_type = data->psy_desc.type; |
| 108 | 108 | ||
| 109 | if (data->ta_in) | 109 | if (data->ta_in) |
| 110 | data->psy.type = POWER_SUPPLY_TYPE_MAINS; | 110 | data->psy_desc.type = POWER_SUPPLY_TYPE_MAINS; |
| 111 | else if (data->usb_in) | 111 | else if (data->usb_in) |
| 112 | data->psy.type = POWER_SUPPLY_TYPE_USB; | 112 | data->psy_desc.type = POWER_SUPPLY_TYPE_USB; |
| 113 | else | 113 | else |
| 114 | data->psy.type = POWER_SUPPLY_TYPE_BATTERY; | 114 | data->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 115 | 115 | ||
| 116 | if (old_type != data->psy.type) | 116 | if (old_type != data->psy_desc.type) |
| 117 | power_supply_changed(&data->psy); | 117 | power_supply_changed(data->psy); |
| 118 | 118 | ||
| 119 | return IRQ_HANDLED; | 119 | return IRQ_HANDLED; |
| 120 | } | 120 | } |
| @@ -143,17 +143,17 @@ static irqreturn_t max8903_usbin(int irq, void *_data) | |||
| 143 | dev_dbg(data->dev, "USB Charger %s.\n", usb_in ? | 143 | dev_dbg(data->dev, "USB Charger %s.\n", usb_in ? |
| 144 | "Connected" : "Disconnected"); | 144 | "Connected" : "Disconnected"); |
| 145 | 145 | ||
| 146 | old_type = data->psy.type; | 146 | old_type = data->psy_desc.type; |
| 147 | 147 | ||
| 148 | if (data->ta_in) | 148 | if (data->ta_in) |
| 149 | data->psy.type = POWER_SUPPLY_TYPE_MAINS; | 149 | data->psy_desc.type = POWER_SUPPLY_TYPE_MAINS; |
| 150 | else if (data->usb_in) | 150 | else if (data->usb_in) |
| 151 | data->psy.type = POWER_SUPPLY_TYPE_USB; | 151 | data->psy_desc.type = POWER_SUPPLY_TYPE_USB; |
| 152 | else | 152 | else |
| 153 | data->psy.type = POWER_SUPPLY_TYPE_BATTERY; | 153 | data->psy_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 154 | 154 | ||
| 155 | if (old_type != data->psy.type) | 155 | if (old_type != data->psy_desc.type) |
| 156 | power_supply_changed(&data->psy); | 156 | power_supply_changed(data->psy); |
| 157 | 157 | ||
| 158 | return IRQ_HANDLED; | 158 | return IRQ_HANDLED; |
| 159 | } | 159 | } |
| @@ -184,6 +184,7 @@ static int max8903_probe(struct platform_device *pdev) | |||
| 184 | struct max8903_data *data; | 184 | struct max8903_data *data; |
| 185 | struct device *dev = &pdev->dev; | 185 | struct device *dev = &pdev->dev; |
| 186 | struct max8903_pdata *pdata = pdev->dev.platform_data; | 186 | struct max8903_pdata *pdata = pdev->dev.platform_data; |
| 187 | struct power_supply_config psy_cfg = {}; | ||
| 187 | int ret = 0; | 188 | int ret = 0; |
| 188 | int gpio; | 189 | int gpio; |
| 189 | int ta_in = 0; | 190 | int ta_in = 0; |
| @@ -280,17 +281,20 @@ static int max8903_probe(struct platform_device *pdev) | |||
| 280 | data->ta_in = ta_in; | 281 | data->ta_in = ta_in; |
| 281 | data->usb_in = usb_in; | 282 | data->usb_in = usb_in; |
| 282 | 283 | ||
| 283 | data->psy.name = "max8903_charger"; | 284 | data->psy_desc.name = "max8903_charger"; |
| 284 | data->psy.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : | 285 | data->psy_desc.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : |
| 285 | ((usb_in) ? POWER_SUPPLY_TYPE_USB : | 286 | ((usb_in) ? POWER_SUPPLY_TYPE_USB : |
| 286 | POWER_SUPPLY_TYPE_BATTERY); | 287 | POWER_SUPPLY_TYPE_BATTERY); |
| 287 | data->psy.get_property = max8903_get_property; | 288 | data->psy_desc.get_property = max8903_get_property; |
| 288 | data->psy.properties = max8903_charger_props; | 289 | data->psy_desc.properties = max8903_charger_props; |
| 289 | data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); | 290 | data->psy_desc.num_properties = ARRAY_SIZE(max8903_charger_props); |
| 290 | 291 | ||
| 291 | ret = power_supply_register(dev, &data->psy); | 292 | psy_cfg.drv_data = data; |
| 292 | if (ret) { | 293 | |
| 294 | data->psy = power_supply_register(dev, &data->psy_desc, &psy_cfg); | ||
| 295 | if (IS_ERR(data->psy)) { | ||
| 293 | dev_err(dev, "failed: power supply register.\n"); | 296 | dev_err(dev, "failed: power supply register.\n"); |
| 297 | ret = PTR_ERR(data->psy); | ||
| 294 | goto err; | 298 | goto err; |
| 295 | } | 299 | } |
| 296 | 300 | ||
| @@ -339,7 +343,7 @@ err_dc_irq: | |||
| 339 | if (pdata->dc_valid) | 343 | if (pdata->dc_valid) |
| 340 | free_irq(gpio_to_irq(pdata->dok), data); | 344 | free_irq(gpio_to_irq(pdata->dok), data); |
| 341 | err_psy: | 345 | err_psy: |
| 342 | power_supply_unregister(&data->psy); | 346 | power_supply_unregister(data->psy); |
| 343 | err: | 347 | err: |
| 344 | return ret; | 348 | return ret; |
| 345 | } | 349 | } |
| @@ -357,7 +361,7 @@ static int max8903_remove(struct platform_device *pdev) | |||
| 357 | free_irq(gpio_to_irq(pdata->uok), data); | 361 | free_irq(gpio_to_irq(pdata->uok), data); |
| 358 | if (pdata->dc_valid) | 362 | if (pdata->dc_valid) |
| 359 | free_irq(gpio_to_irq(pdata->dok), data); | 363 | free_irq(gpio_to_irq(pdata->dok), data); |
| 360 | power_supply_unregister(&data->psy); | 364 | power_supply_unregister(data->psy); |
| 361 | } | 365 | } |
| 362 | 366 | ||
| 363 | return 0; | 367 | return 0; |
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c index a6d45eef64dd..57eb5c2bfc21 100644 --- a/drivers/power/max8925_power.c +++ b/drivers/power/max8925_power.c | |||
| @@ -68,9 +68,9 @@ struct max8925_power_info { | |||
| 68 | struct i2c_client *gpm; | 68 | struct i2c_client *gpm; |
| 69 | struct i2c_client *adc; | 69 | struct i2c_client *adc; |
| 70 | 70 | ||
| 71 | struct power_supply ac; | 71 | struct power_supply *ac; |
| 72 | struct power_supply usb; | 72 | struct power_supply *usb; |
| 73 | struct power_supply battery; | 73 | struct power_supply *battery; |
| 74 | int irq_base; | 74 | int irq_base; |
| 75 | unsigned ac_online:1; | 75 | unsigned ac_online:1; |
| 76 | unsigned usb_online:1; | 76 | unsigned usb_online:1; |
| @@ -196,7 +196,7 @@ static int max8925_ac_get_prop(struct power_supply *psy, | |||
| 196 | enum power_supply_property psp, | 196 | enum power_supply_property psp, |
| 197 | union power_supply_propval *val) | 197 | union power_supply_propval *val) |
| 198 | { | 198 | { |
| 199 | struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); | 199 | struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent); |
| 200 | int ret = 0; | 200 | int ret = 0; |
| 201 | 201 | ||
| 202 | switch (psp) { | 202 | switch (psp) { |
| @@ -230,7 +230,7 @@ static int max8925_usb_get_prop(struct power_supply *psy, | |||
| 230 | enum power_supply_property psp, | 230 | enum power_supply_property psp, |
| 231 | union power_supply_propval *val) | 231 | union power_supply_propval *val) |
| 232 | { | 232 | { |
| 233 | struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); | 233 | struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent); |
| 234 | int ret = 0; | 234 | int ret = 0; |
| 235 | 235 | ||
| 236 | switch (psp) { | 236 | switch (psp) { |
| @@ -264,7 +264,7 @@ static int max8925_bat_get_prop(struct power_supply *psy, | |||
| 264 | enum power_supply_property psp, | 264 | enum power_supply_property psp, |
| 265 | union power_supply_propval *val) | 265 | union power_supply_propval *val) |
| 266 | { | 266 | { |
| 267 | struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent); | 267 | struct max8925_power_info *info = dev_get_drvdata(psy->dev.parent); |
| 268 | int ret = 0; | 268 | int ret = 0; |
| 269 | 269 | ||
| 270 | switch (psp) { | 270 | switch (psp) { |
| @@ -347,6 +347,30 @@ static enum power_supply_property max8925_battery_props[] = { | |||
| 347 | POWER_SUPPLY_PROP_STATUS, | 347 | POWER_SUPPLY_PROP_STATUS, |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static const struct power_supply_desc ac_desc = { | ||
| 351 | .name = "max8925-ac", | ||
| 352 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 353 | .properties = max8925_ac_props, | ||
| 354 | .num_properties = ARRAY_SIZE(max8925_ac_props), | ||
| 355 | .get_property = max8925_ac_get_prop, | ||
| 356 | }; | ||
| 357 | |||
| 358 | static const struct power_supply_desc usb_desc = { | ||
| 359 | .name = "max8925-usb", | ||
| 360 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 361 | .properties = max8925_usb_props, | ||
| 362 | .num_properties = ARRAY_SIZE(max8925_usb_props), | ||
| 363 | .get_property = max8925_usb_get_prop, | ||
| 364 | }; | ||
| 365 | |||
| 366 | static const struct power_supply_desc battery_desc = { | ||
| 367 | .name = "max8925-battery", | ||
| 368 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 369 | .properties = max8925_battery_props, | ||
| 370 | .num_properties = ARRAY_SIZE(max8925_battery_props), | ||
| 371 | .get_property = max8925_bat_get_prop, | ||
| 372 | }; | ||
| 373 | |||
| 350 | #define REQUEST_IRQ(_irq, _name) \ | 374 | #define REQUEST_IRQ(_irq, _name) \ |
| 351 | do { \ | 375 | do { \ |
| 352 | ret = request_threaded_irq(chip->irq_base + _irq, NULL, \ | 376 | ret = request_threaded_irq(chip->irq_base + _irq, NULL, \ |
| @@ -482,6 +506,7 @@ max8925_power_dt_init(struct platform_device *pdev) | |||
| 482 | static int max8925_power_probe(struct platform_device *pdev) | 506 | static int max8925_power_probe(struct platform_device *pdev) |
| 483 | { | 507 | { |
| 484 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | 508 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| 509 | struct power_supply_config psy_cfg = {}; /* Only for ac and usb */ | ||
| 485 | struct max8925_power_pdata *pdata = NULL; | 510 | struct max8925_power_pdata *pdata = NULL; |
| 486 | struct max8925_power_info *info; | 511 | struct max8925_power_info *info; |
| 487 | int ret; | 512 | int ret; |
| @@ -502,40 +527,29 @@ static int max8925_power_probe(struct platform_device *pdev) | |||
| 502 | info->adc = chip->adc; | 527 | info->adc = chip->adc; |
| 503 | platform_set_drvdata(pdev, info); | 528 | platform_set_drvdata(pdev, info); |
| 504 | 529 | ||
| 505 | info->ac.name = "max8925-ac"; | 530 | psy_cfg.supplied_to = pdata->supplied_to; |
| 506 | info->ac.type = POWER_SUPPLY_TYPE_MAINS; | 531 | psy_cfg.num_supplicants = pdata->num_supplicants; |
| 507 | info->ac.properties = max8925_ac_props; | 532 | |
| 508 | info->ac.num_properties = ARRAY_SIZE(max8925_ac_props); | 533 | info->ac = power_supply_register(&pdev->dev, &ac_desc, &psy_cfg); |
| 509 | info->ac.get_property = max8925_ac_get_prop; | 534 | if (IS_ERR(info->ac)) { |
| 510 | info->ac.supplied_to = pdata->supplied_to; | 535 | ret = PTR_ERR(info->ac); |
| 511 | info->ac.num_supplicants = pdata->num_supplicants; | ||
| 512 | ret = power_supply_register(&pdev->dev, &info->ac); | ||
| 513 | if (ret) | ||
| 514 | goto out; | 536 | goto out; |
| 515 | info->ac.dev->parent = &pdev->dev; | 537 | } |
| 516 | 538 | info->ac->dev.parent = &pdev->dev; | |
| 517 | info->usb.name = "max8925-usb"; | 539 | |
| 518 | info->usb.type = POWER_SUPPLY_TYPE_USB; | 540 | info->usb = power_supply_register(&pdev->dev, &usb_desc, &psy_cfg); |
| 519 | info->usb.properties = max8925_usb_props; | 541 | if (IS_ERR(info->usb)) { |
| 520 | info->usb.num_properties = ARRAY_SIZE(max8925_usb_props); | 542 | ret = PTR_ERR(info->usb); |
| 521 | info->usb.get_property = max8925_usb_get_prop; | ||
| 522 | info->usb.supplied_to = pdata->supplied_to; | ||
| 523 | info->usb.num_supplicants = pdata->num_supplicants; | ||
| 524 | |||
| 525 | ret = power_supply_register(&pdev->dev, &info->usb); | ||
| 526 | if (ret) | ||
| 527 | goto out_usb; | 543 | goto out_usb; |
| 528 | info->usb.dev->parent = &pdev->dev; | 544 | } |
| 529 | 545 | info->usb->dev.parent = &pdev->dev; | |
| 530 | info->battery.name = "max8925-battery"; | 546 | |
| 531 | info->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 547 | info->battery = power_supply_register(&pdev->dev, &battery_desc, NULL); |
| 532 | info->battery.properties = max8925_battery_props; | 548 | if (IS_ERR(info->battery)) { |
| 533 | info->battery.num_properties = ARRAY_SIZE(max8925_battery_props); | 549 | ret = PTR_ERR(info->battery); |
| 534 | info->battery.get_property = max8925_bat_get_prop; | ||
| 535 | ret = power_supply_register(&pdev->dev, &info->battery); | ||
| 536 | if (ret) | ||
| 537 | goto out_battery; | 550 | goto out_battery; |
| 538 | info->battery.dev->parent = &pdev->dev; | 551 | } |
| 552 | info->battery->dev.parent = &pdev->dev; | ||
| 539 | 553 | ||
| 540 | info->batt_detect = pdata->batt_detect; | 554 | info->batt_detect = pdata->batt_detect; |
| 541 | info->topoff_threshold = pdata->topoff_threshold; | 555 | info->topoff_threshold = pdata->topoff_threshold; |
| @@ -547,9 +561,9 @@ static int max8925_power_probe(struct platform_device *pdev) | |||
| 547 | max8925_init_charger(chip, info); | 561 | max8925_init_charger(chip, info); |
| 548 | return 0; | 562 | return 0; |
| 549 | out_battery: | 563 | out_battery: |
| 550 | power_supply_unregister(&info->battery); | 564 | power_supply_unregister(info->battery); |
| 551 | out_usb: | 565 | out_usb: |
| 552 | power_supply_unregister(&info->ac); | 566 | power_supply_unregister(info->ac); |
| 553 | out: | 567 | out: |
| 554 | return ret; | 568 | return ret; |
| 555 | } | 569 | } |
| @@ -559,9 +573,9 @@ static int max8925_power_remove(struct platform_device *pdev) | |||
| 559 | struct max8925_power_info *info = platform_get_drvdata(pdev); | 573 | struct max8925_power_info *info = platform_get_drvdata(pdev); |
| 560 | 574 | ||
| 561 | if (info) { | 575 | if (info) { |
| 562 | power_supply_unregister(&info->ac); | 576 | power_supply_unregister(info->ac); |
| 563 | power_supply_unregister(&info->usb); | 577 | power_supply_unregister(info->usb); |
| 564 | power_supply_unregister(&info->battery); | 578 | power_supply_unregister(info->battery); |
| 565 | max8925_deinit_charger(info); | 579 | max8925_deinit_charger(info); |
| 566 | } | 580 | } |
| 567 | return 0; | 581 | return 0; |
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c index aefa0c9a3007..0b2eab571528 100644 --- a/drivers/power/max8997_charger.c +++ b/drivers/power/max8997_charger.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | struct charger_data { | 30 | struct charger_data { |
| 31 | struct device *dev; | 31 | struct device *dev; |
| 32 | struct max8997_dev *iodev; | 32 | struct max8997_dev *iodev; |
| 33 | struct power_supply battery; | 33 | struct power_supply *battery; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static enum power_supply_property max8997_battery_props[] = { | 36 | static enum power_supply_property max8997_battery_props[] = { |
| @@ -44,8 +44,7 @@ static int max8997_battery_get_property(struct power_supply *psy, | |||
| 44 | enum power_supply_property psp, | 44 | enum power_supply_property psp, |
| 45 | union power_supply_propval *val) | 45 | union power_supply_propval *val) |
| 46 | { | 46 | { |
| 47 | struct charger_data *charger = container_of(psy, | 47 | struct charger_data *charger = power_supply_get_drvdata(psy); |
| 48 | struct charger_data, battery); | ||
| 49 | struct i2c_client *i2c = charger->iodev->i2c; | 48 | struct i2c_client *i2c = charger->iodev->i2c; |
| 50 | int ret; | 49 | int ret; |
| 51 | u8 reg; | 50 | u8 reg; |
| @@ -86,12 +85,21 @@ static int max8997_battery_get_property(struct power_supply *psy, | |||
| 86 | return 0; | 85 | return 0; |
| 87 | } | 86 | } |
| 88 | 87 | ||
| 88 | static const struct power_supply_desc max8997_battery_desc = { | ||
| 89 | .name = "max8997_pmic", | ||
| 90 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 91 | .get_property = max8997_battery_get_property, | ||
| 92 | .properties = max8997_battery_props, | ||
| 93 | .num_properties = ARRAY_SIZE(max8997_battery_props), | ||
| 94 | }; | ||
| 95 | |||
| 89 | static int max8997_battery_probe(struct platform_device *pdev) | 96 | static int max8997_battery_probe(struct platform_device *pdev) |
| 90 | { | 97 | { |
| 91 | int ret = 0; | 98 | int ret = 0; |
| 92 | struct charger_data *charger; | 99 | struct charger_data *charger; |
| 93 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 100 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 94 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | 101 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); |
| 102 | struct power_supply_config psy_cfg = {}; | ||
| 95 | 103 | ||
| 96 | if (!pdata) | 104 | if (!pdata) |
| 97 | return -EINVAL; | 105 | return -EINVAL; |
| @@ -147,19 +155,18 @@ static int max8997_battery_probe(struct platform_device *pdev) | |||
| 147 | 155 | ||
| 148 | platform_set_drvdata(pdev, charger); | 156 | platform_set_drvdata(pdev, charger); |
| 149 | 157 | ||
| 150 | charger->battery.name = "max8997_pmic"; | ||
| 151 | charger->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 152 | charger->battery.get_property = max8997_battery_get_property; | ||
| 153 | charger->battery.properties = max8997_battery_props; | ||
| 154 | charger->battery.num_properties = ARRAY_SIZE(max8997_battery_props); | ||
| 155 | 158 | ||
| 156 | charger->dev = &pdev->dev; | 159 | charger->dev = &pdev->dev; |
| 157 | charger->iodev = iodev; | 160 | charger->iodev = iodev; |
| 158 | 161 | ||
| 159 | ret = power_supply_register(&pdev->dev, &charger->battery); | 162 | psy_cfg.drv_data = charger; |
| 160 | if (ret) { | 163 | |
| 164 | charger->battery = power_supply_register(&pdev->dev, | ||
| 165 | &max8997_battery_desc, | ||
| 166 | &psy_cfg); | ||
| 167 | if (IS_ERR(charger->battery)) { | ||
| 161 | dev_err(&pdev->dev, "failed: power supply register\n"); | 168 | dev_err(&pdev->dev, "failed: power supply register\n"); |
| 162 | return ret; | 169 | return PTR_ERR(charger->battery); |
| 163 | } | 170 | } |
| 164 | 171 | ||
| 165 | return 0; | 172 | return 0; |
| @@ -169,7 +176,7 @@ static int max8997_battery_remove(struct platform_device *pdev) | |||
| 169 | { | 176 | { |
| 170 | struct charger_data *charger = platform_get_drvdata(pdev); | 177 | struct charger_data *charger = platform_get_drvdata(pdev); |
| 171 | 178 | ||
| 172 | power_supply_unregister(&charger->battery); | 179 | power_supply_unregister(charger->battery); |
| 173 | return 0; | 180 | return 0; |
| 174 | } | 181 | } |
| 175 | 182 | ||
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c index 08694c7a9f38..47448d4bc6cd 100644 --- a/drivers/power/max8998_charger.c +++ b/drivers/power/max8998_charger.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | struct max8998_battery_data { | 30 | struct max8998_battery_data { |
| 31 | struct device *dev; | 31 | struct device *dev; |
| 32 | struct max8998_dev *iodev; | 32 | struct max8998_dev *iodev; |
| 33 | struct power_supply battery; | 33 | struct power_supply *battery; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static enum power_supply_property max8998_battery_props[] = { | 36 | static enum power_supply_property max8998_battery_props[] = { |
| @@ -43,8 +43,7 @@ static int max8998_battery_get_property(struct power_supply *psy, | |||
| 43 | enum power_supply_property psp, | 43 | enum power_supply_property psp, |
| 44 | union power_supply_propval *val) | 44 | union power_supply_propval *val) |
| 45 | { | 45 | { |
| 46 | struct max8998_battery_data *max8998 = container_of(psy, | 46 | struct max8998_battery_data *max8998 = power_supply_get_drvdata(psy); |
| 47 | struct max8998_battery_data, battery); | ||
| 48 | struct i2c_client *i2c = max8998->iodev->i2c; | 47 | struct i2c_client *i2c = max8998->iodev->i2c; |
| 49 | int ret; | 48 | int ret; |
| 50 | u8 reg; | 49 | u8 reg; |
| @@ -75,10 +74,19 @@ static int max8998_battery_get_property(struct power_supply *psy, | |||
| 75 | return 0; | 74 | return 0; |
| 76 | } | 75 | } |
| 77 | 76 | ||
| 77 | static const struct power_supply_desc max8998_battery_desc = { | ||
| 78 | .name = "max8998_pmic", | ||
| 79 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 80 | .get_property = max8998_battery_get_property, | ||
| 81 | .properties = max8998_battery_props, | ||
| 82 | .num_properties = ARRAY_SIZE(max8998_battery_props), | ||
| 83 | }; | ||
| 84 | |||
| 78 | static int max8998_battery_probe(struct platform_device *pdev) | 85 | static int max8998_battery_probe(struct platform_device *pdev) |
| 79 | { | 86 | { |
| 80 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 87 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
| 81 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); | 88 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); |
| 89 | struct power_supply_config psy_cfg = {}; | ||
| 82 | struct max8998_battery_data *max8998; | 90 | struct max8998_battery_data *max8998; |
| 83 | struct i2c_client *i2c; | 91 | struct i2c_client *i2c; |
| 84 | int ret = 0; | 92 | int ret = 0; |
| @@ -161,15 +169,15 @@ static int max8998_battery_probe(struct platform_device *pdev) | |||
| 161 | goto err; | 169 | goto err; |
| 162 | } | 170 | } |
| 163 | 171 | ||
| 164 | max8998->battery.name = "max8998_pmic"; | 172 | psy_cfg.drv_data = max8998; |
| 165 | max8998->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
| 166 | max8998->battery.get_property = max8998_battery_get_property; | ||
| 167 | max8998->battery.properties = max8998_battery_props; | ||
| 168 | max8998->battery.num_properties = ARRAY_SIZE(max8998_battery_props); | ||
| 169 | 173 | ||
| 170 | ret = power_supply_register(max8998->dev, &max8998->battery); | 174 | max8998->battery = power_supply_register(max8998->dev, |
| 171 | if (ret) { | 175 | &max8998_battery_desc, |
| 172 | dev_err(max8998->dev, "failed: power supply register\n"); | 176 | &psy_cfg); |
| 177 | if (IS_ERR(max8998->battery)) { | ||
| 178 | ret = PTR_ERR(max8998->battery); | ||
| 179 | dev_err(max8998->dev, "failed: power supply register: %d\n", | ||
| 180 | ret); | ||
| 173 | goto err; | 181 | goto err; |
| 174 | } | 182 | } |
| 175 | 183 | ||
| @@ -182,7 +190,7 @@ static int max8998_battery_remove(struct platform_device *pdev) | |||
| 182 | { | 190 | { |
| 183 | struct max8998_battery_data *max8998 = platform_get_drvdata(pdev); | 191 | struct max8998_battery_data *max8998 = platform_get_drvdata(pdev); |
| 184 | 192 | ||
| 185 | power_supply_unregister(&max8998->battery); | 193 | power_supply_unregister(max8998->battery); |
| 186 | 194 | ||
| 187 | return 0; | 195 | return 0; |
| 188 | } | 196 | } |
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index ad9cde705de1..a944338a39de 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
| @@ -81,7 +81,7 @@ static enum power_supply_property olpc_ac_props[] = { | |||
| 81 | POWER_SUPPLY_PROP_ONLINE, | 81 | POWER_SUPPLY_PROP_ONLINE, |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | static struct power_supply olpc_ac = { | 84 | static const struct power_supply_desc olpc_ac_desc = { |
| 85 | .name = "olpc-ac", | 85 | .name = "olpc-ac", |
| 86 | .type = POWER_SUPPLY_TYPE_MAINS, | 86 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 87 | .properties = olpc_ac_props, | 87 | .properties = olpc_ac_props, |
| @@ -89,6 +89,8 @@ static struct power_supply olpc_ac = { | |||
| 89 | .get_property = olpc_ac_get_prop, | 89 | .get_property = olpc_ac_get_prop, |
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | static struct power_supply *olpc_ac; | ||
| 93 | |||
| 92 | static char bat_serial[17]; /* Ick */ | 94 | static char bat_serial[17]; /* Ick */ |
| 93 | 95 | ||
| 94 | static int olpc_bat_get_status(union power_supply_propval *val, uint8_t ec_byte) | 96 | static int olpc_bat_get_status(union power_supply_propval *val, uint8_t ec_byte) |
| @@ -574,21 +576,23 @@ static struct device_attribute olpc_bat_error = { | |||
| 574 | * Initialisation | 576 | * Initialisation |
| 575 | *********************************************************************/ | 577 | *********************************************************************/ |
| 576 | 578 | ||
| 577 | static struct power_supply olpc_bat = { | 579 | static struct power_supply_desc olpc_bat_desc = { |
| 578 | .name = "olpc-battery", | 580 | .name = "olpc-battery", |
| 579 | .get_property = olpc_bat_get_property, | 581 | .get_property = olpc_bat_get_property, |
| 580 | .use_for_apm = 1, | 582 | .use_for_apm = 1, |
| 581 | }; | 583 | }; |
| 582 | 584 | ||
| 585 | static struct power_supply *olpc_bat; | ||
| 586 | |||
| 583 | static int olpc_battery_suspend(struct platform_device *pdev, | 587 | static int olpc_battery_suspend(struct platform_device *pdev, |
| 584 | pm_message_t state) | 588 | pm_message_t state) |
| 585 | { | 589 | { |
| 586 | if (device_may_wakeup(olpc_ac.dev)) | 590 | if (device_may_wakeup(&olpc_ac->dev)) |
| 587 | olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR); | 591 | olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR); |
| 588 | else | 592 | else |
| 589 | olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR); | 593 | olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR); |
| 590 | 594 | ||
| 591 | if (device_may_wakeup(olpc_bat.dev)) | 595 | if (device_may_wakeup(&olpc_bat->dev)) |
| 592 | olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC | 596 | olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC |
| 593 | | EC_SCI_SRC_BATERR); | 597 | | EC_SCI_SRC_BATERR); |
| 594 | else | 598 | else |
| @@ -619,52 +623,54 @@ static int olpc_battery_probe(struct platform_device *pdev) | |||
| 619 | 623 | ||
| 620 | /* Ignore the status. It doesn't actually matter */ | 624 | /* Ignore the status. It doesn't actually matter */ |
| 621 | 625 | ||
| 622 | ret = power_supply_register(&pdev->dev, &olpc_ac); | 626 | olpc_ac = power_supply_register(&pdev->dev, &olpc_ac_desc, NULL); |
| 623 | if (ret) | 627 | if (IS_ERR(olpc_ac)) |
| 624 | return ret; | 628 | return PTR_ERR(olpc_ac); |
| 625 | 629 | ||
| 626 | if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ | 630 | if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ |
| 627 | olpc_bat.properties = olpc_xo15_bat_props; | 631 | olpc_bat_desc.properties = olpc_xo15_bat_props; |
| 628 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); | 632 | olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); |
| 629 | } else { /* XO-1 */ | 633 | } else { /* XO-1 */ |
| 630 | olpc_bat.properties = olpc_xo1_bat_props; | 634 | olpc_bat_desc.properties = olpc_xo1_bat_props; |
| 631 | olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); | 635 | olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); |
| 632 | } | 636 | } |
| 633 | 637 | ||
| 634 | ret = power_supply_register(&pdev->dev, &olpc_bat); | 638 | olpc_bat = power_supply_register(&pdev->dev, &olpc_bat_desc, NULL); |
| 635 | if (ret) | 639 | if (IS_ERR(olpc_bat)) { |
| 640 | ret = PTR_ERR(olpc_bat); | ||
| 636 | goto battery_failed; | 641 | goto battery_failed; |
| 642 | } | ||
| 637 | 643 | ||
| 638 | ret = device_create_bin_file(olpc_bat.dev, &olpc_bat_eeprom); | 644 | ret = device_create_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); |
| 639 | if (ret) | 645 | if (ret) |
| 640 | goto eeprom_failed; | 646 | goto eeprom_failed; |
| 641 | 647 | ||
| 642 | ret = device_create_file(olpc_bat.dev, &olpc_bat_error); | 648 | ret = device_create_file(&olpc_bat->dev, &olpc_bat_error); |
| 643 | if (ret) | 649 | if (ret) |
| 644 | goto error_failed; | 650 | goto error_failed; |
| 645 | 651 | ||
| 646 | if (olpc_ec_wakeup_available()) { | 652 | if (olpc_ec_wakeup_available()) { |
| 647 | device_set_wakeup_capable(olpc_ac.dev, true); | 653 | device_set_wakeup_capable(&olpc_ac->dev, true); |
| 648 | device_set_wakeup_capable(olpc_bat.dev, true); | 654 | device_set_wakeup_capable(&olpc_bat->dev, true); |
| 649 | } | 655 | } |
| 650 | 656 | ||
| 651 | return 0; | 657 | return 0; |
| 652 | 658 | ||
| 653 | error_failed: | 659 | error_failed: |
| 654 | device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); | 660 | device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); |
| 655 | eeprom_failed: | 661 | eeprom_failed: |
| 656 | power_supply_unregister(&olpc_bat); | 662 | power_supply_unregister(olpc_bat); |
| 657 | battery_failed: | 663 | battery_failed: |
| 658 | power_supply_unregister(&olpc_ac); | 664 | power_supply_unregister(olpc_ac); |
| 659 | return ret; | 665 | return ret; |
| 660 | } | 666 | } |
| 661 | 667 | ||
| 662 | static int olpc_battery_remove(struct platform_device *pdev) | 668 | static int olpc_battery_remove(struct platform_device *pdev) |
| 663 | { | 669 | { |
| 664 | device_remove_file(olpc_bat.dev, &olpc_bat_error); | 670 | device_remove_file(&olpc_bat->dev, &olpc_bat_error); |
| 665 | device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); | 671 | device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); |
| 666 | power_supply_unregister(&olpc_bat); | 672 | power_supply_unregister(olpc_bat); |
| 667 | power_supply_unregister(&olpc_ac); | 673 | power_supply_unregister(olpc_ac); |
| 668 | return 0; | 674 | return 0; |
| 669 | } | 675 | } |
| 670 | 676 | ||
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 771c4f0fb8ac..d05597b4e40f 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c | |||
| @@ -33,9 +33,9 @@ struct pcf50633_mbc { | |||
| 33 | int adapter_online; | 33 | int adapter_online; |
| 34 | int usb_online; | 34 | int usb_online; |
| 35 | 35 | ||
| 36 | struct power_supply usb; | 36 | struct power_supply *usb; |
| 37 | struct power_supply adapter; | 37 | struct power_supply *adapter; |
| 38 | struct power_supply ac; | 38 | struct power_supply *ac; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) | 41 | int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) |
| @@ -104,7 +104,7 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) | |||
| 104 | PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); | 104 | PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | power_supply_changed(&mbc->usb); | 107 | power_supply_changed(mbc->usb); |
| 108 | 108 | ||
| 109 | return ret; | 109 | return ret; |
| 110 | } | 110 | } |
| @@ -278,9 +278,9 @@ pcf50633_mbc_irq_handler(int irq, void *data) | |||
| 278 | else if (irq == PCF50633_IRQ_ADPREM) | 278 | else if (irq == PCF50633_IRQ_ADPREM) |
| 279 | mbc->adapter_online = 0; | 279 | mbc->adapter_online = 0; |
| 280 | 280 | ||
| 281 | power_supply_changed(&mbc->ac); | 281 | power_supply_changed(mbc->ac); |
| 282 | power_supply_changed(&mbc->usb); | 282 | power_supply_changed(mbc->usb); |
| 283 | power_supply_changed(&mbc->adapter); | 283 | power_supply_changed(mbc->adapter); |
| 284 | 284 | ||
| 285 | if (mbc->pcf->pdata->mbc_event_callback) | 285 | if (mbc->pcf->pdata->mbc_event_callback) |
| 286 | mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq); | 286 | mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq); |
| @@ -290,8 +290,7 @@ static int adapter_get_property(struct power_supply *psy, | |||
| 290 | enum power_supply_property psp, | 290 | enum power_supply_property psp, |
| 291 | union power_supply_propval *val) | 291 | union power_supply_propval *val) |
| 292 | { | 292 | { |
| 293 | struct pcf50633_mbc *mbc = container_of(psy, | 293 | struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy); |
| 294 | struct pcf50633_mbc, adapter); | ||
| 295 | int ret = 0; | 294 | int ret = 0; |
| 296 | 295 | ||
| 297 | switch (psp) { | 296 | switch (psp) { |
| @@ -309,7 +308,7 @@ static int usb_get_property(struct power_supply *psy, | |||
| 309 | enum power_supply_property psp, | 308 | enum power_supply_property psp, |
| 310 | union power_supply_propval *val) | 309 | union power_supply_propval *val) |
| 311 | { | 310 | { |
| 312 | struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); | 311 | struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy); |
| 313 | int ret = 0; | 312 | int ret = 0; |
| 314 | u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & | 313 | u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & |
| 315 | PCF50633_MBCC7_USB_MASK; | 314 | PCF50633_MBCC7_USB_MASK; |
| @@ -330,7 +329,7 @@ static int ac_get_property(struct power_supply *psy, | |||
| 330 | enum power_supply_property psp, | 329 | enum power_supply_property psp, |
| 331 | union power_supply_propval *val) | 330 | union power_supply_propval *val) |
| 332 | { | 331 | { |
| 333 | struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac); | 332 | struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy); |
| 334 | int ret = 0; | 333 | int ret = 0; |
| 335 | u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & | 334 | u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & |
| 336 | PCF50633_MBCC7_USB_MASK; | 335 | PCF50633_MBCC7_USB_MASK; |
| @@ -366,8 +365,33 @@ static const u8 mbc_irq_handlers[] = { | |||
| 366 | PCF50633_IRQ_LOWBAT, | 365 | PCF50633_IRQ_LOWBAT, |
| 367 | }; | 366 | }; |
| 368 | 367 | ||
| 368 | static const struct power_supply_desc pcf50633_mbc_adapter_desc = { | ||
| 369 | .name = "adapter", | ||
| 370 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 371 | .properties = power_props, | ||
| 372 | .num_properties = ARRAY_SIZE(power_props), | ||
| 373 | .get_property = &adapter_get_property, | ||
| 374 | }; | ||
| 375 | |||
| 376 | static const struct power_supply_desc pcf50633_mbc_usb_desc = { | ||
| 377 | .name = "usb", | ||
| 378 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 379 | .properties = power_props, | ||
| 380 | .num_properties = ARRAY_SIZE(power_props), | ||
| 381 | .get_property = usb_get_property, | ||
| 382 | }; | ||
| 383 | |||
| 384 | static const struct power_supply_desc pcf50633_mbc_ac_desc = { | ||
| 385 | .name = "ac", | ||
| 386 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 387 | .properties = power_props, | ||
| 388 | .num_properties = ARRAY_SIZE(power_props), | ||
| 389 | .get_property = ac_get_property, | ||
| 390 | }; | ||
| 391 | |||
| 369 | static int pcf50633_mbc_probe(struct platform_device *pdev) | 392 | static int pcf50633_mbc_probe(struct platform_device *pdev) |
| 370 | { | 393 | { |
| 394 | struct power_supply_config psy_cfg = {}; | ||
| 371 | struct pcf50633_mbc *mbc; | 395 | struct pcf50633_mbc *mbc; |
| 372 | int ret; | 396 | int ret; |
| 373 | int i; | 397 | int i; |
| @@ -385,49 +409,36 @@ static int pcf50633_mbc_probe(struct platform_device *pdev) | |||
| 385 | pcf50633_register_irq(mbc->pcf, mbc_irq_handlers[i], | 409 | pcf50633_register_irq(mbc->pcf, mbc_irq_handlers[i], |
| 386 | pcf50633_mbc_irq_handler, mbc); | 410 | pcf50633_mbc_irq_handler, mbc); |
| 387 | 411 | ||
| 412 | psy_cfg.supplied_to = mbc->pcf->pdata->batteries; | ||
| 413 | psy_cfg.num_supplicants = mbc->pcf->pdata->num_batteries; | ||
| 414 | psy_cfg.drv_data = mbc; | ||
| 415 | |||
| 388 | /* Create power supplies */ | 416 | /* Create power supplies */ |
| 389 | mbc->adapter.name = "adapter"; | 417 | mbc->adapter = power_supply_register(&pdev->dev, |
| 390 | mbc->adapter.type = POWER_SUPPLY_TYPE_MAINS; | 418 | &pcf50633_mbc_adapter_desc, |
| 391 | mbc->adapter.properties = power_props; | 419 | &psy_cfg); |
| 392 | mbc->adapter.num_properties = ARRAY_SIZE(power_props); | 420 | if (IS_ERR(mbc->adapter)) { |
| 393 | mbc->adapter.get_property = &adapter_get_property; | ||
| 394 | mbc->adapter.supplied_to = mbc->pcf->pdata->batteries; | ||
| 395 | mbc->adapter.num_supplicants = mbc->pcf->pdata->num_batteries; | ||
| 396 | |||
| 397 | mbc->usb.name = "usb"; | ||
| 398 | mbc->usb.type = POWER_SUPPLY_TYPE_USB; | ||
| 399 | mbc->usb.properties = power_props; | ||
| 400 | mbc->usb.num_properties = ARRAY_SIZE(power_props); | ||
| 401 | mbc->usb.get_property = usb_get_property; | ||
| 402 | mbc->usb.supplied_to = mbc->pcf->pdata->batteries; | ||
| 403 | mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries; | ||
| 404 | |||
| 405 | mbc->ac.name = "ac"; | ||
| 406 | mbc->ac.type = POWER_SUPPLY_TYPE_MAINS; | ||
| 407 | mbc->ac.properties = power_props; | ||
| 408 | mbc->ac.num_properties = ARRAY_SIZE(power_props); | ||
| 409 | mbc->ac.get_property = ac_get_property; | ||
| 410 | mbc->ac.supplied_to = mbc->pcf->pdata->batteries; | ||
| 411 | mbc->ac.num_supplicants = mbc->pcf->pdata->num_batteries; | ||
| 412 | |||
| 413 | ret = power_supply_register(&pdev->dev, &mbc->adapter); | ||
| 414 | if (ret) { | ||
| 415 | dev_err(mbc->pcf->dev, "failed to register adapter\n"); | 421 | dev_err(mbc->pcf->dev, "failed to register adapter\n"); |
| 422 | ret = PTR_ERR(mbc->adapter); | ||
| 416 | return ret; | 423 | return ret; |
| 417 | } | 424 | } |
| 418 | 425 | ||
| 419 | ret = power_supply_register(&pdev->dev, &mbc->usb); | 426 | mbc->usb = power_supply_register(&pdev->dev, &pcf50633_mbc_usb_desc, |
| 420 | if (ret) { | 427 | &psy_cfg); |
| 428 | if (IS_ERR(mbc->usb)) { | ||
| 421 | dev_err(mbc->pcf->dev, "failed to register usb\n"); | 429 | dev_err(mbc->pcf->dev, "failed to register usb\n"); |
| 422 | power_supply_unregister(&mbc->adapter); | 430 | power_supply_unregister(mbc->adapter); |
| 431 | ret = PTR_ERR(mbc->usb); | ||
| 423 | return ret; | 432 | return ret; |
| 424 | } | 433 | } |
| 425 | 434 | ||
| 426 | ret = power_supply_register(&pdev->dev, &mbc->ac); | 435 | mbc->ac = power_supply_register(&pdev->dev, &pcf50633_mbc_ac_desc, |
| 427 | if (ret) { | 436 | &psy_cfg); |
| 437 | if (IS_ERR(mbc->ac)) { | ||
| 428 | dev_err(mbc->pcf->dev, "failed to register ac\n"); | 438 | dev_err(mbc->pcf->dev, "failed to register ac\n"); |
| 429 | power_supply_unregister(&mbc->adapter); | 439 | power_supply_unregister(mbc->adapter); |
| 430 | power_supply_unregister(&mbc->usb); | 440 | power_supply_unregister(mbc->usb); |
| 441 | ret = PTR_ERR(mbc->ac); | ||
| 431 | return ret; | 442 | return ret; |
| 432 | } | 443 | } |
| 433 | 444 | ||
| @@ -454,9 +465,9 @@ static int pcf50633_mbc_remove(struct platform_device *pdev) | |||
| 454 | pcf50633_free_irq(mbc->pcf, mbc_irq_handlers[i]); | 465 | pcf50633_free_irq(mbc->pcf, mbc_irq_handlers[i]); |
| 455 | 466 | ||
| 456 | sysfs_remove_group(&pdev->dev.kobj, &mbc_attr_group); | 467 | sysfs_remove_group(&pdev->dev.kobj, &mbc_attr_group); |
| 457 | power_supply_unregister(&mbc->usb); | 468 | power_supply_unregister(mbc->usb); |
| 458 | power_supply_unregister(&mbc->adapter); | 469 | power_supply_unregister(mbc->adapter); |
| 459 | power_supply_unregister(&mbc->ac); | 470 | power_supply_unregister(mbc->ac); |
| 460 | 471 | ||
| 461 | return 0; | 472 | return 0; |
| 462 | } | 473 | } |
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 0c52e2a0d90c..dfe1ee89f7c7 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c | |||
| @@ -34,6 +34,7 @@ static struct timer_list charger_timer; | |||
| 34 | static struct timer_list supply_timer; | 34 | static struct timer_list supply_timer; |
| 35 | static struct timer_list polling_timer; | 35 | static struct timer_list polling_timer; |
| 36 | static int polling; | 36 | static int polling; |
| 37 | static struct power_supply *pda_psy_ac, *pda_psy_usb; | ||
| 37 | 38 | ||
| 38 | #if IS_ENABLED(CONFIG_USB_PHY) | 39 | #if IS_ENABLED(CONFIG_USB_PHY) |
| 39 | static struct usb_phy *transceiver; | 40 | static struct usb_phy *transceiver; |
| @@ -58,7 +59,7 @@ static int pda_power_get_property(struct power_supply *psy, | |||
| 58 | { | 59 | { |
| 59 | switch (psp) { | 60 | switch (psp) { |
| 60 | case POWER_SUPPLY_PROP_ONLINE: | 61 | case POWER_SUPPLY_PROP_ONLINE: |
| 61 | if (psy->type == POWER_SUPPLY_TYPE_MAINS) | 62 | if (psy->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 62 | val->intval = pdata->is_ac_online ? | 63 | val->intval = pdata->is_ac_online ? |
| 63 | pdata->is_ac_online() : 0; | 64 | pdata->is_ac_online() : 0; |
| 64 | else | 65 | else |
| @@ -80,21 +81,17 @@ static char *pda_power_supplied_to[] = { | |||
| 80 | "backup-battery", | 81 | "backup-battery", |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | static struct power_supply pda_psy_ac = { | 84 | static const struct power_supply_desc pda_psy_ac_desc = { |
| 84 | .name = "ac", | 85 | .name = "ac", |
| 85 | .type = POWER_SUPPLY_TYPE_MAINS, | 86 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 86 | .supplied_to = pda_power_supplied_to, | ||
| 87 | .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), | ||
| 88 | .properties = pda_power_props, | 87 | .properties = pda_power_props, |
| 89 | .num_properties = ARRAY_SIZE(pda_power_props), | 88 | .num_properties = ARRAY_SIZE(pda_power_props), |
| 90 | .get_property = pda_power_get_property, | 89 | .get_property = pda_power_get_property, |
| 91 | }; | 90 | }; |
| 92 | 91 | ||
| 93 | static struct power_supply pda_psy_usb = { | 92 | static const struct power_supply_desc pda_psy_usb_desc = { |
| 94 | .name = "usb", | 93 | .name = "usb", |
| 95 | .type = POWER_SUPPLY_TYPE_USB, | 94 | .type = POWER_SUPPLY_TYPE_USB, |
| 96 | .supplied_to = pda_power_supplied_to, | ||
| 97 | .num_supplicants = ARRAY_SIZE(pda_power_supplied_to), | ||
| 98 | .properties = pda_power_props, | 95 | .properties = pda_power_props, |
| 99 | .num_properties = ARRAY_SIZE(pda_power_props), | 96 | .num_properties = ARRAY_SIZE(pda_power_props), |
| 100 | .get_property = pda_power_get_property, | 97 | .get_property = pda_power_get_property, |
| @@ -147,12 +144,12 @@ static void supply_timer_func(unsigned long unused) | |||
| 147 | { | 144 | { |
| 148 | if (ac_status == PDA_PSY_TO_CHANGE) { | 145 | if (ac_status == PDA_PSY_TO_CHANGE) { |
| 149 | ac_status = new_ac_status; | 146 | ac_status = new_ac_status; |
| 150 | power_supply_changed(&pda_psy_ac); | 147 | power_supply_changed(pda_psy_ac); |
| 151 | } | 148 | } |
| 152 | 149 | ||
| 153 | if (usb_status == PDA_PSY_TO_CHANGE) { | 150 | if (usb_status == PDA_PSY_TO_CHANGE) { |
| 154 | usb_status = new_usb_status; | 151 | usb_status = new_usb_status; |
| 155 | power_supply_changed(&pda_psy_usb); | 152 | power_supply_changed(pda_psy_usb); |
| 156 | } | 153 | } |
| 157 | } | 154 | } |
| 158 | 155 | ||
| @@ -176,9 +173,9 @@ static void charger_timer_func(unsigned long unused) | |||
| 176 | 173 | ||
| 177 | static irqreturn_t power_changed_isr(int irq, void *power_supply) | 174 | static irqreturn_t power_changed_isr(int irq, void *power_supply) |
| 178 | { | 175 | { |
| 179 | if (power_supply == &pda_psy_ac) | 176 | if (power_supply == pda_psy_ac) |
| 180 | ac_status = PDA_PSY_TO_CHANGE; | 177 | ac_status = PDA_PSY_TO_CHANGE; |
| 181 | else if (power_supply == &pda_psy_usb) | 178 | else if (power_supply == pda_psy_usb) |
| 182 | usb_status = PDA_PSY_TO_CHANGE; | 179 | usb_status = PDA_PSY_TO_CHANGE; |
| 183 | else | 180 | else |
| 184 | return IRQ_NONE; | 181 | return IRQ_NONE; |
| @@ -262,6 +259,7 @@ static int otg_handle_notification(struct notifier_block *nb, | |||
| 262 | 259 | ||
| 263 | static int pda_power_probe(struct platform_device *pdev) | 260 | static int pda_power_probe(struct platform_device *pdev) |
| 264 | { | 261 | { |
| 262 | struct power_supply_config psy_cfg = {}; | ||
| 265 | int ret = 0; | 263 | int ret = 0; |
| 266 | 264 | ||
| 267 | dev = &pdev->dev; | 265 | dev = &pdev->dev; |
| @@ -309,10 +307,11 @@ static int pda_power_probe(struct platform_device *pdev) | |||
| 309 | usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); | 307 | usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); |
| 310 | 308 | ||
| 311 | if (pdata->supplied_to) { | 309 | if (pdata->supplied_to) { |
| 312 | pda_psy_ac.supplied_to = pdata->supplied_to; | 310 | psy_cfg.supplied_to = pdata->supplied_to; |
| 313 | pda_psy_ac.num_supplicants = pdata->num_supplicants; | 311 | psy_cfg.num_supplicants = pdata->num_supplicants; |
| 314 | pda_psy_usb.supplied_to = pdata->supplied_to; | 312 | } else { |
| 315 | pda_psy_usb.num_supplicants = pdata->num_supplicants; | 313 | psy_cfg.supplied_to = pda_power_supplied_to; |
| 314 | psy_cfg.num_supplicants = ARRAY_SIZE(pda_power_supplied_to); | ||
| 316 | } | 315 | } |
| 317 | 316 | ||
| 318 | #if IS_ENABLED(CONFIG_USB_PHY) | 317 | #if IS_ENABLED(CONFIG_USB_PHY) |
| @@ -326,17 +325,19 @@ static int pda_power_probe(struct platform_device *pdev) | |||
| 326 | #endif | 325 | #endif |
| 327 | 326 | ||
| 328 | if (pdata->is_ac_online) { | 327 | if (pdata->is_ac_online) { |
| 329 | ret = power_supply_register(&pdev->dev, &pda_psy_ac); | 328 | pda_psy_ac = power_supply_register(&pdev->dev, |
| 330 | if (ret) { | 329 | &pda_psy_ac_desc, &psy_cfg); |
| 330 | if (IS_ERR(pda_psy_ac)) { | ||
| 331 | dev_err(dev, "failed to register %s power supply\n", | 331 | dev_err(dev, "failed to register %s power supply\n", |
| 332 | pda_psy_ac.name); | 332 | pda_psy_ac_desc.name); |
| 333 | ret = PTR_ERR(pda_psy_ac); | ||
| 333 | goto ac_supply_failed; | 334 | goto ac_supply_failed; |
| 334 | } | 335 | } |
| 335 | 336 | ||
| 336 | if (ac_irq) { | 337 | if (ac_irq) { |
| 337 | ret = request_irq(ac_irq->start, power_changed_isr, | 338 | ret = request_irq(ac_irq->start, power_changed_isr, |
| 338 | get_irq_flags(ac_irq), ac_irq->name, | 339 | get_irq_flags(ac_irq), ac_irq->name, |
| 339 | &pda_psy_ac); | 340 | pda_psy_ac); |
| 340 | if (ret) { | 341 | if (ret) { |
| 341 | dev_err(dev, "request ac irq failed\n"); | 342 | dev_err(dev, "request ac irq failed\n"); |
| 342 | goto ac_irq_failed; | 343 | goto ac_irq_failed; |
| @@ -347,17 +348,20 @@ static int pda_power_probe(struct platform_device *pdev) | |||
| 347 | } | 348 | } |
| 348 | 349 | ||
| 349 | if (pdata->is_usb_online) { | 350 | if (pdata->is_usb_online) { |
| 350 | ret = power_supply_register(&pdev->dev, &pda_psy_usb); | 351 | pda_psy_usb = power_supply_register(&pdev->dev, |
| 351 | if (ret) { | 352 | &pda_psy_usb_desc, |
| 353 | &psy_cfg); | ||
| 354 | if (IS_ERR(pda_psy_usb)) { | ||
| 352 | dev_err(dev, "failed to register %s power supply\n", | 355 | dev_err(dev, "failed to register %s power supply\n", |
| 353 | pda_psy_usb.name); | 356 | pda_psy_usb_desc.name); |
| 357 | ret = PTR_ERR(pda_psy_usb); | ||
| 354 | goto usb_supply_failed; | 358 | goto usb_supply_failed; |
| 355 | } | 359 | } |
| 356 | 360 | ||
| 357 | if (usb_irq) { | 361 | if (usb_irq) { |
| 358 | ret = request_irq(usb_irq->start, power_changed_isr, | 362 | ret = request_irq(usb_irq->start, power_changed_isr, |
| 359 | get_irq_flags(usb_irq), | 363 | get_irq_flags(usb_irq), |
| 360 | usb_irq->name, &pda_psy_usb); | 364 | usb_irq->name, pda_psy_usb); |
| 361 | if (ret) { | 365 | if (ret) { |
| 362 | dev_err(dev, "request usb irq failed\n"); | 366 | dev_err(dev, "request usb irq failed\n"); |
| 363 | goto usb_irq_failed; | 367 | goto usb_irq_failed; |
| @@ -394,21 +398,21 @@ static int pda_power_probe(struct platform_device *pdev) | |||
| 394 | #if IS_ENABLED(CONFIG_USB_PHY) | 398 | #if IS_ENABLED(CONFIG_USB_PHY) |
| 395 | otg_reg_notifier_failed: | 399 | otg_reg_notifier_failed: |
| 396 | if (pdata->is_usb_online && usb_irq) | 400 | if (pdata->is_usb_online && usb_irq) |
| 397 | free_irq(usb_irq->start, &pda_psy_usb); | 401 | free_irq(usb_irq->start, pda_psy_usb); |
| 398 | #endif | 402 | #endif |
| 399 | usb_irq_failed: | 403 | usb_irq_failed: |
| 400 | if (pdata->is_usb_online) | 404 | if (pdata->is_usb_online) |
| 401 | power_supply_unregister(&pda_psy_usb); | 405 | power_supply_unregister(pda_psy_usb); |
| 402 | usb_supply_failed: | 406 | usb_supply_failed: |
| 403 | if (pdata->is_ac_online && ac_irq) | 407 | if (pdata->is_ac_online && ac_irq) |
| 404 | free_irq(ac_irq->start, &pda_psy_ac); | 408 | free_irq(ac_irq->start, pda_psy_ac); |
| 405 | #if IS_ENABLED(CONFIG_USB_PHY) | 409 | #if IS_ENABLED(CONFIG_USB_PHY) |
| 406 | if (!IS_ERR_OR_NULL(transceiver)) | 410 | if (!IS_ERR_OR_NULL(transceiver)) |
| 407 | usb_put_phy(transceiver); | 411 | usb_put_phy(transceiver); |
| 408 | #endif | 412 | #endif |
| 409 | ac_irq_failed: | 413 | ac_irq_failed: |
| 410 | if (pdata->is_ac_online) | 414 | if (pdata->is_ac_online) |
| 411 | power_supply_unregister(&pda_psy_ac); | 415 | power_supply_unregister(pda_psy_ac); |
| 412 | ac_supply_failed: | 416 | ac_supply_failed: |
| 413 | if (ac_draw) { | 417 | if (ac_draw) { |
| 414 | regulator_put(ac_draw); | 418 | regulator_put(ac_draw); |
| @@ -424,9 +428,9 @@ wrongid: | |||
| 424 | static int pda_power_remove(struct platform_device *pdev) | 428 | static int pda_power_remove(struct platform_device *pdev) |
| 425 | { | 429 | { |
| 426 | if (pdata->is_usb_online && usb_irq) | 430 | if (pdata->is_usb_online && usb_irq) |
| 427 | free_irq(usb_irq->start, &pda_psy_usb); | 431 | free_irq(usb_irq->start, pda_psy_usb); |
| 428 | if (pdata->is_ac_online && ac_irq) | 432 | if (pdata->is_ac_online && ac_irq) |
| 429 | free_irq(ac_irq->start, &pda_psy_ac); | 433 | free_irq(ac_irq->start, pda_psy_ac); |
| 430 | 434 | ||
| 431 | if (polling) | 435 | if (polling) |
| 432 | del_timer_sync(&polling_timer); | 436 | del_timer_sync(&polling_timer); |
| @@ -434,9 +438,9 @@ static int pda_power_remove(struct platform_device *pdev) | |||
| 434 | del_timer_sync(&supply_timer); | 438 | del_timer_sync(&supply_timer); |
| 435 | 439 | ||
| 436 | if (pdata->is_usb_online) | 440 | if (pdata->is_usb_online) |
| 437 | power_supply_unregister(&pda_psy_usb); | 441 | power_supply_unregister(pda_psy_usb); |
| 438 | if (pdata->is_ac_online) | 442 | if (pdata->is_ac_online) |
| 439 | power_supply_unregister(&pda_psy_ac); | 443 | power_supply_unregister(pda_psy_ac); |
| 440 | #if IS_ENABLED(CONFIG_USB_PHY) | 444 | #if IS_ENABLED(CONFIG_USB_PHY) |
| 441 | if (!IS_ERR_OR_NULL(transceiver)) | 445 | if (!IS_ERR_OR_NULL(transceiver)) |
| 442 | usb_put_phy(transceiver); | 446 | usb_put_phy(transceiver); |
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 777324992c59..cc0893ffbf7e 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
| @@ -216,7 +216,7 @@ static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) | |||
| 216 | { | 216 | { |
| 217 | dev_err(pm2->dev, "Overvoltage detected\n"); | 217 | dev_err(pm2->dev, "Overvoltage detected\n"); |
| 218 | pm2->flags.ovv = true; | 218 | pm2->flags.ovv = true; |
| 219 | power_supply_changed(&pm2->ac_chg.psy); | 219 | power_supply_changed(pm2->ac_chg.psy); |
| 220 | 220 | ||
| 221 | /* Schedule a new HW failure check */ | 221 | /* Schedule a new HW failure check */ |
| 222 | queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0); | 222 | queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0); |
| @@ -229,7 +229,7 @@ static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) | |||
| 229 | dev_dbg(pm2->dev , "20 minutes watchdog expired\n"); | 229 | dev_dbg(pm2->dev , "20 minutes watchdog expired\n"); |
| 230 | 230 | ||
| 231 | pm2->ac.wd_expired = true; | 231 | pm2->ac.wd_expired = true; |
| 232 | power_supply_changed(&pm2->ac_chg.psy); | 232 | power_supply_changed(pm2->ac_chg.psy); |
| 233 | 233 | ||
| 234 | return 0; | 234 | return 0; |
| 235 | } | 235 | } |
| @@ -573,7 +573,7 @@ static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger, | |||
| 573 | struct pm2xxx_charger *pm2; | 573 | struct pm2xxx_charger *pm2; |
| 574 | u8 val; | 574 | u8 val; |
| 575 | 575 | ||
| 576 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | 576 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 577 | pm2 = to_pm2xxx_charger_ac_device_info(charger); | 577 | pm2 = to_pm2xxx_charger_ac_device_info(charger); |
| 578 | else | 578 | else |
| 579 | return -ENXIO; | 579 | return -ENXIO; |
| @@ -816,7 +816,7 @@ static int pm2xxx_charger_ac_en(struct ux500_charger *charger, | |||
| 816 | 816 | ||
| 817 | dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n"); | 817 | dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n"); |
| 818 | } | 818 | } |
| 819 | power_supply_changed(&pm2->ac_chg.psy); | 819 | power_supply_changed(pm2->ac_chg.psy); |
| 820 | 820 | ||
| 821 | error_occured: | 821 | error_occured: |
| 822 | return ret; | 822 | return ret; |
| @@ -827,7 +827,7 @@ static int pm2xxx_charger_watchdog_kick(struct ux500_charger *charger) | |||
| 827 | int ret; | 827 | int ret; |
| 828 | struct pm2xxx_charger *pm2; | 828 | struct pm2xxx_charger *pm2; |
| 829 | 829 | ||
| 830 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | 830 | if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) |
| 831 | pm2 = to_pm2xxx_charger_ac_device_info(charger); | 831 | pm2 = to_pm2xxx_charger_ac_device_info(charger); |
| 832 | else | 832 | else |
| 833 | return -ENXIO; | 833 | return -ENXIO; |
| @@ -845,8 +845,8 @@ static void pm2xxx_charger_ac_work(struct work_struct *work) | |||
| 845 | struct pm2xxx_charger, ac_work); | 845 | struct pm2xxx_charger, ac_work); |
| 846 | 846 | ||
| 847 | 847 | ||
| 848 | power_supply_changed(&pm2->ac_chg.psy); | 848 | power_supply_changed(pm2->ac_chg.psy); |
| 849 | sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); | 849 | sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present"); |
| 850 | }; | 850 | }; |
| 851 | 851 | ||
| 852 | static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) | 852 | static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) |
| @@ -862,7 +862,7 @@ static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) | |||
| 862 | if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV | | 862 | if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV | |
| 863 | PM2XXX_INT4_S_ITVPWR2OVV))) { | 863 | PM2XXX_INT4_S_ITVPWR2OVV))) { |
| 864 | pm2->flags.ovv = false; | 864 | pm2->flags.ovv = false; |
| 865 | power_supply_changed(&pm2->ac_chg.psy); | 865 | power_supply_changed(pm2->ac_chg.psy); |
| 866 | } | 866 | } |
| 867 | } | 867 | } |
| 868 | 868 | ||
| @@ -895,7 +895,7 @@ static void pm2xxx_charger_check_main_thermal_prot_work( | |||
| 895 | | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL)) | 895 | | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL)) |
| 896 | pm2->flags.main_thermal_prot = false; | 896 | pm2->flags.main_thermal_prot = false; |
| 897 | 897 | ||
| 898 | power_supply_changed(&pm2->ac_chg.psy); | 898 | power_supply_changed(pm2->ac_chg.psy); |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | static struct pm2xxx_interrupts pm2xxx_int = { | 901 | static struct pm2xxx_interrupts pm2xxx_int = { |
| @@ -989,6 +989,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
| 989 | const struct i2c_device_id *id) | 989 | const struct i2c_device_id *id) |
| 990 | { | 990 | { |
| 991 | struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; | 991 | struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; |
| 992 | struct power_supply_config psy_cfg = {}; | ||
| 992 | struct pm2xxx_charger *pm2; | 993 | struct pm2xxx_charger *pm2; |
| 993 | int ret = 0; | 994 | int ret = 0; |
| 994 | u8 val; | 995 | u8 val; |
| @@ -1042,13 +1043,14 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
| 1042 | 1043 | ||
| 1043 | /* AC supply */ | 1044 | /* AC supply */ |
| 1044 | /* power_supply base class */ | 1045 | /* power_supply base class */ |
| 1045 | pm2->ac_chg.psy.name = pm2->pdata->label; | 1046 | pm2->ac_chg_desc.name = pm2->pdata->label; |
| 1046 | pm2->ac_chg.psy.type = POWER_SUPPLY_TYPE_MAINS; | 1047 | pm2->ac_chg_desc.type = POWER_SUPPLY_TYPE_MAINS; |
| 1047 | pm2->ac_chg.psy.properties = pm2xxx_charger_ac_props; | 1048 | pm2->ac_chg_desc.properties = pm2xxx_charger_ac_props; |
| 1048 | pm2->ac_chg.psy.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props); | 1049 | pm2->ac_chg_desc.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props); |
| 1049 | pm2->ac_chg.psy.get_property = pm2xxx_charger_ac_get_property; | 1050 | pm2->ac_chg_desc.get_property = pm2xxx_charger_ac_get_property; |
| 1050 | pm2->ac_chg.psy.supplied_to = pm2->pdata->supplied_to; | 1051 | |
| 1051 | pm2->ac_chg.psy.num_supplicants = pm2->pdata->num_supplicants; | 1052 | psy_cfg.supplied_to = pm2->pdata->supplied_to; |
| 1053 | psy_cfg.num_supplicants = pm2->pdata->num_supplicants; | ||
| 1052 | /* pm2xxx_charger sub-class */ | 1054 | /* pm2xxx_charger sub-class */ |
| 1053 | pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en; | 1055 | pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en; |
| 1054 | pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick; | 1056 | pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick; |
| @@ -1093,9 +1095,11 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
| 1093 | } | 1095 | } |
| 1094 | 1096 | ||
| 1095 | /* Register AC charger class */ | 1097 | /* Register AC charger class */ |
| 1096 | ret = power_supply_register(pm2->dev, &pm2->ac_chg.psy); | 1098 | pm2->ac_chg.psy = power_supply_register(pm2->dev, &pm2->ac_chg_desc, |
| 1097 | if (ret) { | 1099 | &psy_cfg); |
| 1100 | if (IS_ERR(pm2->ac_chg.psy)) { | ||
| 1098 | dev_err(pm2->dev, "failed to register AC charger\n"); | 1101 | dev_err(pm2->dev, "failed to register AC charger\n"); |
| 1102 | ret = PTR_ERR(pm2->ac_chg.psy); | ||
| 1099 | goto free_regulator; | 1103 | goto free_regulator; |
| 1100 | } | 1104 | } |
| 1101 | 1105 | ||
| @@ -1167,8 +1171,8 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
| 1167 | ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, | 1171 | ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, |
| 1168 | AB8500_MAIN_CH_DET); | 1172 | AB8500_MAIN_CH_DET); |
| 1169 | pm2->ac_conn = true; | 1173 | pm2->ac_conn = true; |
| 1170 | power_supply_changed(&pm2->ac_chg.psy); | 1174 | power_supply_changed(pm2->ac_chg.psy); |
| 1171 | sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); | 1175 | sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present"); |
| 1172 | } | 1176 | } |
| 1173 | 1177 | ||
| 1174 | return 0; | 1178 | return 0; |
| @@ -1183,7 +1187,7 @@ unregister_pm2xxx_interrupt: | |||
| 1183 | free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); | 1187 | free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); |
| 1184 | unregister_pm2xxx_charger: | 1188 | unregister_pm2xxx_charger: |
| 1185 | /* unregister power supply */ | 1189 | /* unregister power supply */ |
| 1186 | power_supply_unregister(&pm2->ac_chg.psy); | 1190 | power_supply_unregister(pm2->ac_chg.psy); |
| 1187 | free_regulator: | 1191 | free_regulator: |
| 1188 | /* disable the regulator */ | 1192 | /* disable the regulator */ |
| 1189 | regulator_put(pm2->regu); | 1193 | regulator_put(pm2->regu); |
| @@ -1218,7 +1222,7 @@ static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) | |||
| 1218 | /* disable the regulator */ | 1222 | /* disable the regulator */ |
| 1219 | regulator_put(pm2->regu); | 1223 | regulator_put(pm2->regu); |
| 1220 | 1224 | ||
| 1221 | power_supply_unregister(&pm2->ac_chg.psy); | 1225 | power_supply_unregister(pm2->ac_chg.psy); |
| 1222 | 1226 | ||
| 1223 | if (gpio_is_valid(pm2->lpn_pin)) | 1227 | if (gpio_is_valid(pm2->lpn_pin)) |
| 1224 | gpio_free(pm2->lpn_pin); | 1228 | gpio_free(pm2->lpn_pin); |
diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h index 8ce3cc0195df..24181cf9717b 100644 --- a/drivers/power/pm2301_charger.h +++ b/drivers/power/pm2301_charger.h | |||
| @@ -486,6 +486,7 @@ struct pm2xxx_charger { | |||
| 486 | struct work_struct check_main_thermal_prot_work; | 486 | struct work_struct check_main_thermal_prot_work; |
| 487 | struct delayed_work check_hw_failure_work; | 487 | struct delayed_work check_hw_failure_work; |
| 488 | struct ux500_charger ac_chg; | 488 | struct ux500_charger ac_chg; |
| 489 | struct power_supply_desc ac_chg_desc; | ||
| 489 | struct pm2xxx_charger_event_flags flags; | 490 | struct pm2xxx_charger_event_flags flags; |
| 490 | }; | 491 | }; |
| 491 | 492 | ||
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c index 023d24993b87..9c8d5253812c 100644 --- a/drivers/power/pmu_battery.c +++ b/drivers/power/pmu_battery.c | |||
| @@ -17,13 +17,14 @@ | |||
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | 18 | ||
| 19 | static struct pmu_battery_dev { | 19 | static struct pmu_battery_dev { |
| 20 | struct power_supply bat; | 20 | struct power_supply *bat; |
| 21 | struct power_supply_desc bat_desc; | ||
| 21 | struct pmu_battery_info *pbi; | 22 | struct pmu_battery_info *pbi; |
| 22 | char name[16]; | 23 | char name[16]; |
| 23 | int propval; | 24 | int propval; |
| 24 | } *pbats[PMU_MAX_BATTERIES]; | 25 | } *pbats[PMU_MAX_BATTERIES]; |
| 25 | 26 | ||
| 26 | #define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat) | 27 | #define to_pmu_battery_dev(x) power_supply_get_drvdata(x) |
| 27 | 28 | ||
| 28 | /********************************************************************* | 29 | /********************************************************************* |
| 29 | * Power | 30 | * Power |
| @@ -49,7 +50,7 @@ static enum power_supply_property pmu_ac_props[] = { | |||
| 49 | POWER_SUPPLY_PROP_ONLINE, | 50 | POWER_SUPPLY_PROP_ONLINE, |
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 52 | static struct power_supply pmu_ac = { | 53 | static const struct power_supply_desc pmu_ac_desc = { |
| 53 | .name = "pmu-ac", | 54 | .name = "pmu-ac", |
| 54 | .type = POWER_SUPPLY_TYPE_MAINS, | 55 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 55 | .properties = pmu_ac_props, | 56 | .properties = pmu_ac_props, |
| @@ -57,6 +58,8 @@ static struct power_supply pmu_ac = { | |||
| 57 | .get_property = pmu_get_ac_prop, | 58 | .get_property = pmu_get_ac_prop, |
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 61 | static struct power_supply *pmu_ac; | ||
| 62 | |||
| 60 | /********************************************************************* | 63 | /********************************************************************* |
| 61 | * Battery properties | 64 | * Battery properties |
| 62 | *********************************************************************/ | 65 | *********************************************************************/ |
| @@ -142,7 +145,7 @@ static struct platform_device *bat_pdev; | |||
| 142 | 145 | ||
| 143 | static int __init pmu_bat_init(void) | 146 | static int __init pmu_bat_init(void) |
| 144 | { | 147 | { |
| 145 | int ret; | 148 | int ret = 0; |
| 146 | int i; | 149 | int i; |
| 147 | 150 | ||
| 148 | bat_pdev = platform_device_register_simple("pmu-battery", | 151 | bat_pdev = platform_device_register_simple("pmu-battery", |
| @@ -152,25 +155,32 @@ static int __init pmu_bat_init(void) | |||
| 152 | goto pdev_register_failed; | 155 | goto pdev_register_failed; |
| 153 | } | 156 | } |
| 154 | 157 | ||
| 155 | ret = power_supply_register(&bat_pdev->dev, &pmu_ac); | 158 | pmu_ac = power_supply_register(&bat_pdev->dev, &pmu_ac_desc, NULL); |
| 156 | if (ret) | 159 | if (IS_ERR(pmu_ac)) { |
| 160 | ret = PTR_ERR(pmu_ac); | ||
| 157 | goto ac_register_failed; | 161 | goto ac_register_failed; |
| 162 | } | ||
| 158 | 163 | ||
| 159 | for (i = 0; i < pmu_battery_count; i++) { | 164 | for (i = 0; i < pmu_battery_count; i++) { |
| 165 | struct power_supply_config psy_cfg = {}; | ||
| 160 | struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat), | 166 | struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat), |
| 161 | GFP_KERNEL); | 167 | GFP_KERNEL); |
| 162 | if (!pbat) | 168 | if (!pbat) |
| 163 | break; | 169 | break; |
| 164 | 170 | ||
| 165 | sprintf(pbat->name, "PMU_battery_%d", i); | 171 | sprintf(pbat->name, "PMU_battery_%d", i); |
| 166 | pbat->bat.name = pbat->name; | 172 | pbat->bat_desc.name = pbat->name; |
| 167 | pbat->bat.properties = pmu_bat_props; | 173 | pbat->bat_desc.properties = pmu_bat_props; |
| 168 | pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props); | 174 | pbat->bat_desc.num_properties = ARRAY_SIZE(pmu_bat_props); |
| 169 | pbat->bat.get_property = pmu_bat_get_property; | 175 | pbat->bat_desc.get_property = pmu_bat_get_property; |
| 170 | pbat->pbi = &pmu_batteries[i]; | 176 | pbat->pbi = &pmu_batteries[i]; |
| 177 | psy_cfg.drv_data = pbat; | ||
| 171 | 178 | ||
| 172 | ret = power_supply_register(&bat_pdev->dev, &pbat->bat); | 179 | pbat->bat = power_supply_register(&bat_pdev->dev, |
| 173 | if (ret) { | 180 | &pbat->bat_desc, |
| 181 | &psy_cfg); | ||
| 182 | if (IS_ERR(pbat->bat)) { | ||
| 183 | ret = PTR_ERR(pbat->bat); | ||
| 174 | kfree(pbat); | 184 | kfree(pbat); |
| 175 | goto battery_register_failed; | 185 | goto battery_register_failed; |
| 176 | } | 186 | } |
| @@ -183,10 +193,10 @@ battery_register_failed: | |||
| 183 | while (i--) { | 193 | while (i--) { |
| 184 | if (!pbats[i]) | 194 | if (!pbats[i]) |
| 185 | continue; | 195 | continue; |
| 186 | power_supply_unregister(&pbats[i]->bat); | 196 | power_supply_unregister(pbats[i]->bat); |
| 187 | kfree(pbats[i]); | 197 | kfree(pbats[i]); |
| 188 | } | 198 | } |
| 189 | power_supply_unregister(&pmu_ac); | 199 | power_supply_unregister(pmu_ac); |
| 190 | ac_register_failed: | 200 | ac_register_failed: |
| 191 | platform_device_unregister(bat_pdev); | 201 | platform_device_unregister(bat_pdev); |
| 192 | pdev_register_failed: | 202 | pdev_register_failed: |
| @@ -201,10 +211,10 @@ static void __exit pmu_bat_exit(void) | |||
| 201 | for (i = 0; i < PMU_MAX_BATTERIES; i++) { | 211 | for (i = 0; i < PMU_MAX_BATTERIES; i++) { |
| 202 | if (!pbats[i]) | 212 | if (!pbats[i]) |
| 203 | continue; | 213 | continue; |
| 204 | power_supply_unregister(&pbats[i]->bat); | 214 | power_supply_unregister(pbats[i]->bat); |
| 205 | kfree(pbats[i]); | 215 | kfree(pbats[i]); |
| 206 | } | 216 | } |
| 207 | power_supply_unregister(&pmu_ac); | 217 | power_supply_unregister(pmu_ac); |
| 208 | platform_device_unregister(bat_pdev); | 218 | platform_device_unregister(bat_pdev); |
| 209 | } | 219 | } |
| 210 | 220 | ||
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 694e8cddd5c1..2ed4a4a6b3c5 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
| @@ -40,16 +40,16 @@ static bool __power_supply_is_supplied_by(struct power_supply *supplier, | |||
| 40 | 40 | ||
| 41 | /* Support both supplied_to and supplied_from modes */ | 41 | /* Support both supplied_to and supplied_from modes */ |
| 42 | if (supply->supplied_from) { | 42 | if (supply->supplied_from) { |
| 43 | if (!supplier->name) | 43 | if (!supplier->desc->name) |
| 44 | return false; | 44 | return false; |
| 45 | for (i = 0; i < supply->num_supplies; i++) | 45 | for (i = 0; i < supply->num_supplies; i++) |
| 46 | if (!strcmp(supplier->name, supply->supplied_from[i])) | 46 | if (!strcmp(supplier->desc->name, supply->supplied_from[i])) |
| 47 | return true; | 47 | return true; |
| 48 | } else { | 48 | } else { |
| 49 | if (!supply->name) | 49 | if (!supply->desc->name) |
| 50 | return false; | 50 | return false; |
| 51 | for (i = 0; i < supplier->num_supplicants; i++) | 51 | for (i = 0; i < supplier->num_supplicants; i++) |
| 52 | if (!strcmp(supplier->supplied_to[i], supply->name)) | 52 | if (!strcmp(supplier->supplied_to[i], supply->desc->name)) |
| 53 | return true; | 53 | return true; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| @@ -62,8 +62,8 @@ static int __power_supply_changed_work(struct device *dev, void *data) | |||
| 62 | struct power_supply *pst = dev_get_drvdata(dev); | 62 | struct power_supply *pst = dev_get_drvdata(dev); |
| 63 | 63 | ||
| 64 | if (__power_supply_is_supplied_by(psy, pst)) { | 64 | if (__power_supply_is_supplied_by(psy, pst)) { |
| 65 | if (pst->external_power_changed) | 65 | if (pst->desc->external_power_changed) |
| 66 | pst->external_power_changed(pst); | 66 | pst->desc->external_power_changed(pst); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | return 0; | 69 | return 0; |
| @@ -75,7 +75,7 @@ static void power_supply_changed_work(struct work_struct *work) | |||
| 75 | struct power_supply *psy = container_of(work, struct power_supply, | 75 | struct power_supply *psy = container_of(work, struct power_supply, |
| 76 | changed_work); | 76 | changed_work); |
| 77 | 77 | ||
| 78 | dev_dbg(psy->dev, "%s\n", __func__); | 78 | dev_dbg(&psy->dev, "%s\n", __func__); |
| 79 | 79 | ||
| 80 | spin_lock_irqsave(&psy->changed_lock, flags); | 80 | spin_lock_irqsave(&psy->changed_lock, flags); |
| 81 | /* | 81 | /* |
| @@ -93,7 +93,7 @@ static void power_supply_changed_work(struct work_struct *work) | |||
| 93 | power_supply_update_leds(psy); | 93 | power_supply_update_leds(psy); |
| 94 | atomic_notifier_call_chain(&power_supply_notifier, | 94 | atomic_notifier_call_chain(&power_supply_notifier, |
| 95 | PSY_EVENT_PROP_CHANGED, psy); | 95 | PSY_EVENT_PROP_CHANGED, psy); |
| 96 | kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); | 96 | kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE); |
| 97 | spin_lock_irqsave(&psy->changed_lock, flags); | 97 | spin_lock_irqsave(&psy->changed_lock, flags); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -103,7 +103,7 @@ static void power_supply_changed_work(struct work_struct *work) | |||
| 103 | * to true. | 103 | * to true. |
| 104 | */ | 104 | */ |
| 105 | if (likely(!psy->changed)) | 105 | if (likely(!psy->changed)) |
| 106 | pm_relax(psy->dev); | 106 | pm_relax(&psy->dev); |
| 107 | spin_unlock_irqrestore(&psy->changed_lock, flags); | 107 | spin_unlock_irqrestore(&psy->changed_lock, flags); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -111,11 +111,11 @@ void power_supply_changed(struct power_supply *psy) | |||
| 111 | { | 111 | { |
| 112 | unsigned long flags; | 112 | unsigned long flags; |
| 113 | 113 | ||
| 114 | dev_dbg(psy->dev, "%s\n", __func__); | 114 | dev_dbg(&psy->dev, "%s\n", __func__); |
| 115 | 115 | ||
| 116 | spin_lock_irqsave(&psy->changed_lock, flags); | 116 | spin_lock_irqsave(&psy->changed_lock, flags); |
| 117 | psy->changed = true; | 117 | psy->changed = true; |
| 118 | pm_stay_awake(psy->dev); | 118 | pm_stay_awake(&psy->dev); |
| 119 | spin_unlock_irqrestore(&psy->changed_lock, flags); | 119 | spin_unlock_irqrestore(&psy->changed_lock, flags); |
| 120 | schedule_work(&psy->changed_work); | 120 | schedule_work(&psy->changed_work); |
| 121 | } | 121 | } |
| @@ -138,9 +138,9 @@ static int __power_supply_populate_supplied_from(struct device *dev, | |||
| 138 | break; | 138 | break; |
| 139 | 139 | ||
| 140 | if (np == epsy->of_node) { | 140 | if (np == epsy->of_node) { |
| 141 | dev_info(psy->dev, "%s: Found supply : %s\n", | 141 | dev_info(&psy->dev, "%s: Found supply : %s\n", |
| 142 | psy->name, epsy->name); | 142 | psy->desc->name, epsy->desc->name); |
| 143 | psy->supplied_from[i-1] = (char *)epsy->name; | 143 | psy->supplied_from[i-1] = (char *)epsy->desc->name; |
| 144 | psy->num_supplies++; | 144 | psy->num_supplies++; |
| 145 | of_node_put(np); | 145 | of_node_put(np); |
| 146 | break; | 146 | break; |
| @@ -158,7 +158,7 @@ static int power_supply_populate_supplied_from(struct power_supply *psy) | |||
| 158 | error = class_for_each_device(power_supply_class, NULL, psy, | 158 | error = class_for_each_device(power_supply_class, NULL, psy, |
| 159 | __power_supply_populate_supplied_from); | 159 | __power_supply_populate_supplied_from); |
| 160 | 160 | ||
| 161 | dev_dbg(psy->dev, "%s %d\n", __func__, error); | 161 | dev_dbg(&psy->dev, "%s %d\n", __func__, error); |
| 162 | 162 | ||
| 163 | return error; | 163 | return error; |
| 164 | } | 164 | } |
| @@ -220,7 +220,7 @@ static int power_supply_check_supplies(struct power_supply *psy) | |||
| 220 | of_node_put(np); | 220 | of_node_put(np); |
| 221 | 221 | ||
| 222 | if (ret) { | 222 | if (ret) { |
| 223 | dev_dbg(psy->dev, "Failed to find supply!\n"); | 223 | dev_dbg(&psy->dev, "Failed to find supply!\n"); |
| 224 | return ret; | 224 | return ret; |
| 225 | } | 225 | } |
| 226 | } while (np); | 226 | } while (np); |
| @@ -230,17 +230,18 @@ static int power_supply_check_supplies(struct power_supply *psy) | |||
| 230 | return 0; | 230 | return 0; |
| 231 | 231 | ||
| 232 | /* All supplies found, allocate char ** array for filling */ | 232 | /* All supplies found, allocate char ** array for filling */ |
| 233 | psy->supplied_from = devm_kzalloc(psy->dev, sizeof(psy->supplied_from), | 233 | psy->supplied_from = devm_kzalloc(&psy->dev, sizeof(psy->supplied_from), |
| 234 | GFP_KERNEL); | 234 | GFP_KERNEL); |
| 235 | if (!psy->supplied_from) { | 235 | if (!psy->supplied_from) { |
| 236 | dev_err(psy->dev, "Couldn't allocate memory for supply list\n"); | 236 | dev_err(&psy->dev, "Couldn't allocate memory for supply list\n"); |
| 237 | return -ENOMEM; | 237 | return -ENOMEM; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | *psy->supplied_from = devm_kzalloc(psy->dev, sizeof(char *) * (cnt - 1), | 240 | *psy->supplied_from = devm_kzalloc(&psy->dev, |
| 241 | sizeof(char *) * (cnt - 1), | ||
| 241 | GFP_KERNEL); | 242 | GFP_KERNEL); |
| 242 | if (!*psy->supplied_from) { | 243 | if (!*psy->supplied_from) { |
| 243 | dev_err(psy->dev, "Couldn't allocate memory for supply list\n"); | 244 | dev_err(&psy->dev, "Couldn't allocate memory for supply list\n"); |
| 244 | return -ENOMEM; | 245 | return -ENOMEM; |
| 245 | } | 246 | } |
| 246 | 247 | ||
| @@ -260,7 +261,8 @@ static int __power_supply_am_i_supplied(struct device *dev, void *data) | |||
| 260 | struct power_supply *epsy = dev_get_drvdata(dev); | 261 | struct power_supply *epsy = dev_get_drvdata(dev); |
| 261 | 262 | ||
| 262 | if (__power_supply_is_supplied_by(epsy, psy)) | 263 | if (__power_supply_is_supplied_by(epsy, psy)) |
| 263 | if (!epsy->get_property(epsy, POWER_SUPPLY_PROP_ONLINE, &ret)) | 264 | if (!epsy->desc->get_property(epsy, POWER_SUPPLY_PROP_ONLINE, |
| 265 | &ret)) | ||
| 264 | return ret.intval; | 266 | return ret.intval; |
| 265 | 267 | ||
| 266 | return 0; | 268 | return 0; |
| @@ -273,7 +275,7 @@ int power_supply_am_i_supplied(struct power_supply *psy) | |||
| 273 | error = class_for_each_device(power_supply_class, NULL, psy, | 275 | error = class_for_each_device(power_supply_class, NULL, psy, |
| 274 | __power_supply_am_i_supplied); | 276 | __power_supply_am_i_supplied); |
| 275 | 277 | ||
| 276 | dev_dbg(psy->dev, "%s %d\n", __func__, error); | 278 | dev_dbg(&psy->dev, "%s %d\n", __func__, error); |
| 277 | 279 | ||
| 278 | return error; | 280 | return error; |
| 279 | } | 281 | } |
| @@ -286,8 +288,9 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) | |||
| 286 | unsigned int *count = data; | 288 | unsigned int *count = data; |
| 287 | 289 | ||
| 288 | (*count)++; | 290 | (*count)++; |
| 289 | if (psy->type != POWER_SUPPLY_TYPE_BATTERY) | 291 | if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) |
| 290 | if (!psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret)) | 292 | if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, |
| 293 | &ret)) | ||
| 291 | return ret.intval; | 294 | return ret.intval; |
| 292 | 295 | ||
| 293 | return 0; | 296 | return 0; |
| @@ -314,8 +317,10 @@ EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); | |||
| 314 | 317 | ||
| 315 | int power_supply_set_battery_charged(struct power_supply *psy) | 318 | int power_supply_set_battery_charged(struct power_supply *psy) |
| 316 | { | 319 | { |
| 317 | if (psy->type == POWER_SUPPLY_TYPE_BATTERY && psy->set_charged) { | 320 | if (atomic_read(&psy->use_cnt) >= 0 && |
| 318 | psy->set_charged(psy); | 321 | psy->desc->type == POWER_SUPPLY_TYPE_BATTERY && |
| 322 | psy->desc->set_charged) { | ||
| 323 | psy->desc->set_charged(psy); | ||
| 319 | return 0; | 324 | return 0; |
| 320 | } | 325 | } |
| 321 | 326 | ||
| @@ -328,28 +333,74 @@ static int power_supply_match_device_by_name(struct device *dev, const void *dat | |||
| 328 | const char *name = data; | 333 | const char *name = data; |
| 329 | struct power_supply *psy = dev_get_drvdata(dev); | 334 | struct power_supply *psy = dev_get_drvdata(dev); |
| 330 | 335 | ||
| 331 | return strcmp(psy->name, name) == 0; | 336 | return strcmp(psy->desc->name, name) == 0; |
| 332 | } | 337 | } |
| 333 | 338 | ||
| 339 | /** | ||
| 340 | * power_supply_get_by_name() - Search for a power supply and returns its ref | ||
| 341 | * @name: Power supply name to fetch | ||
| 342 | * | ||
| 343 | * If power supply was found, it increases reference count for the | ||
| 344 | * internal power supply's device. The user should power_supply_put() | ||
| 345 | * after usage. | ||
| 346 | * | ||
| 347 | * Return: On success returns a reference to a power supply with | ||
| 348 | * matching name equals to @name, a NULL otherwise. | ||
| 349 | */ | ||
| 334 | struct power_supply *power_supply_get_by_name(const char *name) | 350 | struct power_supply *power_supply_get_by_name(const char *name) |
| 335 | { | 351 | { |
| 352 | struct power_supply *psy = NULL; | ||
| 336 | struct device *dev = class_find_device(power_supply_class, NULL, name, | 353 | struct device *dev = class_find_device(power_supply_class, NULL, name, |
| 337 | power_supply_match_device_by_name); | 354 | power_supply_match_device_by_name); |
| 338 | 355 | ||
| 339 | return dev ? dev_get_drvdata(dev) : NULL; | 356 | if (dev) { |
| 357 | psy = dev_get_drvdata(dev); | ||
| 358 | atomic_inc(&psy->use_cnt); | ||
| 359 | } | ||
| 360 | |||
| 361 | return psy; | ||
| 340 | } | 362 | } |
| 341 | EXPORT_SYMBOL_GPL(power_supply_get_by_name); | 363 | EXPORT_SYMBOL_GPL(power_supply_get_by_name); |
| 342 | 364 | ||
| 365 | /** | ||
| 366 | * power_supply_put() - Drop reference obtained with power_supply_get_by_name | ||
| 367 | * @psy: Reference to put | ||
| 368 | * | ||
| 369 | * The reference to power supply should be put before unregistering | ||
| 370 | * the power supply. | ||
| 371 | */ | ||
| 372 | void power_supply_put(struct power_supply *psy) | ||
| 373 | { | ||
| 374 | might_sleep(); | ||
| 375 | |||
| 376 | atomic_dec(&psy->use_cnt); | ||
| 377 | put_device(&psy->dev); | ||
| 378 | } | ||
| 379 | EXPORT_SYMBOL_GPL(power_supply_put); | ||
| 380 | |||
| 343 | #ifdef CONFIG_OF | 381 | #ifdef CONFIG_OF |
| 344 | static int power_supply_match_device_node(struct device *dev, const void *data) | 382 | static int power_supply_match_device_node(struct device *dev, const void *data) |
| 345 | { | 383 | { |
| 346 | return dev->parent && dev->parent->of_node == data; | 384 | return dev->parent && dev->parent->of_node == data; |
| 347 | } | 385 | } |
| 348 | 386 | ||
| 387 | /** | ||
| 388 | * power_supply_get_by_phandle() - Search for a power supply and returns its ref | ||
| 389 | * @np: Pointer to device node holding phandle property | ||
| 390 | * @phandle_name: Name of property holding a power supply name | ||
| 391 | * | ||
| 392 | * If power supply was found, it increases reference count for the | ||
| 393 | * internal power supply's device. The user should power_supply_put() | ||
| 394 | * after usage. | ||
| 395 | * | ||
| 396 | * Return: On success returns a reference to a power supply with | ||
| 397 | * matching name equals to value under @property, NULL or ERR_PTR otherwise. | ||
| 398 | */ | ||
| 349 | struct power_supply *power_supply_get_by_phandle(struct device_node *np, | 399 | struct power_supply *power_supply_get_by_phandle(struct device_node *np, |
| 350 | const char *property) | 400 | const char *property) |
| 351 | { | 401 | { |
| 352 | struct device_node *power_supply_np; | 402 | struct device_node *power_supply_np; |
| 403 | struct power_supply *psy = NULL; | ||
| 353 | struct device *dev; | 404 | struct device *dev; |
| 354 | 405 | ||
| 355 | power_supply_np = of_parse_phandle(np, property, 0); | 406 | power_supply_np = of_parse_phandle(np, property, 0); |
| @@ -361,21 +412,70 @@ struct power_supply *power_supply_get_by_phandle(struct device_node *np, | |||
| 361 | 412 | ||
| 362 | of_node_put(power_supply_np); | 413 | of_node_put(power_supply_np); |
| 363 | 414 | ||
| 364 | return dev ? dev_get_drvdata(dev) : NULL; | 415 | if (dev) { |
| 416 | psy = dev_get_drvdata(dev); | ||
| 417 | atomic_inc(&psy->use_cnt); | ||
| 418 | } | ||
| 419 | |||
| 420 | return psy; | ||
| 365 | } | 421 | } |
| 366 | EXPORT_SYMBOL_GPL(power_supply_get_by_phandle); | 422 | EXPORT_SYMBOL_GPL(power_supply_get_by_phandle); |
| 367 | #endif /* CONFIG_OF */ | 423 | #endif /* CONFIG_OF */ |
| 368 | 424 | ||
| 425 | int power_supply_get_property(struct power_supply *psy, | ||
| 426 | enum power_supply_property psp, | ||
| 427 | union power_supply_propval *val) | ||
| 428 | { | ||
| 429 | if (atomic_read(&psy->use_cnt) <= 0) | ||
| 430 | return -ENODEV; | ||
| 431 | |||
| 432 | return psy->desc->get_property(psy, psp, val); | ||
| 433 | } | ||
| 434 | EXPORT_SYMBOL_GPL(power_supply_get_property); | ||
| 435 | |||
| 436 | int power_supply_set_property(struct power_supply *psy, | ||
| 437 | enum power_supply_property psp, | ||
| 438 | const union power_supply_propval *val) | ||
| 439 | { | ||
| 440 | if (atomic_read(&psy->use_cnt) <= 0 || !psy->desc->set_property) | ||
| 441 | return -ENODEV; | ||
| 442 | |||
| 443 | return psy->desc->set_property(psy, psp, val); | ||
| 444 | } | ||
| 445 | EXPORT_SYMBOL_GPL(power_supply_set_property); | ||
| 446 | |||
| 447 | int power_supply_property_is_writeable(struct power_supply *psy, | ||
| 448 | enum power_supply_property psp) | ||
| 449 | { | ||
| 450 | if (atomic_read(&psy->use_cnt) <= 0 || | ||
| 451 | !psy->desc->property_is_writeable) | ||
| 452 | return -ENODEV; | ||
| 453 | |||
| 454 | return psy->desc->property_is_writeable(psy, psp); | ||
| 455 | } | ||
| 456 | EXPORT_SYMBOL_GPL(power_supply_property_is_writeable); | ||
| 457 | |||
| 458 | void power_supply_external_power_changed(struct power_supply *psy) | ||
| 459 | { | ||
| 460 | if (atomic_read(&psy->use_cnt) <= 0 || | ||
| 461 | !psy->desc->external_power_changed) | ||
| 462 | return; | ||
| 463 | |||
| 464 | psy->desc->external_power_changed(psy); | ||
| 465 | } | ||
| 466 | EXPORT_SYMBOL_GPL(power_supply_external_power_changed); | ||
| 467 | |||
| 369 | int power_supply_powers(struct power_supply *psy, struct device *dev) | 468 | int power_supply_powers(struct power_supply *psy, struct device *dev) |
| 370 | { | 469 | { |
| 371 | return sysfs_create_link(&psy->dev->kobj, &dev->kobj, "powers"); | 470 | return sysfs_create_link(&psy->dev.kobj, &dev->kobj, "powers"); |
| 372 | } | 471 | } |
| 373 | EXPORT_SYMBOL_GPL(power_supply_powers); | 472 | EXPORT_SYMBOL_GPL(power_supply_powers); |
| 374 | 473 | ||
| 375 | static void power_supply_dev_release(struct device *dev) | 474 | static void power_supply_dev_release(struct device *dev) |
| 376 | { | 475 | { |
| 476 | struct power_supply *psy = container_of(dev, struct power_supply, dev); | ||
| 377 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 477 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
| 378 | kfree(dev); | 478 | kfree(psy); |
| 379 | } | 479 | } |
| 380 | 480 | ||
| 381 | int power_supply_reg_notifier(struct notifier_block *nb) | 481 | int power_supply_reg_notifier(struct notifier_block *nb) |
| @@ -400,7 +500,7 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd, | |||
| 400 | 500 | ||
| 401 | WARN_ON(tzd == NULL); | 501 | WARN_ON(tzd == NULL); |
| 402 | psy = tzd->devdata; | 502 | psy = tzd->devdata; |
| 403 | ret = psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val); | 503 | ret = psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val); |
| 404 | 504 | ||
| 405 | /* Convert tenths of degree Celsius to milli degree Celsius. */ | 505 | /* Convert tenths of degree Celsius to milli degree Celsius. */ |
| 406 | if (!ret) | 506 | if (!ret) |
| @@ -417,14 +517,14 @@ static int psy_register_thermal(struct power_supply *psy) | |||
| 417 | { | 517 | { |
| 418 | int i; | 518 | int i; |
| 419 | 519 | ||
| 420 | if (psy->no_thermal) | 520 | if (psy->desc->no_thermal) |
| 421 | return 0; | 521 | return 0; |
| 422 | 522 | ||
| 423 | /* Register battery zone device psy reports temperature */ | 523 | /* Register battery zone device psy reports temperature */ |
| 424 | for (i = 0; i < psy->num_properties; i++) { | 524 | for (i = 0; i < psy->desc->num_properties; i++) { |
| 425 | if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) { | 525 | if (psy->desc->properties[i] == POWER_SUPPLY_PROP_TEMP) { |
| 426 | psy->tzd = thermal_zone_device_register(psy->name, 0, 0, | 526 | psy->tzd = thermal_zone_device_register(psy->desc->name, |
| 427 | psy, &psy_tzd_ops, NULL, 0, 0); | 527 | 0, 0, psy, &psy_tzd_ops, NULL, 0, 0); |
| 428 | return PTR_ERR_OR_ZERO(psy->tzd); | 528 | return PTR_ERR_OR_ZERO(psy->tzd); |
| 429 | } | 529 | } |
| 430 | } | 530 | } |
| @@ -447,7 +547,7 @@ static int ps_get_max_charge_cntl_limit(struct thermal_cooling_device *tcd, | |||
| 447 | int ret; | 547 | int ret; |
| 448 | 548 | ||
| 449 | psy = tcd->devdata; | 549 | psy = tcd->devdata; |
| 450 | ret = psy->get_property(psy, | 550 | ret = psy->desc->get_property(psy, |
| 451 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val); | 551 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val); |
| 452 | if (!ret) | 552 | if (!ret) |
| 453 | *state = val.intval; | 553 | *state = val.intval; |
| @@ -463,7 +563,7 @@ static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device *tcd, | |||
| 463 | int ret; | 563 | int ret; |
| 464 | 564 | ||
| 465 | psy = tcd->devdata; | 565 | psy = tcd->devdata; |
| 466 | ret = psy->get_property(psy, | 566 | ret = psy->desc->get_property(psy, |
| 467 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); | 567 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); |
| 468 | if (!ret) | 568 | if (!ret) |
| 469 | *state = val.intval; | 569 | *state = val.intval; |
| @@ -480,7 +580,7 @@ static int ps_set_cur_charge_cntl_limit(struct thermal_cooling_device *tcd, | |||
| 480 | 580 | ||
| 481 | psy = tcd->devdata; | 581 | psy = tcd->devdata; |
| 482 | val.intval = state; | 582 | val.intval = state; |
| 483 | ret = psy->set_property(psy, | 583 | ret = psy->desc->set_property(psy, |
| 484 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); | 584 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val); |
| 485 | 585 | ||
| 486 | return ret; | 586 | return ret; |
| @@ -497,11 +597,11 @@ static int psy_register_cooler(struct power_supply *psy) | |||
| 497 | int i; | 597 | int i; |
| 498 | 598 | ||
| 499 | /* Register for cooling device if psy can control charging */ | 599 | /* Register for cooling device if psy can control charging */ |
| 500 | for (i = 0; i < psy->num_properties; i++) { | 600 | for (i = 0; i < psy->desc->num_properties; i++) { |
| 501 | if (psy->properties[i] == | 601 | if (psy->desc->properties[i] == |
| 502 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) { | 602 | POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) { |
| 503 | psy->tcd = thermal_cooling_device_register( | 603 | psy->tcd = thermal_cooling_device_register( |
| 504 | (char *)psy->name, | 604 | (char *)psy->desc->name, |
| 505 | psy, &psy_tcd_ops); | 605 | psy, &psy_tcd_ops); |
| 506 | return PTR_ERR_OR_ZERO(psy->tcd); | 606 | return PTR_ERR_OR_ZERO(psy->tcd); |
| 507 | } | 607 | } |
| @@ -535,15 +635,21 @@ static void psy_unregister_cooler(struct power_supply *psy) | |||
| 535 | } | 635 | } |
| 536 | #endif | 636 | #endif |
| 537 | 637 | ||
| 538 | static int __power_supply_register(struct device *parent, | 638 | static struct power_supply *__must_check |
| 539 | struct power_supply *psy, bool ws) | 639 | __power_supply_register(struct device *parent, |
| 640 | const struct power_supply_desc *desc, | ||
| 641 | const struct power_supply_config *cfg, | ||
| 642 | bool ws) | ||
| 540 | { | 643 | { |
| 541 | struct device *dev; | 644 | struct device *dev; |
| 645 | struct power_supply *psy; | ||
| 542 | int rc; | 646 | int rc; |
| 543 | 647 | ||
| 544 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 648 | psy = kzalloc(sizeof(*psy), GFP_KERNEL); |
| 545 | if (!dev) | 649 | if (!psy) |
| 546 | return -ENOMEM; | 650 | return ERR_PTR(-ENOMEM); |
| 651 | |||
| 652 | dev = &psy->dev; | ||
| 547 | 653 | ||
| 548 | device_initialize(dev); | 654 | device_initialize(dev); |
| 549 | 655 | ||
| @@ -552,9 +658,16 @@ static int __power_supply_register(struct device *parent, | |||
| 552 | dev->parent = parent; | 658 | dev->parent = parent; |
| 553 | dev->release = power_supply_dev_release; | 659 | dev->release = power_supply_dev_release; |
| 554 | dev_set_drvdata(dev, psy); | 660 | dev_set_drvdata(dev, psy); |
| 555 | psy->dev = dev; | 661 | psy->desc = desc; |
| 662 | atomic_inc(&psy->use_cnt); | ||
| 663 | if (cfg) { | ||
| 664 | psy->drv_data = cfg->drv_data; | ||
| 665 | psy->of_node = cfg->of_node; | ||
| 666 | psy->supplied_to = cfg->supplied_to; | ||
| 667 | psy->num_supplicants = cfg->num_supplicants; | ||
| 668 | } | ||
| 556 | 669 | ||
| 557 | rc = dev_set_name(dev, "%s", psy->name); | 670 | rc = dev_set_name(dev, "%s", desc->name); |
| 558 | if (rc) | 671 | if (rc) |
| 559 | goto dev_set_name_failed; | 672 | goto dev_set_name_failed; |
| 560 | 673 | ||
| @@ -589,7 +702,7 @@ static int __power_supply_register(struct device *parent, | |||
| 589 | 702 | ||
| 590 | power_supply_changed(psy); | 703 | power_supply_changed(psy); |
| 591 | 704 | ||
| 592 | return 0; | 705 | return psy; |
| 593 | 706 | ||
| 594 | create_triggers_failed: | 707 | create_triggers_failed: |
| 595 | psy_unregister_cooler(psy); | 708 | psy_unregister_cooler(psy); |
| @@ -602,33 +715,155 @@ wakeup_init_failed: | |||
| 602 | check_supplies_failed: | 715 | check_supplies_failed: |
| 603 | dev_set_name_failed: | 716 | dev_set_name_failed: |
| 604 | put_device(dev); | 717 | put_device(dev); |
| 605 | return rc; | 718 | return ERR_PTR(rc); |
| 606 | } | 719 | } |
| 607 | 720 | ||
| 608 | int power_supply_register(struct device *parent, struct power_supply *psy) | 721 | /** |
| 722 | * power_supply_register() - Register new power supply | ||
| 723 | * @parent: Device to be a parent of power supply's device | ||
| 724 | * @desc: Description of power supply, must be valid through whole | ||
| 725 | * lifetime of this power supply | ||
| 726 | * @cfg: Run-time specific configuration accessed during registering, | ||
| 727 | * may be NULL | ||
| 728 | * | ||
| 729 | * Return: A pointer to newly allocated power_supply on success | ||
| 730 | * or ERR_PTR otherwise. | ||
| 731 | * Use power_supply_unregister() on returned power_supply pointer to release | ||
| 732 | * resources. | ||
| 733 | */ | ||
| 734 | struct power_supply *__must_check power_supply_register(struct device *parent, | ||
| 735 | const struct power_supply_desc *desc, | ||
| 736 | const struct power_supply_config *cfg) | ||
| 609 | { | 737 | { |
| 610 | return __power_supply_register(parent, psy, true); | 738 | return __power_supply_register(parent, desc, cfg, true); |
| 611 | } | 739 | } |
| 612 | EXPORT_SYMBOL_GPL(power_supply_register); | 740 | EXPORT_SYMBOL_GPL(power_supply_register); |
| 613 | 741 | ||
| 614 | int power_supply_register_no_ws(struct device *parent, struct power_supply *psy) | 742 | /** |
| 743 | * power_supply_register() - Register new non-waking-source power supply | ||
| 744 | * @parent: Device to be a parent of power supply's device | ||
| 745 | * @desc: Description of power supply, must be valid through whole | ||
| 746 | * lifetime of this power supply | ||
| 747 | * @cfg: Run-time specific configuration accessed during registering, | ||
| 748 | * may be NULL | ||
| 749 | * | ||
| 750 | * Return: A pointer to newly allocated power_supply on success | ||
| 751 | * or ERR_PTR otherwise. | ||
| 752 | * Use power_supply_unregister() on returned power_supply pointer to release | ||
| 753 | * resources. | ||
| 754 | */ | ||
| 755 | struct power_supply *__must_check | ||
| 756 | power_supply_register_no_ws(struct device *parent, | ||
| 757 | const struct power_supply_desc *desc, | ||
| 758 | const struct power_supply_config *cfg) | ||
| 615 | { | 759 | { |
| 616 | return __power_supply_register(parent, psy, false); | 760 | return __power_supply_register(parent, desc, cfg, false); |
| 617 | } | 761 | } |
| 618 | EXPORT_SYMBOL_GPL(power_supply_register_no_ws); | 762 | EXPORT_SYMBOL_GPL(power_supply_register_no_ws); |
| 619 | 763 | ||
| 764 | static void devm_power_supply_release(struct device *dev, void *res) | ||
| 765 | { | ||
| 766 | struct power_supply **psy = res; | ||
| 767 | |||
| 768 | power_supply_unregister(*psy); | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * power_supply_register() - Register managed power supply | ||
| 773 | * @parent: Device to be a parent of power supply's device | ||
| 774 | * @desc: Description of power supply, must be valid through whole | ||
| 775 | * lifetime of this power supply | ||
| 776 | * @cfg: Run-time specific configuration accessed during registering, | ||
| 777 | * may be NULL | ||
| 778 | * | ||
| 779 | * Return: A pointer to newly allocated power_supply on success | ||
| 780 | * or ERR_PTR otherwise. | ||
| 781 | * The returned power_supply pointer will be automatically unregistered | ||
| 782 | * on driver detach. | ||
| 783 | */ | ||
| 784 | struct power_supply *__must_check | ||
| 785 | devm_power_supply_register(struct device *parent, | ||
| 786 | const struct power_supply_desc *desc, | ||
| 787 | const struct power_supply_config *cfg) | ||
| 788 | { | ||
| 789 | struct power_supply **ptr, *psy; | ||
| 790 | |||
| 791 | ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL); | ||
| 792 | |||
| 793 | if (!ptr) | ||
| 794 | return ERR_PTR(-ENOMEM); | ||
| 795 | psy = __power_supply_register(parent, desc, cfg, true); | ||
| 796 | if (IS_ERR(psy)) { | ||
| 797 | devres_free(ptr); | ||
| 798 | } else { | ||
| 799 | *ptr = psy; | ||
| 800 | devres_add(parent, ptr); | ||
| 801 | } | ||
| 802 | return psy; | ||
| 803 | } | ||
| 804 | EXPORT_SYMBOL_GPL(devm_power_supply_register); | ||
| 805 | |||
| 806 | /** | ||
| 807 | * power_supply_register() - Register managed non-waking-source power supply | ||
| 808 | * @parent: Device to be a parent of power supply's device | ||
| 809 | * @desc: Description of power supply, must be valid through whole | ||
| 810 | * lifetime of this power supply | ||
| 811 | * @cfg: Run-time specific configuration accessed during registering, | ||
| 812 | * may be NULL | ||
| 813 | * | ||
| 814 | * Return: A pointer to newly allocated power_supply on success | ||
| 815 | * or ERR_PTR otherwise. | ||
| 816 | * The returned power_supply pointer will be automatically unregistered | ||
| 817 | * on driver detach. | ||
| 818 | */ | ||
| 819 | struct power_supply *__must_check | ||
| 820 | devm_power_supply_register_no_ws(struct device *parent, | ||
| 821 | const struct power_supply_desc *desc, | ||
| 822 | const struct power_supply_config *cfg) | ||
| 823 | { | ||
| 824 | struct power_supply **ptr, *psy; | ||
| 825 | |||
| 826 | ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL); | ||
| 827 | |||
| 828 | if (!ptr) | ||
| 829 | return ERR_PTR(-ENOMEM); | ||
| 830 | psy = __power_supply_register(parent, desc, cfg, false); | ||
| 831 | if (IS_ERR(psy)) { | ||
| 832 | devres_free(ptr); | ||
| 833 | } else { | ||
| 834 | *ptr = psy; | ||
| 835 | devres_add(parent, ptr); | ||
| 836 | } | ||
| 837 | return psy; | ||
| 838 | } | ||
| 839 | EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws); | ||
| 840 | |||
| 841 | /** | ||
| 842 | * power_supply_unregister() - Remove this power supply from system | ||
| 843 | * @psy: Pointer to power supply to unregister | ||
| 844 | * | ||
| 845 | * Remove this power supply from the system. The resources of power supply | ||
| 846 | * will be freed here or on last power_supply_put() call. | ||
| 847 | */ | ||
| 620 | void power_supply_unregister(struct power_supply *psy) | 848 | void power_supply_unregister(struct power_supply *psy) |
| 621 | { | 849 | { |
| 850 | WARN_ON(atomic_dec_return(&psy->use_cnt)); | ||
| 622 | cancel_work_sync(&psy->changed_work); | 851 | cancel_work_sync(&psy->changed_work); |
| 623 | sysfs_remove_link(&psy->dev->kobj, "powers"); | 852 | sysfs_remove_link(&psy->dev.kobj, "powers"); |
| 624 | power_supply_remove_triggers(psy); | 853 | power_supply_remove_triggers(psy); |
| 625 | psy_unregister_cooler(psy); | 854 | psy_unregister_cooler(psy); |
| 626 | psy_unregister_thermal(psy); | 855 | psy_unregister_thermal(psy); |
| 627 | device_init_wakeup(psy->dev, false); | 856 | device_init_wakeup(&psy->dev, false); |
| 628 | device_unregister(psy->dev); | 857 | device_unregister(&psy->dev); |
| 629 | } | 858 | } |
| 630 | EXPORT_SYMBOL_GPL(power_supply_unregister); | 859 | EXPORT_SYMBOL_GPL(power_supply_unregister); |
| 631 | 860 | ||
| 861 | void *power_supply_get_drvdata(struct power_supply *psy) | ||
| 862 | { | ||
| 863 | return psy->drv_data; | ||
| 864 | } | ||
| 865 | EXPORT_SYMBOL_GPL(power_supply_get_drvdata); | ||
| 866 | |||
| 632 | static int __init power_supply_class_init(void) | 867 | static int __init power_supply_class_init(void) |
| 633 | { | 868 | { |
| 634 | power_supply_class = class_create(THIS_MODULE, "power_supply"); | 869 | power_supply_class = class_create(THIS_MODULE, "power_supply"); |
diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c index effa093c37b0..2d41a43fc81a 100644 --- a/drivers/power/power_supply_leds.c +++ b/drivers/power/power_supply_leds.c | |||
| @@ -25,10 +25,10 @@ static void power_supply_update_bat_leds(struct power_supply *psy) | |||
| 25 | unsigned long delay_on = 0; | 25 | unsigned long delay_on = 0; |
| 26 | unsigned long delay_off = 0; | 26 | unsigned long delay_off = 0; |
| 27 | 27 | ||
| 28 | if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) | 28 | if (psy->desc->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) |
| 29 | return; | 29 | return; |
| 30 | 30 | ||
| 31 | dev_dbg(psy->dev, "%s %d\n", __func__, status.intval); | 31 | dev_dbg(&psy->dev, "%s %d\n", __func__, status.intval); |
| 32 | 32 | ||
| 33 | switch (status.intval) { | 33 | switch (status.intval) { |
| 34 | case POWER_SUPPLY_STATUS_FULL: | 34 | case POWER_SUPPLY_STATUS_FULL: |
| @@ -58,21 +58,21 @@ static void power_supply_update_bat_leds(struct power_supply *psy) | |||
| 58 | static int power_supply_create_bat_triggers(struct power_supply *psy) | 58 | static int power_supply_create_bat_triggers(struct power_supply *psy) |
| 59 | { | 59 | { |
| 60 | psy->charging_full_trig_name = kasprintf(GFP_KERNEL, | 60 | psy->charging_full_trig_name = kasprintf(GFP_KERNEL, |
| 61 | "%s-charging-or-full", psy->name); | 61 | "%s-charging-or-full", psy->desc->name); |
| 62 | if (!psy->charging_full_trig_name) | 62 | if (!psy->charging_full_trig_name) |
| 63 | goto charging_full_failed; | 63 | goto charging_full_failed; |
| 64 | 64 | ||
| 65 | psy->charging_trig_name = kasprintf(GFP_KERNEL, | 65 | psy->charging_trig_name = kasprintf(GFP_KERNEL, |
| 66 | "%s-charging", psy->name); | 66 | "%s-charging", psy->desc->name); |
| 67 | if (!psy->charging_trig_name) | 67 | if (!psy->charging_trig_name) |
| 68 | goto charging_failed; | 68 | goto charging_failed; |
| 69 | 69 | ||
| 70 | psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->name); | 70 | psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->desc->name); |
| 71 | if (!psy->full_trig_name) | 71 | if (!psy->full_trig_name) |
| 72 | goto full_failed; | 72 | goto full_failed; |
| 73 | 73 | ||
| 74 | psy->charging_blink_full_solid_trig_name = kasprintf(GFP_KERNEL, | 74 | psy->charging_blink_full_solid_trig_name = kasprintf(GFP_KERNEL, |
| 75 | "%s-charging-blink-full-solid", psy->name); | 75 | "%s-charging-blink-full-solid", psy->desc->name); |
| 76 | if (!psy->charging_blink_full_solid_trig_name) | 76 | if (!psy->charging_blink_full_solid_trig_name) |
| 77 | goto charging_blink_full_solid_failed; | 77 | goto charging_blink_full_solid_failed; |
| 78 | 78 | ||
| @@ -115,10 +115,10 @@ static void power_supply_update_gen_leds(struct power_supply *psy) | |||
| 115 | { | 115 | { |
| 116 | union power_supply_propval online; | 116 | union power_supply_propval online; |
| 117 | 117 | ||
| 118 | if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online)) | 118 | if (psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online)) |
| 119 | return; | 119 | return; |
| 120 | 120 | ||
| 121 | dev_dbg(psy->dev, "%s %d\n", __func__, online.intval); | 121 | dev_dbg(&psy->dev, "%s %d\n", __func__, online.intval); |
| 122 | 122 | ||
| 123 | if (online.intval) | 123 | if (online.intval) |
| 124 | led_trigger_event(psy->online_trig, LED_FULL); | 124 | led_trigger_event(psy->online_trig, LED_FULL); |
| @@ -128,7 +128,8 @@ static void power_supply_update_gen_leds(struct power_supply *psy) | |||
| 128 | 128 | ||
| 129 | static int power_supply_create_gen_triggers(struct power_supply *psy) | 129 | static int power_supply_create_gen_triggers(struct power_supply *psy) |
| 130 | { | 130 | { |
| 131 | psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", psy->name); | 131 | psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", |
| 132 | psy->desc->name); | ||
| 132 | if (!psy->online_trig_name) | 133 | if (!psy->online_trig_name) |
| 133 | return -ENOMEM; | 134 | return -ENOMEM; |
| 134 | 135 | ||
| @@ -147,7 +148,7 @@ static void power_supply_remove_gen_triggers(struct power_supply *psy) | |||
| 147 | 148 | ||
| 148 | void power_supply_update_leds(struct power_supply *psy) | 149 | void power_supply_update_leds(struct power_supply *psy) |
| 149 | { | 150 | { |
| 150 | if (psy->type == POWER_SUPPLY_TYPE_BATTERY) | 151 | if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY) |
| 151 | power_supply_update_bat_leds(psy); | 152 | power_supply_update_bat_leds(psy); |
| 152 | else | 153 | else |
| 153 | power_supply_update_gen_leds(psy); | 154 | power_supply_update_gen_leds(psy); |
| @@ -155,14 +156,14 @@ void power_supply_update_leds(struct power_supply *psy) | |||
| 155 | 156 | ||
| 156 | int power_supply_create_triggers(struct power_supply *psy) | 157 | int power_supply_create_triggers(struct power_supply *psy) |
| 157 | { | 158 | { |
| 158 | if (psy->type == POWER_SUPPLY_TYPE_BATTERY) | 159 | if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY) |
| 159 | return power_supply_create_bat_triggers(psy); | 160 | return power_supply_create_bat_triggers(psy); |
| 160 | return power_supply_create_gen_triggers(psy); | 161 | return power_supply_create_gen_triggers(psy); |
| 161 | } | 162 | } |
| 162 | 163 | ||
| 163 | void power_supply_remove_triggers(struct power_supply *psy) | 164 | void power_supply_remove_triggers(struct power_supply *psy) |
| 164 | { | 165 | { |
| 165 | if (psy->type == POWER_SUPPLY_TYPE_BATTERY) | 166 | if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY) |
| 166 | power_supply_remove_bat_triggers(psy); | 167 | power_supply_remove_bat_triggers(psy); |
| 167 | else | 168 | else |
| 168 | power_supply_remove_gen_triggers(psy); | 169 | power_supply_remove_gen_triggers(psy); |
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 62653f50a524..9134e3d2d95e 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
| @@ -74,9 +74,9 @@ static ssize_t power_supply_show_property(struct device *dev, | |||
| 74 | union power_supply_propval value; | 74 | union power_supply_propval value; |
| 75 | 75 | ||
| 76 | if (off == POWER_SUPPLY_PROP_TYPE) { | 76 | if (off == POWER_SUPPLY_PROP_TYPE) { |
| 77 | value.intval = psy->type; | 77 | value.intval = psy->desc->type; |
| 78 | } else { | 78 | } else { |
| 79 | ret = psy->get_property(psy, off, &value); | 79 | ret = power_supply_get_property(psy, off, &value); |
| 80 | 80 | ||
| 81 | if (ret < 0) { | 81 | if (ret < 0) { |
| 82 | if (ret == -ENODATA) | 82 | if (ret == -ENODATA) |
| @@ -125,7 +125,7 @@ static ssize_t power_supply_store_property(struct device *dev, | |||
| 125 | 125 | ||
| 126 | value.intval = long_val; | 126 | value.intval = long_val; |
| 127 | 127 | ||
| 128 | ret = psy->set_property(psy, off, &value); | 128 | ret = psy->desc->set_property(psy, off, &value); |
| 129 | if (ret < 0) | 129 | if (ret < 0) |
| 130 | return ret; | 130 | return ret; |
| 131 | 131 | ||
| @@ -218,12 +218,12 @@ static umode_t power_supply_attr_is_visible(struct kobject *kobj, | |||
| 218 | if (attrno == POWER_SUPPLY_PROP_TYPE) | 218 | if (attrno == POWER_SUPPLY_PROP_TYPE) |
| 219 | return mode; | 219 | return mode; |
| 220 | 220 | ||
| 221 | for (i = 0; i < psy->num_properties; i++) { | 221 | for (i = 0; i < psy->desc->num_properties; i++) { |
| 222 | int property = psy->properties[i]; | 222 | int property = psy->desc->properties[i]; |
| 223 | 223 | ||
| 224 | if (property == attrno) { | 224 | if (property == attrno) { |
| 225 | if (psy->property_is_writeable && | 225 | if (psy->desc->property_is_writeable && |
| 226 | psy->property_is_writeable(psy, property) > 0) | 226 | power_supply_property_is_writeable(psy, property) > 0) |
| 227 | mode |= S_IWUSR; | 227 | mode |= S_IWUSR; |
| 228 | 228 | ||
| 229 | return mode; | 229 | return mode; |
| @@ -279,14 +279,14 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 279 | 279 | ||
| 280 | dev_dbg(dev, "uevent\n"); | 280 | dev_dbg(dev, "uevent\n"); |
| 281 | 281 | ||
| 282 | if (!psy || !psy->dev) { | 282 | if (!psy || !psy->desc) { |
| 283 | dev_dbg(dev, "No power supply yet\n"); | 283 | dev_dbg(dev, "No power supply yet\n"); |
| 284 | return ret; | 284 | return ret; |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); | 287 | dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->desc->name); |
| 288 | 288 | ||
| 289 | ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name); | 289 | ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->desc->name); |
| 290 | if (ret) | 290 | if (ret) |
| 291 | return ret; | 291 | return ret; |
| 292 | 292 | ||
| @@ -294,11 +294,11 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 294 | if (!prop_buf) | 294 | if (!prop_buf) |
| 295 | return -ENOMEM; | 295 | return -ENOMEM; |
| 296 | 296 | ||
| 297 | for (j = 0; j < psy->num_properties; j++) { | 297 | for (j = 0; j < psy->desc->num_properties; j++) { |
| 298 | struct device_attribute *attr; | 298 | struct device_attribute *attr; |
| 299 | char *line; | 299 | char *line; |
| 300 | 300 | ||
| 301 | attr = &power_supply_attrs[psy->properties[j]]; | 301 | attr = &power_supply_attrs[psy->desc->properties[j]]; |
| 302 | 302 | ||
| 303 | ret = power_supply_show_property(dev, attr, prop_buf); | 303 | ret = power_supply_show_property(dev, attr, prop_buf); |
| 304 | if (ret == -ENODEV || ret == -ENODATA) { | 304 | if (ret == -ENODEV || ret == -ENODATA) { |
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 27f6646731b0..aad9c3318c02 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
| @@ -151,9 +151,17 @@ config POWER_RESET_SYSCON | |||
| 151 | help | 151 | help |
| 152 | Reboot support for generic SYSCON mapped register reset. | 152 | Reboot support for generic SYSCON mapped register reset. |
| 153 | 153 | ||
| 154 | config POWER_RESET_SYSCON_POWEROFF | ||
| 155 | bool "Generic SYSCON regmap poweroff driver" | ||
| 156 | depends on OF | ||
| 157 | select MFD_SYSCON | ||
| 158 | help | ||
| 159 | Poweroff support for generic SYSCON mapped register poweroff. | ||
| 160 | |||
| 154 | config POWER_RESET_RMOBILE | 161 | config POWER_RESET_RMOBILE |
| 155 | tristate "Renesas R-Mobile reset driver" | 162 | tristate "Renesas R-Mobile reset driver" |
| 156 | depends on ARCH_RMOBILE || COMPILE_TEST | 163 | depends on ARCH_RMOBILE || COMPILE_TEST |
| 164 | depends on HAS_IOMEM | ||
| 157 | help | 165 | help |
| 158 | Reboot support for Renesas R-Mobile and SH-Mobile SoCs. | 166 | Reboot support for Renesas R-Mobile and SH-Mobile SoCs. |
| 159 | 167 | ||
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 11de15bae52e..dbe06c368743 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
| @@ -17,4 +17,5 @@ obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o | |||
| 17 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o | 17 | obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o |
| 18 | obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o | 18 | obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o |
| 19 | obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o | 19 | obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o |
| 20 | obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o | ||
| 20 | obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o | 21 | obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o |
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c index 4b72ea51c364..9847cfb7e23d 100644 --- a/drivers/power/reset/at91-poweroff.c +++ b/drivers/power/reset/at91-poweroff.c | |||
| @@ -140,7 +140,7 @@ static int at91_poweroff_probe(struct platform_device *pdev) | |||
| 140 | return 0; | 140 | return 0; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static struct of_device_id at91_poweroff_of_match[] = { | 143 | static const struct of_device_id at91_poweroff_of_match[] = { |
| 144 | { .compatible = "atmel,at91sam9260-shdwc", }, | 144 | { .compatible = "atmel,at91sam9260-shdwc", }, |
| 145 | { .compatible = "atmel,at91sam9rl-shdwc", }, | 145 | { .compatible = "atmel,at91sam9rl-shdwc", }, |
| 146 | { .compatible = "atmel,at91sam9x5-shdwc", }, | 146 | { .compatible = "atmel,at91sam9x5-shdwc", }, |
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 13584e24736a..01c7055c4200 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c | |||
| @@ -73,8 +73,8 @@ static int at91sam9260_restart(struct notifier_block *this, unsigned long mode, | |||
| 73 | : "r" (at91_ramc_base[0]), | 73 | : "r" (at91_ramc_base[0]), |
| 74 | "r" (at91_rstc_base), | 74 | "r" (at91_rstc_base), |
| 75 | "r" (1), | 75 | "r" (1), |
| 76 | "r" (AT91_SDRAMC_LPCB_POWER_DOWN), | 76 | "r" cpu_to_le32(AT91_SDRAMC_LPCB_POWER_DOWN), |
| 77 | "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); | 77 | "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); |
| 78 | 78 | ||
| 79 | return NOTIFY_DONE; | 79 | return NOTIFY_DONE; |
| 80 | } | 80 | } |
| @@ -116,8 +116,8 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, | |||
| 116 | "r" (at91_ramc_base[1]), | 116 | "r" (at91_ramc_base[1]), |
| 117 | "r" (at91_rstc_base), | 117 | "r" (at91_rstc_base), |
| 118 | "r" (1), | 118 | "r" (1), |
| 119 | "r" (AT91_DDRSDRC_LPCB_POWER_DOWN), | 119 | "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN), |
| 120 | "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) | 120 | "r" cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) |
| 121 | : "r0"); | 121 | : "r0"); |
| 122 | 122 | ||
| 123 | return NOTIFY_DONE; | 123 | return NOTIFY_DONE; |
| @@ -152,14 +152,14 @@ static void __init at91_reset_status(struct platform_device *pdev) | |||
| 152 | pr_info("AT91: Starting after %s\n", reason); | 152 | pr_info("AT91: Starting after %s\n", reason); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static struct of_device_id at91_ramc_of_match[] = { | 155 | static const struct of_device_id at91_ramc_of_match[] = { |
| 156 | { .compatible = "atmel,at91sam9260-sdramc", }, | 156 | { .compatible = "atmel,at91sam9260-sdramc", }, |
| 157 | { .compatible = "atmel,at91sam9g45-ddramc", }, | 157 | { .compatible = "atmel,at91sam9g45-ddramc", }, |
| 158 | { .compatible = "atmel,sama5d3-ddramc", }, | 158 | { .compatible = "atmel,sama5d3-ddramc", }, |
| 159 | { /* sentinel */ } | 159 | { /* sentinel */ } |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static struct of_device_id at91_reset_of_match[] = { | 162 | static const struct of_device_id at91_reset_of_match[] = { |
| 163 | { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, | 163 | { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, |
| 164 | { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, | 164 | { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, |
| 165 | { /* sentinel */ } | 165 | { /* sentinel */ } |
diff --git a/drivers/power/reset/hisi-reboot.c b/drivers/power/reset/hisi-reboot.c index 5385460e23bb..9ab7f562a83b 100644 --- a/drivers/power/reset/hisi-reboot.c +++ b/drivers/power/reset/hisi-reboot.c | |||
| @@ -64,7 +64,7 @@ static int hisi_reboot_probe(struct platform_device *pdev) | |||
| 64 | return err; | 64 | return err; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static struct of_device_id hisi_reboot_of_match[] = { | 67 | static const struct of_device_id hisi_reboot_of_match[] = { |
| 68 | { .compatible = "hisilicon,sysctrl" }, | 68 | { .compatible = "hisilicon,sysctrl" }, |
| 69 | {} | 69 | {} |
| 70 | }; | 70 | }; |
diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c index faedf16c8111..c70f1bffe038 100644 --- a/drivers/power/reset/keystone-reset.c +++ b/drivers/power/reset/keystone-reset.c | |||
| @@ -70,7 +70,7 @@ static struct notifier_block rsctrl_restart_nb = { | |||
| 70 | .priority = 128, | 70 | .priority = 128, |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | static struct of_device_id rsctrl_of_match[] = { | 73 | static const struct of_device_id rsctrl_of_match[] = { |
| 74 | {.compatible = "ti,keystone-reset", }, | 74 | {.compatible = "ti,keystone-reset", }, |
| 75 | {}, | 75 | {}, |
| 76 | }; | 76 | }; |
diff --git a/drivers/power/reset/st-poweroff.c b/drivers/power/reset/st-poweroff.c index 27383de9caa8..a488877a3538 100644 --- a/drivers/power/reset/st-poweroff.c +++ b/drivers/power/reset/st-poweroff.c | |||
| @@ -97,7 +97,7 @@ static struct notifier_block st_restart_nb = { | |||
| 97 | .priority = 192, | 97 | .priority = 192, |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | static struct of_device_id st_reset_of_match[] = { | 100 | static const struct of_device_id st_reset_of_match[] = { |
| 101 | { | 101 | { |
| 102 | .compatible = "st,stih415-restart", | 102 | .compatible = "st,stih415-restart", |
| 103 | .data = (void *)&stih415_reset, | 103 | .data = (void *)&stih415_reset, |
diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c new file mode 100644 index 000000000000..5560b0dbc180 --- /dev/null +++ b/drivers/power/reset/syscon-poweroff.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * Generic Syscon Poweroff Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2015, National Instruments Corp. | ||
| 5 | * Author: Moritz Fischer <moritz.fischer@ettus.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License as | ||
| 9 | * published by the Free Software Foundation; either version 2 of | ||
| 10 | * the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kallsyms.h> | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/notifier.h> | ||
| 22 | #include <linux/mfd/syscon.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/pm.h> | ||
| 27 | #include <linux/regmap.h> | ||
| 28 | |||
| 29 | static struct regmap *map; | ||
| 30 | static u32 offset; | ||
| 31 | static u32 mask; | ||
| 32 | |||
| 33 | void syscon_poweroff(void) | ||
| 34 | { | ||
| 35 | /* Issue the poweroff */ | ||
| 36 | regmap_write(map, offset, mask); | ||
| 37 | |||
| 38 | mdelay(1000); | ||
| 39 | |||
| 40 | pr_emerg("Unable to poweroff system\n"); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int syscon_poweroff_probe(struct platform_device *pdev) | ||
| 44 | { | ||
| 45 | char symname[KSYM_NAME_LEN]; | ||
| 46 | |||
| 47 | map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap"); | ||
| 48 | if (IS_ERR(map)) { | ||
| 49 | dev_err(&pdev->dev, "unable to get syscon"); | ||
| 50 | return PTR_ERR(map); | ||
| 51 | } | ||
| 52 | |||
| 53 | if (of_property_read_u32(pdev->dev.of_node, "offset", &offset)) { | ||
| 54 | dev_err(&pdev->dev, "unable to read 'offset'"); | ||
| 55 | return -EINVAL; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (of_property_read_u32(pdev->dev.of_node, "mask", &mask)) { | ||
| 59 | dev_err(&pdev->dev, "unable to read 'mask'"); | ||
| 60 | return -EINVAL; | ||
| 61 | } | ||
| 62 | |||
| 63 | if (pm_power_off) { | ||
| 64 | lookup_symbol_name((ulong)pm_power_off, symname); | ||
| 65 | dev_err(&pdev->dev, | ||
| 66 | "pm_power_off already claimed %p %s", | ||
| 67 | pm_power_off, symname); | ||
| 68 | return -EBUSY; | ||
| 69 | } | ||
| 70 | |||
| 71 | pm_power_off = syscon_poweroff; | ||
| 72 | |||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int syscon_poweroff_remove(struct platform_device *pdev) | ||
| 77 | { | ||
| 78 | if (pm_power_off == syscon_poweroff) | ||
| 79 | pm_power_off = NULL; | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static const struct of_device_id syscon_poweroff_of_match[] = { | ||
| 85 | { .compatible = "syscon-poweroff" }, | ||
| 86 | {} | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct platform_driver syscon_poweroff_driver = { | ||
| 90 | .probe = syscon_poweroff_probe, | ||
| 91 | .remove = syscon_poweroff_remove, | ||
| 92 | .driver = { | ||
| 93 | .name = "syscon-poweroff", | ||
| 94 | .of_match_table = syscon_poweroff_of_match, | ||
| 95 | }, | ||
| 96 | }; | ||
| 97 | |||
| 98 | static int __init syscon_poweroff_register(void) | ||
| 99 | { | ||
| 100 | return platform_driver_register(&syscon_poweroff_driver); | ||
| 101 | } | ||
| 102 | device_initcall(syscon_poweroff_register); | ||
diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c index c4049f45663f..d3c7d245ae63 100644 --- a/drivers/power/reset/syscon-reboot.c +++ b/drivers/power/reset/syscon-reboot.c | |||
| @@ -76,7 +76,7 @@ static int syscon_reboot_probe(struct platform_device *pdev) | |||
| 76 | return err; | 76 | return err; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static struct of_device_id syscon_reboot_of_match[] = { | 79 | static const struct of_device_id syscon_reboot_of_match[] = { |
| 80 | { .compatible = "syscon-reboot" }, | 80 | { .compatible = "syscon-reboot" }, |
| 81 | {} | 81 | {} |
| 82 | }; | 82 | }; |
diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index be12d9b92957..6a9bf7089373 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c | |||
| @@ -80,7 +80,7 @@ DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show, | |||
| 80 | 80 | ||
| 81 | enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT }; | 81 | enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT }; |
| 82 | 82 | ||
| 83 | static struct of_device_id vexpress_reset_of_match[] = { | 83 | static const struct of_device_id vexpress_reset_of_match[] = { |
| 84 | { | 84 | { |
| 85 | .compatible = "arm,vexpress-reset", | 85 | .compatible = "arm,vexpress-reset", |
| 86 | .data = (void *)FUNC_RESET, | 86 | .data = (void *)FUNC_RESET, |
diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index b0e5002f8deb..f07e93c97ba3 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c | |||
| @@ -87,7 +87,7 @@ static int xgene_reboot_probe(struct platform_device *pdev) | |||
| 87 | return err; | 87 | return err; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static struct of_device_id xgene_reboot_of_match[] = { | 90 | static const struct of_device_id xgene_reboot_of_match[] = { |
| 91 | { .compatible = "apm,xgene-reboot" }, | 91 | { .compatible = "apm,xgene-reboot" }, |
| 92 | {} | 92 | {} |
| 93 | }; | 93 | }; |
diff --git a/drivers/power/rt5033_battery.c b/drivers/power/rt5033_battery.c index 7b898f41c595..a7a6877b4e16 100644 --- a/drivers/power/rt5033_battery.c +++ b/drivers/power/rt5033_battery.c | |||
| @@ -72,8 +72,7 @@ static int rt5033_battery_get_property(struct power_supply *psy, | |||
| 72 | enum power_supply_property psp, | 72 | enum power_supply_property psp, |
| 73 | union power_supply_propval *val) | 73 | union power_supply_propval *val) |
| 74 | { | 74 | { |
| 75 | struct rt5033_battery *battery = container_of(psy, | 75 | struct rt5033_battery *battery = power_supply_get_drvdata(psy); |
| 76 | struct rt5033_battery, psy); | ||
| 77 | 76 | ||
| 78 | switch (psp) { | 77 | switch (psp) { |
| 79 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 78 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
| @@ -102,16 +101,25 @@ static enum power_supply_property rt5033_battery_props[] = { | |||
| 102 | POWER_SUPPLY_PROP_CAPACITY, | 101 | POWER_SUPPLY_PROP_CAPACITY, |
| 103 | }; | 102 | }; |
| 104 | 103 | ||
| 105 | static struct regmap_config rt5033_battery_regmap_config = { | 104 | static const struct regmap_config rt5033_battery_regmap_config = { |
| 106 | .reg_bits = 8, | 105 | .reg_bits = 8, |
| 107 | .val_bits = 8, | 106 | .val_bits = 8, |
| 108 | .max_register = RT5033_FUEL_REG_END, | 107 | .max_register = RT5033_FUEL_REG_END, |
| 109 | }; | 108 | }; |
| 110 | 109 | ||
| 110 | static const struct power_supply_desc rt5033_battery_desc = { | ||
| 111 | .name = "rt5033-battery", | ||
| 112 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 113 | .get_property = rt5033_battery_get_property, | ||
| 114 | .properties = rt5033_battery_props, | ||
| 115 | .num_properties = ARRAY_SIZE(rt5033_battery_props), | ||
| 116 | }; | ||
| 117 | |||
| 111 | static int rt5033_battery_probe(struct i2c_client *client, | 118 | static int rt5033_battery_probe(struct i2c_client *client, |
| 112 | const struct i2c_device_id *id) | 119 | const struct i2c_device_id *id) |
| 113 | { | 120 | { |
| 114 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 121 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 122 | struct power_supply_config psy_cfg = {}; | ||
| 115 | struct rt5033_battery *battery; | 123 | struct rt5033_battery *battery; |
| 116 | u32 ret; | 124 | u32 ret; |
| 117 | 125 | ||
| @@ -131,16 +139,13 @@ static int rt5033_battery_probe(struct i2c_client *client, | |||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | i2c_set_clientdata(client, battery); | 141 | i2c_set_clientdata(client, battery); |
| 142 | psy_cfg.drv_data = battery; | ||
| 134 | 143 | ||
| 135 | battery->psy.name = "rt5033-battery"; | 144 | battery->psy = power_supply_register(&client->dev, |
| 136 | battery->psy.type = POWER_SUPPLY_TYPE_BATTERY; | 145 | &rt5033_battery_desc, &psy_cfg); |
| 137 | battery->psy.get_property = rt5033_battery_get_property; | 146 | if (IS_ERR(battery->psy)) { |
| 138 | battery->psy.properties = rt5033_battery_props; | ||
| 139 | battery->psy.num_properties = ARRAY_SIZE(rt5033_battery_props); | ||
| 140 | |||
| 141 | ret = power_supply_register(&client->dev, &battery->psy); | ||
| 142 | if (ret) { | ||
| 143 | dev_err(&client->dev, "Failed to register power supply\n"); | 147 | dev_err(&client->dev, "Failed to register power supply\n"); |
| 148 | ret = PTR_ERR(battery->psy); | ||
| 144 | return ret; | 149 | return ret; |
| 145 | } | 150 | } |
| 146 | 151 | ||
| @@ -151,7 +156,7 @@ static int rt5033_battery_remove(struct i2c_client *client) | |||
| 151 | { | 156 | { |
| 152 | struct rt5033_battery *battery = i2c_get_clientdata(client); | 157 | struct rt5033_battery *battery = i2c_get_clientdata(client); |
| 153 | 158 | ||
| 154 | power_supply_unregister(&battery->psy); | 159 | power_supply_unregister(battery->psy); |
| 155 | 160 | ||
| 156 | return 0; | 161 | return 0; |
| 157 | } | 162 | } |
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index a01aacb32f59..ac6206951d58 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c | |||
| @@ -29,7 +29,8 @@ | |||
| 29 | 29 | ||
| 30 | struct rx51_device_info { | 30 | struct rx51_device_info { |
| 31 | struct device *dev; | 31 | struct device *dev; |
| 32 | struct power_supply bat; | 32 | struct power_supply *bat; |
| 33 | struct power_supply_desc bat_desc; | ||
| 33 | struct iio_channel *channel_temp; | 34 | struct iio_channel *channel_temp; |
| 34 | struct iio_channel *channel_bsi; | 35 | struct iio_channel *channel_bsi; |
| 35 | struct iio_channel *channel_vbat; | 36 | struct iio_channel *channel_vbat; |
| @@ -161,8 +162,7 @@ static int rx51_battery_get_property(struct power_supply *psy, | |||
| 161 | enum power_supply_property psp, | 162 | enum power_supply_property psp, |
| 162 | union power_supply_propval *val) | 163 | union power_supply_propval *val) |
| 163 | { | 164 | { |
| 164 | struct rx51_device_info *di = container_of((psy), | 165 | struct rx51_device_info *di = power_supply_get_drvdata(psy); |
| 165 | struct rx51_device_info, bat); | ||
| 166 | 166 | ||
| 167 | switch (psp) { | 167 | switch (psp) { |
| 168 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 168 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| @@ -204,6 +204,7 @@ static enum power_supply_property rx51_battery_props[] = { | |||
| 204 | 204 | ||
| 205 | static int rx51_battery_probe(struct platform_device *pdev) | 205 | static int rx51_battery_probe(struct platform_device *pdev) |
| 206 | { | 206 | { |
| 207 | struct power_supply_config psy_cfg = {}; | ||
| 207 | struct rx51_device_info *di; | 208 | struct rx51_device_info *di; |
| 208 | int ret; | 209 | int ret; |
| 209 | 210 | ||
| @@ -214,11 +215,13 @@ static int rx51_battery_probe(struct platform_device *pdev) | |||
| 214 | platform_set_drvdata(pdev, di); | 215 | platform_set_drvdata(pdev, di); |
| 215 | 216 | ||
| 216 | di->dev = &pdev->dev; | 217 | di->dev = &pdev->dev; |
| 217 | di->bat.name = dev_name(&pdev->dev); | 218 | di->bat_desc.name = dev_name(&pdev->dev); |
| 218 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 219 | di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 219 | di->bat.properties = rx51_battery_props; | 220 | di->bat_desc.properties = rx51_battery_props; |
| 220 | di->bat.num_properties = ARRAY_SIZE(rx51_battery_props); | 221 | di->bat_desc.num_properties = ARRAY_SIZE(rx51_battery_props); |
| 221 | di->bat.get_property = rx51_battery_get_property; | 222 | di->bat_desc.get_property = rx51_battery_get_property; |
| 223 | |||
| 224 | psy_cfg.drv_data = di; | ||
| 222 | 225 | ||
| 223 | di->channel_temp = iio_channel_get(di->dev, "temp"); | 226 | di->channel_temp = iio_channel_get(di->dev, "temp"); |
| 224 | if (IS_ERR(di->channel_temp)) { | 227 | if (IS_ERR(di->channel_temp)) { |
| @@ -238,9 +241,11 @@ static int rx51_battery_probe(struct platform_device *pdev) | |||
| 238 | goto error_channel_bsi; | 241 | goto error_channel_bsi; |
| 239 | } | 242 | } |
| 240 | 243 | ||
| 241 | ret = power_supply_register(di->dev, &di->bat); | 244 | di->bat = power_supply_register(di->dev, &di->bat_desc, &psy_cfg); |
| 242 | if (ret) | 245 | if (IS_ERR(di->bat)) { |
| 246 | ret = PTR_ERR(di->bat); | ||
| 243 | goto error_channel_vbat; | 247 | goto error_channel_vbat; |
| 248 | } | ||
| 244 | 249 | ||
| 245 | return 0; | 250 | return 0; |
| 246 | 251 | ||
| @@ -259,7 +264,7 @@ static int rx51_battery_remove(struct platform_device *pdev) | |||
| 259 | { | 264 | { |
| 260 | struct rx51_device_info *di = platform_get_drvdata(pdev); | 265 | struct rx51_device_info *di = platform_get_drvdata(pdev); |
| 261 | 266 | ||
| 262 | power_supply_unregister(&di->bat); | 267 | power_supply_unregister(di->bat); |
| 263 | 268 | ||
| 264 | iio_channel_release(di->channel_vbat); | 269 | iio_channel_release(di->channel_vbat); |
| 265 | iio_channel_release(di->channel_bsi); | 270 | iio_channel_release(di->channel_bsi); |
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index 5948ce058bdd..0ffe5cd3abf6 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #define JITTER_DELAY 500 /* ms */ | 28 | #define JITTER_DELAY 500 /* ms */ |
| 29 | 29 | ||
| 30 | struct s3c_adc_bat { | 30 | struct s3c_adc_bat { |
| 31 | struct power_supply psy; | 31 | struct power_supply *psy; |
| 32 | struct s3c_adc_client *client; | 32 | struct s3c_adc_client *client; |
| 33 | struct s3c_adc_bat_pdata *pdata; | 33 | struct s3c_adc_bat_pdata *pdata; |
| 34 | int volt_value; | 34 | int volt_value; |
| @@ -73,10 +73,10 @@ static int s3c_adc_backup_bat_get_property(struct power_supply *psy, | |||
| 73 | enum power_supply_property psp, | 73 | enum power_supply_property psp, |
| 74 | union power_supply_propval *val) | 74 | union power_supply_propval *val) |
| 75 | { | 75 | { |
| 76 | struct s3c_adc_bat *bat = container_of(psy, struct s3c_adc_bat, psy); | 76 | struct s3c_adc_bat *bat = power_supply_get_drvdata(psy); |
| 77 | 77 | ||
| 78 | if (!bat) { | 78 | if (!bat) { |
| 79 | dev_err(psy->dev, "%s: no battery infos ?!\n", __func__); | 79 | dev_err(&psy->dev, "%s: no battery infos ?!\n", __func__); |
| 80 | return -EINVAL; | 80 | return -EINVAL; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| @@ -105,17 +105,17 @@ static int s3c_adc_backup_bat_get_property(struct power_supply *psy, | |||
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static struct s3c_adc_bat backup_bat = { | 108 | static const struct power_supply_desc backup_bat_desc = { |
| 109 | .psy = { | 109 | .name = "backup-battery", |
| 110 | .name = "backup-battery", | 110 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 111 | .type = POWER_SUPPLY_TYPE_BATTERY, | 111 | .properties = s3c_adc_backup_bat_props, |
| 112 | .properties = s3c_adc_backup_bat_props, | 112 | .num_properties = ARRAY_SIZE(s3c_adc_backup_bat_props), |
| 113 | .num_properties = ARRAY_SIZE(s3c_adc_backup_bat_props), | 113 | .get_property = s3c_adc_backup_bat_get_property, |
| 114 | .get_property = s3c_adc_backup_bat_get_property, | 114 | .use_for_apm = 1, |
| 115 | .use_for_apm = 1, | ||
| 116 | }, | ||
| 117 | }; | 115 | }; |
| 118 | 116 | ||
| 117 | static struct s3c_adc_bat backup_bat; | ||
| 118 | |||
| 119 | static enum power_supply_property s3c_adc_main_bat_props[] = { | 119 | static enum power_supply_property s3c_adc_main_bat_props[] = { |
| 120 | POWER_SUPPLY_PROP_STATUS, | 120 | POWER_SUPPLY_PROP_STATUS, |
| 121 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | 121 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, |
| @@ -141,7 +141,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, | |||
| 141 | enum power_supply_property psp, | 141 | enum power_supply_property psp, |
| 142 | union power_supply_propval *val) | 142 | union power_supply_propval *val) |
| 143 | { | 143 | { |
| 144 | struct s3c_adc_bat *bat = container_of(psy, struct s3c_adc_bat, psy); | 144 | struct s3c_adc_bat *bat = power_supply_get_drvdata(psy); |
| 145 | 145 | ||
| 146 | int new_level; | 146 | int new_level; |
| 147 | int full_volt; | 147 | int full_volt; |
| @@ -149,7 +149,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, | |||
| 149 | unsigned int lut_size; | 149 | unsigned int lut_size; |
| 150 | 150 | ||
| 151 | if (!bat) { | 151 | if (!bat) { |
| 152 | dev_err(psy->dev, "no battery infos ?!\n"); | 152 | dev_err(&psy->dev, "no battery infos ?!\n"); |
| 153 | return -EINVAL; | 153 | return -EINVAL; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| @@ -232,18 +232,18 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, | |||
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static struct s3c_adc_bat main_bat = { | 235 | static const struct power_supply_desc main_bat_desc = { |
| 236 | .psy = { | 236 | .name = "main-battery", |
| 237 | .name = "main-battery", | 237 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 238 | .type = POWER_SUPPLY_TYPE_BATTERY, | 238 | .properties = s3c_adc_main_bat_props, |
| 239 | .properties = s3c_adc_main_bat_props, | 239 | .num_properties = ARRAY_SIZE(s3c_adc_main_bat_props), |
| 240 | .num_properties = ARRAY_SIZE(s3c_adc_main_bat_props), | 240 | .get_property = s3c_adc_bat_get_property, |
| 241 | .get_property = s3c_adc_bat_get_property, | 241 | .external_power_changed = s3c_adc_bat_ext_power_changed, |
| 242 | .external_power_changed = s3c_adc_bat_ext_power_changed, | 242 | .use_for_apm = 1, |
| 243 | .use_for_apm = 1, | ||
| 244 | }, | ||
| 245 | }; | 243 | }; |
| 246 | 244 | ||
| 245 | static struct s3c_adc_bat main_bat; | ||
| 246 | |||
| 247 | static void s3c_adc_bat_work(struct work_struct *work) | 247 | static void s3c_adc_bat_work(struct work_struct *work) |
| 248 | { | 248 | { |
| 249 | struct s3c_adc_bat *bat = &main_bat; | 249 | struct s3c_adc_bat *bat = &main_bat; |
| @@ -251,7 +251,7 @@ static void s3c_adc_bat_work(struct work_struct *work) | |||
| 251 | int is_plugged; | 251 | int is_plugged; |
| 252 | static int was_plugged; | 252 | static int was_plugged; |
| 253 | 253 | ||
| 254 | is_plugged = power_supply_am_i_supplied(&bat->psy); | 254 | is_plugged = power_supply_am_i_supplied(bat->psy); |
| 255 | bat->cable_plugged = is_plugged; | 255 | bat->cable_plugged = is_plugged; |
| 256 | if (is_plugged != was_plugged) { | 256 | if (is_plugged != was_plugged) { |
| 257 | was_plugged = is_plugged; | 257 | was_plugged = is_plugged; |
| @@ -279,7 +279,7 @@ static void s3c_adc_bat_work(struct work_struct *work) | |||
| 279 | } | 279 | } |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | power_supply_changed(&bat->psy); | 282 | power_supply_changed(bat->psy); |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id) | 285 | static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id) |
| @@ -310,16 +310,25 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) | |||
| 310 | main_bat.cable_plugged = 0; | 310 | main_bat.cable_plugged = 0; |
| 311 | main_bat.status = POWER_SUPPLY_STATUS_DISCHARGING; | 311 | main_bat.status = POWER_SUPPLY_STATUS_DISCHARGING; |
| 312 | 312 | ||
| 313 | ret = power_supply_register(&pdev->dev, &main_bat.psy); | 313 | main_bat.psy = power_supply_register(&pdev->dev, &main_bat_desc, NULL); |
| 314 | if (ret) | 314 | if (IS_ERR(main_bat.psy)) { |
| 315 | ret = PTR_ERR(main_bat.psy); | ||
| 315 | goto err_reg_main; | 316 | goto err_reg_main; |
| 317 | } | ||
| 316 | if (pdata->backup_volt_mult) { | 318 | if (pdata->backup_volt_mult) { |
| 319 | const struct power_supply_config psy_cfg | ||
| 320 | = { .drv_data = &backup_bat, }; | ||
| 321 | |||
| 317 | backup_bat.client = client; | 322 | backup_bat.client = client; |
| 318 | backup_bat.pdata = pdev->dev.platform_data; | 323 | backup_bat.pdata = pdev->dev.platform_data; |
| 319 | backup_bat.volt_value = -1; | 324 | backup_bat.volt_value = -1; |
| 320 | ret = power_supply_register(&pdev->dev, &backup_bat.psy); | 325 | backup_bat.psy = power_supply_register(&pdev->dev, |
| 321 | if (ret) | 326 | &backup_bat_desc, |
| 327 | &psy_cfg); | ||
| 328 | if (IS_ERR(backup_bat.psy)) { | ||
| 329 | ret = PTR_ERR(backup_bat.psy); | ||
| 322 | goto err_reg_backup; | 330 | goto err_reg_backup; |
| 331 | } | ||
| 323 | } | 332 | } |
| 324 | 333 | ||
| 325 | INIT_DELAYED_WORK(&bat_work, s3c_adc_bat_work); | 334 | INIT_DELAYED_WORK(&bat_work, s3c_adc_bat_work); |
| @@ -360,9 +369,9 @@ err_irq: | |||
| 360 | gpio_free(pdata->gpio_charge_finished); | 369 | gpio_free(pdata->gpio_charge_finished); |
| 361 | err_gpio: | 370 | err_gpio: |
| 362 | if (pdata->backup_volt_mult) | 371 | if (pdata->backup_volt_mult) |
| 363 | power_supply_unregister(&backup_bat.psy); | 372 | power_supply_unregister(backup_bat.psy); |
| 364 | err_reg_backup: | 373 | err_reg_backup: |
| 365 | power_supply_unregister(&main_bat.psy); | 374 | power_supply_unregister(main_bat.psy); |
| 366 | err_reg_main: | 375 | err_reg_main: |
| 367 | return ret; | 376 | return ret; |
| 368 | } | 377 | } |
| @@ -372,9 +381,9 @@ static int s3c_adc_bat_remove(struct platform_device *pdev) | |||
| 372 | struct s3c_adc_client *client = platform_get_drvdata(pdev); | 381 | struct s3c_adc_client *client = platform_get_drvdata(pdev); |
| 373 | struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; | 382 | struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; |
| 374 | 383 | ||
| 375 | power_supply_unregister(&main_bat.psy); | 384 | power_supply_unregister(main_bat.psy); |
| 376 | if (pdata->backup_volt_mult) | 385 | if (pdata->backup_volt_mult) |
| 377 | power_supply_unregister(&backup_bat.psy); | 386 | power_supply_unregister(backup_bat.psy); |
| 378 | 387 | ||
| 379 | s3c_adc_release(client); | 388 | s3c_adc_release(client); |
| 380 | 389 | ||
diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c index c7b7b4018df3..de1178659d4b 100644 --- a/drivers/power/sbs-battery.c +++ b/drivers/power/sbs-battery.c | |||
| @@ -156,7 +156,7 @@ static enum power_supply_property sbs_properties[] = { | |||
| 156 | 156 | ||
| 157 | struct sbs_info { | 157 | struct sbs_info { |
| 158 | struct i2c_client *client; | 158 | struct i2c_client *client; |
| 159 | struct power_supply power_supply; | 159 | struct power_supply *power_supply; |
| 160 | struct sbs_platform_data *pdata; | 160 | struct sbs_platform_data *pdata; |
| 161 | bool is_present; | 161 | bool is_present; |
| 162 | bool gpio_detect; | 162 | bool gpio_detect; |
| @@ -391,7 +391,7 @@ static int sbs_get_battery_property(struct i2c_client *client, | |||
| 391 | chip->last_state = val->intval; | 391 | chip->last_state = val->intval; |
| 392 | else if (chip->last_state != val->intval) { | 392 | else if (chip->last_state != val->intval) { |
| 393 | cancel_delayed_work_sync(&chip->work); | 393 | cancel_delayed_work_sync(&chip->work); |
| 394 | power_supply_changed(&chip->power_supply); | 394 | power_supply_changed(chip->power_supply); |
| 395 | chip->poll_time = 0; | 395 | chip->poll_time = 0; |
| 396 | } | 396 | } |
| 397 | } else { | 397 | } else { |
| @@ -556,8 +556,7 @@ static int sbs_get_property(struct power_supply *psy, | |||
| 556 | union power_supply_propval *val) | 556 | union power_supply_propval *val) |
| 557 | { | 557 | { |
| 558 | int ret = 0; | 558 | int ret = 0; |
| 559 | struct sbs_info *chip = container_of(psy, | 559 | struct sbs_info *chip = power_supply_get_drvdata(psy); |
| 560 | struct sbs_info, power_supply); | ||
| 561 | struct i2c_client *client = chip->client; | 560 | struct i2c_client *client = chip->client; |
| 562 | 561 | ||
| 563 | switch (psp) { | 562 | switch (psp) { |
| @@ -638,7 +637,7 @@ static int sbs_get_property(struct power_supply *psy, | |||
| 638 | if (!chip->gpio_detect && | 637 | if (!chip->gpio_detect && |
| 639 | chip->is_present != (ret >= 0)) { | 638 | chip->is_present != (ret >= 0)) { |
| 640 | chip->is_present = (ret >= 0); | 639 | chip->is_present = (ret >= 0); |
| 641 | power_supply_changed(&chip->power_supply); | 640 | power_supply_changed(chip->power_supply); |
| 642 | } | 641 | } |
| 643 | 642 | ||
| 644 | done: | 643 | done: |
| @@ -671,9 +670,7 @@ static irqreturn_t sbs_irq(int irq, void *devid) | |||
| 671 | 670 | ||
| 672 | static void sbs_external_power_changed(struct power_supply *psy) | 671 | static void sbs_external_power_changed(struct power_supply *psy) |
| 673 | { | 672 | { |
| 674 | struct sbs_info *chip; | 673 | struct sbs_info *chip = power_supply_get_drvdata(psy); |
| 675 | |||
| 676 | chip = container_of(psy, struct sbs_info, power_supply); | ||
| 677 | 674 | ||
| 678 | if (chip->ignore_changes > 0) { | 675 | if (chip->ignore_changes > 0) { |
| 679 | chip->ignore_changes--; | 676 | chip->ignore_changes--; |
| @@ -712,7 +709,7 @@ static void sbs_delayed_work(struct work_struct *work) | |||
| 712 | 709 | ||
| 713 | if (chip->last_state != ret) { | 710 | if (chip->last_state != ret) { |
| 714 | chip->poll_time = 0; | 711 | chip->poll_time = 0; |
| 715 | power_supply_changed(&chip->power_supply); | 712 | power_supply_changed(chip->power_supply); |
| 716 | return; | 713 | return; |
| 717 | } | 714 | } |
| 718 | if (chip->poll_time > 0) { | 715 | if (chip->poll_time > 0) { |
| @@ -796,42 +793,48 @@ static struct sbs_platform_data *sbs_of_populate_pdata( | |||
| 796 | } | 793 | } |
| 797 | #endif | 794 | #endif |
| 798 | 795 | ||
| 796 | static const struct power_supply_desc sbs_default_desc = { | ||
| 797 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 798 | .properties = sbs_properties, | ||
| 799 | .num_properties = ARRAY_SIZE(sbs_properties), | ||
| 800 | .get_property = sbs_get_property, | ||
| 801 | .external_power_changed = sbs_external_power_changed, | ||
| 802 | }; | ||
| 803 | |||
| 799 | static int sbs_probe(struct i2c_client *client, | 804 | static int sbs_probe(struct i2c_client *client, |
| 800 | const struct i2c_device_id *id) | 805 | const struct i2c_device_id *id) |
| 801 | { | 806 | { |
| 802 | struct sbs_info *chip; | 807 | struct sbs_info *chip; |
| 808 | struct power_supply_desc *sbs_desc; | ||
| 803 | struct sbs_platform_data *pdata = client->dev.platform_data; | 809 | struct sbs_platform_data *pdata = client->dev.platform_data; |
| 810 | struct power_supply_config psy_cfg = {}; | ||
| 804 | int rc; | 811 | int rc; |
| 805 | int irq; | 812 | int irq; |
| 806 | char *name; | ||
| 807 | 813 | ||
| 808 | name = kasprintf(GFP_KERNEL, "sbs-%s", dev_name(&client->dev)); | 814 | sbs_desc = devm_kmemdup(&client->dev, &sbs_default_desc, |
| 809 | if (!name) { | 815 | sizeof(*sbs_desc), GFP_KERNEL); |
| 810 | dev_err(&client->dev, "Failed to allocate device name\n"); | 816 | if (!sbs_desc) |
| 817 | return -ENOMEM; | ||
| 818 | |||
| 819 | sbs_desc->name = devm_kasprintf(&client->dev, GFP_KERNEL, "sbs-%s", | ||
| 820 | dev_name(&client->dev)); | ||
| 821 | if (!sbs_desc->name) | ||
| 811 | return -ENOMEM; | 822 | return -ENOMEM; |
| 812 | } | ||
| 813 | 823 | ||
| 814 | chip = kzalloc(sizeof(struct sbs_info), GFP_KERNEL); | 824 | chip = kzalloc(sizeof(struct sbs_info), GFP_KERNEL); |
| 815 | if (!chip) { | 825 | if (!chip) |
| 816 | rc = -ENOMEM; | 826 | return -ENOMEM; |
| 817 | goto exit_free_name; | ||
| 818 | } | ||
| 819 | 827 | ||
| 820 | chip->client = client; | 828 | chip->client = client; |
| 821 | chip->enable_detection = false; | 829 | chip->enable_detection = false; |
| 822 | chip->gpio_detect = false; | 830 | chip->gpio_detect = false; |
| 823 | chip->power_supply.name = name; | 831 | psy_cfg.of_node = client->dev.of_node; |
| 824 | chip->power_supply.type = POWER_SUPPLY_TYPE_BATTERY; | 832 | psy_cfg.drv_data = chip; |
| 825 | chip->power_supply.properties = sbs_properties; | ||
| 826 | chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties); | ||
| 827 | chip->power_supply.get_property = sbs_get_property; | ||
| 828 | chip->power_supply.of_node = client->dev.of_node; | ||
| 829 | /* ignore first notification of external change, it is generated | 833 | /* ignore first notification of external change, it is generated |
| 830 | * from the power_supply_register call back | 834 | * from the power_supply_register call back |
| 831 | */ | 835 | */ |
| 832 | chip->ignore_changes = 1; | 836 | chip->ignore_changes = 1; |
| 833 | chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; | 837 | chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; |
| 834 | chip->power_supply.external_power_changed = sbs_external_power_changed; | ||
| 835 | 838 | ||
| 836 | pdata = sbs_of_populate_pdata(client); | 839 | pdata = sbs_of_populate_pdata(client); |
| 837 | 840 | ||
| @@ -870,7 +873,7 @@ static int sbs_probe(struct i2c_client *client, | |||
| 870 | 873 | ||
| 871 | rc = request_irq(irq, sbs_irq, | 874 | rc = request_irq(irq, sbs_irq, |
| 872 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 875 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 873 | dev_name(&client->dev), &chip->power_supply); | 876 | dev_name(&client->dev), chip->power_supply); |
| 874 | if (rc) { | 877 | if (rc) { |
| 875 | dev_warn(&client->dev, "Failed to request irq: %d\n", rc); | 878 | dev_warn(&client->dev, "Failed to request irq: %d\n", rc); |
| 876 | gpio_free(pdata->battery_detect); | 879 | gpio_free(pdata->battery_detect); |
| @@ -892,10 +895,12 @@ skip_gpio: | |||
| 892 | goto exit_psupply; | 895 | goto exit_psupply; |
| 893 | } | 896 | } |
| 894 | 897 | ||
| 895 | rc = power_supply_register(&client->dev, &chip->power_supply); | 898 | chip->power_supply = power_supply_register(&client->dev, sbs_desc, |
| 896 | if (rc) { | 899 | &psy_cfg); |
| 900 | if (IS_ERR(chip->power_supply)) { | ||
| 897 | dev_err(&client->dev, | 901 | dev_err(&client->dev, |
| 898 | "%s: Failed to register power supply\n", __func__); | 902 | "%s: Failed to register power supply\n", __func__); |
| 903 | rc = PTR_ERR(chip->power_supply); | ||
| 899 | goto exit_psupply; | 904 | goto exit_psupply; |
| 900 | } | 905 | } |
| 901 | 906 | ||
| @@ -910,15 +915,12 @@ skip_gpio: | |||
| 910 | 915 | ||
| 911 | exit_psupply: | 916 | exit_psupply: |
| 912 | if (chip->irq) | 917 | if (chip->irq) |
| 913 | free_irq(chip->irq, &chip->power_supply); | 918 | free_irq(chip->irq, chip->power_supply); |
| 914 | if (chip->gpio_detect) | 919 | if (chip->gpio_detect) |
| 915 | gpio_free(pdata->battery_detect); | 920 | gpio_free(pdata->battery_detect); |
| 916 | 921 | ||
| 917 | kfree(chip); | 922 | kfree(chip); |
| 918 | 923 | ||
| 919 | exit_free_name: | ||
| 920 | kfree(name); | ||
| 921 | |||
| 922 | return rc; | 924 | return rc; |
| 923 | } | 925 | } |
| 924 | 926 | ||
| @@ -927,15 +929,14 @@ static int sbs_remove(struct i2c_client *client) | |||
| 927 | struct sbs_info *chip = i2c_get_clientdata(client); | 929 | struct sbs_info *chip = i2c_get_clientdata(client); |
| 928 | 930 | ||
| 929 | if (chip->irq) | 931 | if (chip->irq) |
| 930 | free_irq(chip->irq, &chip->power_supply); | 932 | free_irq(chip->irq, chip->power_supply); |
| 931 | if (chip->gpio_detect) | 933 | if (chip->gpio_detect) |
| 932 | gpio_free(chip->pdata->battery_detect); | 934 | gpio_free(chip->pdata->battery_detect); |
| 933 | 935 | ||
| 934 | power_supply_unregister(&chip->power_supply); | 936 | power_supply_unregister(chip->power_supply); |
| 935 | 937 | ||
| 936 | cancel_delayed_work_sync(&chip->work); | 938 | cancel_delayed_work_sync(&chip->work); |
| 937 | 939 | ||
| 938 | kfree(chip->power_supply.name); | ||
| 939 | kfree(chip); | 940 | kfree(chip); |
| 940 | chip = NULL; | 941 | chip = NULL; |
| 941 | 942 | ||
diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c index acf84e80fe98..0b60a0b5878b 100644 --- a/drivers/power/smb347-charger.c +++ b/drivers/power/smb347-charger.c | |||
| @@ -139,9 +139,9 @@ struct smb347_charger { | |||
| 139 | struct mutex lock; | 139 | struct mutex lock; |
| 140 | struct device *dev; | 140 | struct device *dev; |
| 141 | struct regmap *regmap; | 141 | struct regmap *regmap; |
| 142 | struct power_supply mains; | 142 | struct power_supply *mains; |
| 143 | struct power_supply usb; | 143 | struct power_supply *usb; |
| 144 | struct power_supply battery; | 144 | struct power_supply *battery; |
| 145 | bool mains_online; | 145 | bool mains_online; |
| 146 | bool usb_online; | 146 | bool usb_online; |
| 147 | bool charging_enabled; | 147 | bool charging_enabled; |
| @@ -741,7 +741,7 @@ static irqreturn_t smb347_interrupt(int irq, void *data) | |||
| 741 | */ | 741 | */ |
| 742 | if (stat_c & STAT_C_CHARGER_ERROR) { | 742 | if (stat_c & STAT_C_CHARGER_ERROR) { |
| 743 | dev_err(smb->dev, "charging stopped due to charger error\n"); | 743 | dev_err(smb->dev, "charging stopped due to charger error\n"); |
| 744 | power_supply_changed(&smb->battery); | 744 | power_supply_changed(smb->battery); |
| 745 | handled = true; | 745 | handled = true; |
| 746 | } | 746 | } |
| 747 | 747 | ||
| @@ -752,7 +752,7 @@ static irqreturn_t smb347_interrupt(int irq, void *data) | |||
| 752 | */ | 752 | */ |
| 753 | if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { | 753 | if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { |
| 754 | if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) | 754 | if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) |
| 755 | power_supply_changed(&smb->battery); | 755 | power_supply_changed(smb->battery); |
| 756 | dev_dbg(smb->dev, "going to HW maintenance mode\n"); | 756 | dev_dbg(smb->dev, "going to HW maintenance mode\n"); |
| 757 | handled = true; | 757 | handled = true; |
| 758 | } | 758 | } |
| @@ -766,7 +766,7 @@ static irqreturn_t smb347_interrupt(int irq, void *data) | |||
| 766 | 766 | ||
| 767 | if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT) | 767 | if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT) |
| 768 | dev_warn(smb->dev, "charging stopped due to timeout\n"); | 768 | dev_warn(smb->dev, "charging stopped due to timeout\n"); |
| 769 | power_supply_changed(&smb->battery); | 769 | power_supply_changed(smb->battery); |
| 770 | handled = true; | 770 | handled = true; |
| 771 | } | 771 | } |
| 772 | 772 | ||
| @@ -778,9 +778,9 @@ static irqreturn_t smb347_interrupt(int irq, void *data) | |||
| 778 | if (smb347_update_ps_status(smb) > 0) { | 778 | if (smb347_update_ps_status(smb) > 0) { |
| 779 | smb347_start_stop_charging(smb); | 779 | smb347_start_stop_charging(smb); |
| 780 | if (smb->pdata->use_mains) | 780 | if (smb->pdata->use_mains) |
| 781 | power_supply_changed(&smb->mains); | 781 | power_supply_changed(smb->mains); |
| 782 | if (smb->pdata->use_usb) | 782 | if (smb->pdata->use_usb) |
| 783 | power_supply_changed(&smb->usb); | 783 | power_supply_changed(smb->usb); |
| 784 | } | 784 | } |
| 785 | handled = true; | 785 | handled = true; |
| 786 | } | 786 | } |
| @@ -842,7 +842,8 @@ static int smb347_irq_init(struct smb347_charger *smb, | |||
| 842 | goto fail; | 842 | goto fail; |
| 843 | 843 | ||
| 844 | ret = request_threaded_irq(irq, NULL, smb347_interrupt, | 844 | ret = request_threaded_irq(irq, NULL, smb347_interrupt, |
| 845 | IRQF_TRIGGER_FALLING, client->name, smb); | 845 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
| 846 | client->name, smb); | ||
| 846 | if (ret < 0) | 847 | if (ret < 0) |
| 847 | goto fail_gpio; | 848 | goto fail_gpio; |
| 848 | 849 | ||
| @@ -934,8 +935,7 @@ static int smb347_mains_get_property(struct power_supply *psy, | |||
| 934 | enum power_supply_property prop, | 935 | enum power_supply_property prop, |
| 935 | union power_supply_propval *val) | 936 | union power_supply_propval *val) |
| 936 | { | 937 | { |
| 937 | struct smb347_charger *smb = | 938 | struct smb347_charger *smb = power_supply_get_drvdata(psy); |
| 938 | container_of(psy, struct smb347_charger, mains); | ||
| 939 | int ret; | 939 | int ret; |
| 940 | 940 | ||
| 941 | switch (prop) { | 941 | switch (prop) { |
| @@ -976,8 +976,7 @@ static int smb347_usb_get_property(struct power_supply *psy, | |||
| 976 | enum power_supply_property prop, | 976 | enum power_supply_property prop, |
| 977 | union power_supply_propval *val) | 977 | union power_supply_propval *val) |
| 978 | { | 978 | { |
| 979 | struct smb347_charger *smb = | 979 | struct smb347_charger *smb = power_supply_get_drvdata(psy); |
| 980 | container_of(psy, struct smb347_charger, usb); | ||
| 981 | int ret; | 980 | int ret; |
| 982 | 981 | ||
| 983 | switch (prop) { | 982 | switch (prop) { |
| @@ -1063,8 +1062,7 @@ static int smb347_battery_get_property(struct power_supply *psy, | |||
| 1063 | enum power_supply_property prop, | 1062 | enum power_supply_property prop, |
| 1064 | union power_supply_propval *val) | 1063 | union power_supply_propval *val) |
| 1065 | { | 1064 | { |
| 1066 | struct smb347_charger *smb = | 1065 | struct smb347_charger *smb = power_supply_get_drvdata(psy); |
| 1067 | container_of(psy, struct smb347_charger, battery); | ||
| 1068 | const struct smb347_charger_platform_data *pdata = smb->pdata; | 1066 | const struct smb347_charger_platform_data *pdata = smb->pdata; |
| 1069 | int ret; | 1067 | int ret; |
| 1070 | 1068 | ||
| @@ -1188,11 +1186,36 @@ static const struct regmap_config smb347_regmap = { | |||
| 1188 | .readable_reg = smb347_readable_reg, | 1186 | .readable_reg = smb347_readable_reg, |
| 1189 | }; | 1187 | }; |
| 1190 | 1188 | ||
| 1189 | static const struct power_supply_desc smb347_mains_desc = { | ||
| 1190 | .name = "smb347-mains", | ||
| 1191 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 1192 | .get_property = smb347_mains_get_property, | ||
| 1193 | .properties = smb347_mains_properties, | ||
| 1194 | .num_properties = ARRAY_SIZE(smb347_mains_properties), | ||
| 1195 | }; | ||
| 1196 | |||
| 1197 | static const struct power_supply_desc smb347_usb_desc = { | ||
| 1198 | .name = "smb347-usb", | ||
| 1199 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 1200 | .get_property = smb347_usb_get_property, | ||
| 1201 | .properties = smb347_usb_properties, | ||
| 1202 | .num_properties = ARRAY_SIZE(smb347_usb_properties), | ||
| 1203 | }; | ||
| 1204 | |||
| 1205 | static const struct power_supply_desc smb347_battery_desc = { | ||
| 1206 | .name = "smb347-battery", | ||
| 1207 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 1208 | .get_property = smb347_battery_get_property, | ||
| 1209 | .properties = smb347_battery_properties, | ||
| 1210 | .num_properties = ARRAY_SIZE(smb347_battery_properties), | ||
| 1211 | }; | ||
| 1212 | |||
| 1191 | static int smb347_probe(struct i2c_client *client, | 1213 | static int smb347_probe(struct i2c_client *client, |
| 1192 | const struct i2c_device_id *id) | 1214 | const struct i2c_device_id *id) |
| 1193 | { | 1215 | { |
| 1194 | static char *battery[] = { "smb347-battery" }; | 1216 | static char *battery[] = { "smb347-battery" }; |
| 1195 | const struct smb347_charger_platform_data *pdata; | 1217 | const struct smb347_charger_platform_data *pdata; |
| 1218 | struct power_supply_config mains_usb_cfg = {}, battery_cfg = {}; | ||
| 1196 | struct device *dev = &client->dev; | 1219 | struct device *dev = &client->dev; |
| 1197 | struct smb347_charger *smb; | 1220 | struct smb347_charger *smb; |
| 1198 | int ret; | 1221 | int ret; |
| @@ -1222,49 +1245,35 @@ static int smb347_probe(struct i2c_client *client, | |||
| 1222 | if (ret < 0) | 1245 | if (ret < 0) |
| 1223 | return ret; | 1246 | return ret; |
| 1224 | 1247 | ||
| 1248 | mains_usb_cfg.supplied_to = battery; | ||
| 1249 | mains_usb_cfg.num_supplicants = ARRAY_SIZE(battery); | ||
| 1250 | mains_usb_cfg.drv_data = smb; | ||
| 1225 | if (smb->pdata->use_mains) { | 1251 | if (smb->pdata->use_mains) { |
| 1226 | smb->mains.name = "smb347-mains"; | 1252 | smb->mains = power_supply_register(dev, &smb347_mains_desc, |
| 1227 | smb->mains.type = POWER_SUPPLY_TYPE_MAINS; | 1253 | &mains_usb_cfg); |
| 1228 | smb->mains.get_property = smb347_mains_get_property; | 1254 | if (IS_ERR(smb->mains)) |
| 1229 | smb->mains.properties = smb347_mains_properties; | 1255 | return PTR_ERR(smb->mains); |
| 1230 | smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties); | ||
| 1231 | smb->mains.supplied_to = battery; | ||
| 1232 | smb->mains.num_supplicants = ARRAY_SIZE(battery); | ||
| 1233 | ret = power_supply_register(dev, &smb->mains); | ||
| 1234 | if (ret < 0) | ||
| 1235 | return ret; | ||
| 1236 | } | 1256 | } |
| 1237 | 1257 | ||
| 1238 | if (smb->pdata->use_usb) { | 1258 | if (smb->pdata->use_usb) { |
| 1239 | smb->usb.name = "smb347-usb"; | 1259 | smb->usb = power_supply_register(dev, &smb347_usb_desc, |
| 1240 | smb->usb.type = POWER_SUPPLY_TYPE_USB; | 1260 | &mains_usb_cfg); |
| 1241 | smb->usb.get_property = smb347_usb_get_property; | 1261 | if (IS_ERR(smb->usb)) { |
| 1242 | smb->usb.properties = smb347_usb_properties; | ||
| 1243 | smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties); | ||
| 1244 | smb->usb.supplied_to = battery; | ||
| 1245 | smb->usb.num_supplicants = ARRAY_SIZE(battery); | ||
| 1246 | ret = power_supply_register(dev, &smb->usb); | ||
| 1247 | if (ret < 0) { | ||
| 1248 | if (smb->pdata->use_mains) | 1262 | if (smb->pdata->use_mains) |
| 1249 | power_supply_unregister(&smb->mains); | 1263 | power_supply_unregister(smb->mains); |
| 1250 | return ret; | 1264 | return PTR_ERR(smb->usb); |
| 1251 | } | 1265 | } |
| 1252 | } | 1266 | } |
| 1253 | 1267 | ||
| 1254 | smb->battery.name = "smb347-battery"; | 1268 | battery_cfg.drv_data = smb; |
| 1255 | smb->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 1269 | smb->battery = power_supply_register(dev, &smb347_battery_desc, |
| 1256 | smb->battery.get_property = smb347_battery_get_property; | 1270 | &battery_cfg); |
| 1257 | smb->battery.properties = smb347_battery_properties; | 1271 | if (IS_ERR(smb->battery)) { |
| 1258 | smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties); | ||
| 1259 | |||
| 1260 | |||
| 1261 | ret = power_supply_register(dev, &smb->battery); | ||
| 1262 | if (ret < 0) { | ||
| 1263 | if (smb->pdata->use_usb) | 1272 | if (smb->pdata->use_usb) |
| 1264 | power_supply_unregister(&smb->usb); | 1273 | power_supply_unregister(smb->usb); |
| 1265 | if (smb->pdata->use_mains) | 1274 | if (smb->pdata->use_mains) |
| 1266 | power_supply_unregister(&smb->mains); | 1275 | power_supply_unregister(smb->mains); |
| 1267 | return ret; | 1276 | return PTR_ERR(smb->battery); |
| 1268 | } | 1277 | } |
| 1269 | 1278 | ||
| 1270 | /* | 1279 | /* |
| @@ -1294,11 +1303,11 @@ static int smb347_remove(struct i2c_client *client) | |||
| 1294 | gpio_free(smb->pdata->irq_gpio); | 1303 | gpio_free(smb->pdata->irq_gpio); |
| 1295 | } | 1304 | } |
| 1296 | 1305 | ||
| 1297 | power_supply_unregister(&smb->battery); | 1306 | power_supply_unregister(smb->battery); |
| 1298 | if (smb->pdata->use_usb) | 1307 | if (smb->pdata->use_usb) |
| 1299 | power_supply_unregister(&smb->usb); | 1308 | power_supply_unregister(smb->usb); |
| 1300 | if (smb->pdata->use_mains) | 1309 | if (smb->pdata->use_mains) |
| 1301 | power_supply_unregister(&smb->mains); | 1310 | power_supply_unregister(smb->mains); |
| 1302 | return 0; | 1311 | return 0; |
| 1303 | } | 1312 | } |
| 1304 | 1313 | ||
diff --git a/drivers/power/test_power.c b/drivers/power/test_power.c index f26b1fa00fe1..f986e0cca7ac 100644 --- a/drivers/power/test_power.c +++ b/drivers/power/test_power.c | |||
| @@ -153,12 +153,12 @@ static char *test_power_ac_supplied_to[] = { | |||
| 153 | "test_battery", | 153 | "test_battery", |
| 154 | }; | 154 | }; |
| 155 | 155 | ||
| 156 | static struct power_supply test_power_supplies[] = { | 156 | static struct power_supply *test_power_supplies[TEST_POWER_NUM]; |
| 157 | |||
| 158 | static const struct power_supply_desc test_power_desc[] = { | ||
| 157 | [TEST_AC] = { | 159 | [TEST_AC] = { |
| 158 | .name = "test_ac", | 160 | .name = "test_ac", |
| 159 | .type = POWER_SUPPLY_TYPE_MAINS, | 161 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 160 | .supplied_to = test_power_ac_supplied_to, | ||
| 161 | .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), | ||
| 162 | .properties = test_power_ac_props, | 162 | .properties = test_power_ac_props, |
| 163 | .num_properties = ARRAY_SIZE(test_power_ac_props), | 163 | .num_properties = ARRAY_SIZE(test_power_ac_props), |
| 164 | .get_property = test_power_get_ac_property, | 164 | .get_property = test_power_get_ac_property, |
| @@ -173,14 +173,25 @@ static struct power_supply test_power_supplies[] = { | |||
| 173 | [TEST_USB] = { | 173 | [TEST_USB] = { |
| 174 | .name = "test_usb", | 174 | .name = "test_usb", |
| 175 | .type = POWER_SUPPLY_TYPE_USB, | 175 | .type = POWER_SUPPLY_TYPE_USB, |
| 176 | .supplied_to = test_power_ac_supplied_to, | ||
| 177 | .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), | ||
| 178 | .properties = test_power_ac_props, | 176 | .properties = test_power_ac_props, |
| 179 | .num_properties = ARRAY_SIZE(test_power_ac_props), | 177 | .num_properties = ARRAY_SIZE(test_power_ac_props), |
| 180 | .get_property = test_power_get_usb_property, | 178 | .get_property = test_power_get_usb_property, |
| 181 | }, | 179 | }, |
| 182 | }; | 180 | }; |
| 183 | 181 | ||
| 182 | static const struct power_supply_config test_power_configs[] = { | ||
| 183 | { | ||
| 184 | /* test_ac */ | ||
| 185 | .supplied_to = test_power_ac_supplied_to, | ||
| 186 | .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), | ||
| 187 | }, { | ||
| 188 | /* test_battery */ | ||
| 189 | }, { | ||
| 190 | /* test_usb */ | ||
| 191 | .supplied_to = test_power_ac_supplied_to, | ||
| 192 | .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), | ||
| 193 | }, | ||
| 194 | }; | ||
| 184 | 195 | ||
| 185 | static int __init test_power_init(void) | 196 | static int __init test_power_init(void) |
| 186 | { | 197 | { |
| @@ -188,12 +199,16 @@ static int __init test_power_init(void) | |||
| 188 | int ret; | 199 | int ret; |
| 189 | 200 | ||
| 190 | BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); | 201 | BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); |
| 202 | BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs)); | ||
| 191 | 203 | ||
| 192 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { | 204 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { |
| 193 | ret = power_supply_register(NULL, &test_power_supplies[i]); | 205 | test_power_supplies[i] = power_supply_register(NULL, |
| 194 | if (ret) { | 206 | &test_power_desc[i], |
| 207 | &test_power_configs[i]); | ||
| 208 | if (IS_ERR(test_power_supplies[i])) { | ||
| 195 | pr_err("%s: failed to register %s\n", __func__, | 209 | pr_err("%s: failed to register %s\n", __func__, |
| 196 | test_power_supplies[i].name); | 210 | test_power_desc[i].name); |
| 211 | ret = PTR_ERR(test_power_supplies[i]); | ||
| 197 | goto failed; | 212 | goto failed; |
| 198 | } | 213 | } |
| 199 | } | 214 | } |
| @@ -202,7 +217,7 @@ static int __init test_power_init(void) | |||
| 202 | return 0; | 217 | return 0; |
| 203 | failed: | 218 | failed: |
| 204 | while (--i >= 0) | 219 | while (--i >= 0) |
| 205 | power_supply_unregister(&test_power_supplies[i]); | 220 | power_supply_unregister(test_power_supplies[i]); |
| 206 | return ret; | 221 | return ret; |
| 207 | } | 222 | } |
| 208 | module_init(test_power_init); | 223 | module_init(test_power_init); |
| @@ -216,13 +231,13 @@ static void __exit test_power_exit(void) | |||
| 216 | usb_online = 0; | 231 | usb_online = 0; |
| 217 | battery_status = POWER_SUPPLY_STATUS_DISCHARGING; | 232 | battery_status = POWER_SUPPLY_STATUS_DISCHARGING; |
| 218 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) | 233 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) |
| 219 | power_supply_changed(&test_power_supplies[i]); | 234 | power_supply_changed(test_power_supplies[i]); |
| 220 | pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", | 235 | pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", |
| 221 | __func__); | 236 | __func__); |
| 222 | ssleep(10); | 237 | ssleep(10); |
| 223 | 238 | ||
| 224 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) | 239 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) |
| 225 | power_supply_unregister(&test_power_supplies[i]); | 240 | power_supply_unregister(test_power_supplies[i]); |
| 226 | 241 | ||
| 227 | module_initialized = false; | 242 | module_initialized = false; |
| 228 | } | 243 | } |
| @@ -320,7 +335,7 @@ static inline void signal_power_supply_changed(struct power_supply *psy) | |||
| 320 | static int param_set_ac_online(const char *key, const struct kernel_param *kp) | 335 | static int param_set_ac_online(const char *key, const struct kernel_param *kp) |
| 321 | { | 336 | { |
| 322 | ac_online = map_get_value(map_ac_online, key, ac_online); | 337 | ac_online = map_get_value(map_ac_online, key, ac_online); |
| 323 | signal_power_supply_changed(&test_power_supplies[TEST_AC]); | 338 | signal_power_supply_changed(test_power_supplies[TEST_AC]); |
| 324 | return 0; | 339 | return 0; |
| 325 | } | 340 | } |
| 326 | 341 | ||
| @@ -333,7 +348,7 @@ static int param_get_ac_online(char *buffer, const struct kernel_param *kp) | |||
| 333 | static int param_set_usb_online(const char *key, const struct kernel_param *kp) | 348 | static int param_set_usb_online(const char *key, const struct kernel_param *kp) |
| 334 | { | 349 | { |
| 335 | usb_online = map_get_value(map_ac_online, key, usb_online); | 350 | usb_online = map_get_value(map_ac_online, key, usb_online); |
| 336 | signal_power_supply_changed(&test_power_supplies[TEST_USB]); | 351 | signal_power_supply_changed(test_power_supplies[TEST_USB]); |
| 337 | return 0; | 352 | return 0; |
| 338 | } | 353 | } |
| 339 | 354 | ||
| @@ -347,7 +362,7 @@ static int param_set_battery_status(const char *key, | |||
| 347 | const struct kernel_param *kp) | 362 | const struct kernel_param *kp) |
| 348 | { | 363 | { |
| 349 | battery_status = map_get_value(map_status, key, battery_status); | 364 | battery_status = map_get_value(map_status, key, battery_status); |
| 350 | signal_power_supply_changed(&test_power_supplies[TEST_BATTERY]); | 365 | signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); |
| 351 | return 0; | 366 | return 0; |
| 352 | } | 367 | } |
| 353 | 368 | ||
| @@ -361,7 +376,7 @@ static int param_set_battery_health(const char *key, | |||
| 361 | const struct kernel_param *kp) | 376 | const struct kernel_param *kp) |
| 362 | { | 377 | { |
| 363 | battery_health = map_get_value(map_health, key, battery_health); | 378 | battery_health = map_get_value(map_health, key, battery_health); |
| 364 | signal_power_supply_changed(&test_power_supplies[TEST_BATTERY]); | 379 | signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); |
| 365 | return 0; | 380 | return 0; |
| 366 | } | 381 | } |
| 367 | 382 | ||
| @@ -375,7 +390,7 @@ static int param_set_battery_present(const char *key, | |||
| 375 | const struct kernel_param *kp) | 390 | const struct kernel_param *kp) |
| 376 | { | 391 | { |
| 377 | battery_present = map_get_value(map_present, key, battery_present); | 392 | battery_present = map_get_value(map_present, key, battery_present); |
| 378 | signal_power_supply_changed(&test_power_supplies[TEST_AC]); | 393 | signal_power_supply_changed(test_power_supplies[TEST_AC]); |
| 379 | return 0; | 394 | return 0; |
| 380 | } | 395 | } |
| 381 | 396 | ||
| @@ -391,7 +406,7 @@ static int param_set_battery_technology(const char *key, | |||
| 391 | { | 406 | { |
| 392 | battery_technology = map_get_value(map_technology, key, | 407 | battery_technology = map_get_value(map_technology, key, |
| 393 | battery_technology); | 408 | battery_technology); |
| 394 | signal_power_supply_changed(&test_power_supplies[TEST_BATTERY]); | 409 | signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); |
| 395 | return 0; | 410 | return 0; |
| 396 | } | 411 | } |
| 397 | 412 | ||
| @@ -412,7 +427,7 @@ static int param_set_battery_capacity(const char *key, | |||
| 412 | return -EINVAL; | 427 | return -EINVAL; |
| 413 | 428 | ||
| 414 | battery_capacity = tmp; | 429 | battery_capacity = tmp; |
| 415 | signal_power_supply_changed(&test_power_supplies[TEST_BATTERY]); | 430 | signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); |
| 416 | return 0; | 431 | return 0; |
| 417 | } | 432 | } |
| 418 | 433 | ||
| @@ -427,7 +442,7 @@ static int param_set_battery_voltage(const char *key, | |||
| 427 | return -EINVAL; | 442 | return -EINVAL; |
| 428 | 443 | ||
| 429 | battery_voltage = tmp; | 444 | battery_voltage = tmp; |
| 430 | signal_power_supply_changed(&test_power_supplies[TEST_BATTERY]); | 445 | signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); |
| 431 | return 0; | 446 | return 0; |
| 432 | } | 447 | } |
| 433 | 448 | ||
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c index f4d80df627c7..6e88c1b37945 100644 --- a/drivers/power/tosa_battery.c +++ b/drivers/power/tosa_battery.c | |||
| @@ -26,7 +26,7 @@ static struct work_struct bat_work; | |||
| 26 | 26 | ||
| 27 | struct tosa_bat { | 27 | struct tosa_bat { |
| 28 | int status; | 28 | int status; |
| 29 | struct power_supply psy; | 29 | struct power_supply *psy; |
| 30 | int full_chrg; | 30 | int full_chrg; |
| 31 | 31 | ||
| 32 | struct mutex work_lock; /* protects data */ | 32 | struct mutex work_lock; /* protects data */ |
| @@ -61,7 +61,7 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat) | |||
| 61 | mutex_lock(&bat_lock); | 61 | mutex_lock(&bat_lock); |
| 62 | gpio_set_value(bat->gpio_bat, 1); | 62 | gpio_set_value(bat->gpio_bat, 1); |
| 63 | msleep(5); | 63 | msleep(5); |
| 64 | value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy.dev->parent), | 64 | value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent), |
| 65 | bat->adc_bat); | 65 | bat->adc_bat); |
| 66 | gpio_set_value(bat->gpio_bat, 0); | 66 | gpio_set_value(bat->gpio_bat, 0); |
| 67 | mutex_unlock(&bat_lock); | 67 | mutex_unlock(&bat_lock); |
| @@ -81,7 +81,7 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat) | |||
| 81 | mutex_lock(&bat_lock); | 81 | mutex_lock(&bat_lock); |
| 82 | gpio_set_value(bat->gpio_temp, 1); | 82 | gpio_set_value(bat->gpio_temp, 1); |
| 83 | msleep(5); | 83 | msleep(5); |
| 84 | value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy.dev->parent), | 84 | value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent), |
| 85 | bat->adc_temp); | 85 | bat->adc_temp); |
| 86 | gpio_set_value(bat->gpio_temp, 0); | 86 | gpio_set_value(bat->gpio_temp, 0); |
| 87 | mutex_unlock(&bat_lock); | 87 | mutex_unlock(&bat_lock); |
| @@ -96,7 +96,7 @@ static int tosa_bat_get_property(struct power_supply *psy, | |||
| 96 | union power_supply_propval *val) | 96 | union power_supply_propval *val) |
| 97 | { | 97 | { |
| 98 | int ret = 0; | 98 | int ret = 0; |
| 99 | struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy); | 99 | struct tosa_bat *bat = power_supply_get_drvdata(psy); |
| 100 | 100 | ||
| 101 | if (bat->is_present && !bat->is_present(bat) | 101 | if (bat->is_present && !bat->is_present(bat) |
| 102 | && psp != POWER_SUPPLY_PROP_PRESENT) { | 102 | && psp != POWER_SUPPLY_PROP_PRESENT) { |
| @@ -158,14 +158,14 @@ static irqreturn_t tosa_bat_gpio_isr(int irq, void *data) | |||
| 158 | static void tosa_bat_update(struct tosa_bat *bat) | 158 | static void tosa_bat_update(struct tosa_bat *bat) |
| 159 | { | 159 | { |
| 160 | int old; | 160 | int old; |
| 161 | struct power_supply *psy = &bat->psy; | 161 | struct power_supply *psy = bat->psy; |
| 162 | 162 | ||
| 163 | mutex_lock(&bat->work_lock); | 163 | mutex_lock(&bat->work_lock); |
| 164 | 164 | ||
| 165 | old = bat->status; | 165 | old = bat->status; |
| 166 | 166 | ||
| 167 | if (bat->is_present && !bat->is_present(bat)) { | 167 | if (bat->is_present && !bat->is_present(bat)) { |
| 168 | printk(KERN_NOTICE "%s not present\n", psy->name); | 168 | printk(KERN_NOTICE "%s not present\n", psy->desc->name); |
| 169 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; | 169 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; |
| 170 | bat->full_chrg = -1; | 170 | bat->full_chrg = -1; |
| 171 | } else if (power_supply_am_i_supplied(psy)) { | 171 | } else if (power_supply_am_i_supplied(psy)) { |
| @@ -222,18 +222,38 @@ static enum power_supply_property tosa_bat_bu_props[] = { | |||
| 222 | POWER_SUPPLY_PROP_PRESENT, | 222 | POWER_SUPPLY_PROP_PRESENT, |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| 225 | static const struct power_supply_desc tosa_bat_main_desc = { | ||
| 226 | .name = "main-battery", | ||
| 227 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 228 | .properties = tosa_bat_main_props, | ||
| 229 | .num_properties = ARRAY_SIZE(tosa_bat_main_props), | ||
| 230 | .get_property = tosa_bat_get_property, | ||
| 231 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 232 | .use_for_apm = 1, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static const struct power_supply_desc tosa_bat_jacket_desc = { | ||
| 236 | .name = "jacket-battery", | ||
| 237 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 238 | .properties = tosa_bat_main_props, | ||
| 239 | .num_properties = ARRAY_SIZE(tosa_bat_main_props), | ||
| 240 | .get_property = tosa_bat_get_property, | ||
| 241 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 242 | }; | ||
| 243 | |||
| 244 | static const struct power_supply_desc tosa_bat_bu_desc = { | ||
| 245 | .name = "backup-battery", | ||
| 246 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 247 | .properties = tosa_bat_bu_props, | ||
| 248 | .num_properties = ARRAY_SIZE(tosa_bat_bu_props), | ||
| 249 | .get_property = tosa_bat_get_property, | ||
| 250 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 251 | }; | ||
| 252 | |||
| 225 | static struct tosa_bat tosa_bat_main = { | 253 | static struct tosa_bat tosa_bat_main = { |
| 226 | .status = POWER_SUPPLY_STATUS_DISCHARGING, | 254 | .status = POWER_SUPPLY_STATUS_DISCHARGING, |
| 227 | .full_chrg = -1, | 255 | .full_chrg = -1, |
| 228 | .psy = { | 256 | .psy = NULL, |
| 229 | .name = "main-battery", | ||
| 230 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 231 | .properties = tosa_bat_main_props, | ||
| 232 | .num_properties = ARRAY_SIZE(tosa_bat_main_props), | ||
| 233 | .get_property = tosa_bat_get_property, | ||
| 234 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 235 | .use_for_apm = 1, | ||
| 236 | }, | ||
| 237 | 257 | ||
| 238 | .gpio_full = TOSA_GPIO_BAT0_CRG, | 258 | .gpio_full = TOSA_GPIO_BAT0_CRG, |
| 239 | .gpio_charge_off = TOSA_GPIO_CHARGE_OFF, | 259 | .gpio_charge_off = TOSA_GPIO_CHARGE_OFF, |
| @@ -254,14 +274,7 @@ static struct tosa_bat tosa_bat_main = { | |||
| 254 | static struct tosa_bat tosa_bat_jacket = { | 274 | static struct tosa_bat tosa_bat_jacket = { |
| 255 | .status = POWER_SUPPLY_STATUS_DISCHARGING, | 275 | .status = POWER_SUPPLY_STATUS_DISCHARGING, |
| 256 | .full_chrg = -1, | 276 | .full_chrg = -1, |
| 257 | .psy = { | 277 | .psy = NULL, |
| 258 | .name = "jacket-battery", | ||
| 259 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 260 | .properties = tosa_bat_main_props, | ||
| 261 | .num_properties = ARRAY_SIZE(tosa_bat_main_props), | ||
| 262 | .get_property = tosa_bat_get_property, | ||
| 263 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 264 | }, | ||
| 265 | 278 | ||
| 266 | .is_present = tosa_jacket_bat_is_present, | 279 | .is_present = tosa_jacket_bat_is_present, |
| 267 | .gpio_full = TOSA_GPIO_BAT1_CRG, | 280 | .gpio_full = TOSA_GPIO_BAT1_CRG, |
| @@ -283,15 +296,7 @@ static struct tosa_bat tosa_bat_jacket = { | |||
| 283 | static struct tosa_bat tosa_bat_bu = { | 296 | static struct tosa_bat tosa_bat_bu = { |
| 284 | .status = POWER_SUPPLY_STATUS_UNKNOWN, | 297 | .status = POWER_SUPPLY_STATUS_UNKNOWN, |
| 285 | .full_chrg = -1, | 298 | .full_chrg = -1, |
| 286 | 299 | .psy = NULL, | |
| 287 | .psy = { | ||
| 288 | .name = "backup-battery", | ||
| 289 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 290 | .properties = tosa_bat_bu_props, | ||
| 291 | .num_properties = ARRAY_SIZE(tosa_bat_bu_props), | ||
| 292 | .get_property = tosa_bat_get_property, | ||
| 293 | .external_power_changed = tosa_bat_external_power_changed, | ||
| 294 | }, | ||
| 295 | 300 | ||
| 296 | .gpio_full = -1, | 301 | .gpio_full = -1, |
| 297 | .gpio_charge_off = -1, | 302 | .gpio_charge_off = -1, |
| @@ -345,6 +350,9 @@ static int tosa_bat_resume(struct platform_device *dev) | |||
| 345 | static int tosa_bat_probe(struct platform_device *dev) | 350 | static int tosa_bat_probe(struct platform_device *dev) |
| 346 | { | 351 | { |
| 347 | int ret; | 352 | int ret; |
| 353 | struct power_supply_config main_psy_cfg = {}, | ||
| 354 | jacket_psy_cfg = {}, | ||
| 355 | bu_psy_cfg = {}; | ||
| 348 | 356 | ||
| 349 | if (!machine_is_tosa()) | 357 | if (!machine_is_tosa()) |
| 350 | return -ENODEV; | 358 | return -ENODEV; |
| @@ -358,15 +366,31 @@ static int tosa_bat_probe(struct platform_device *dev) | |||
| 358 | 366 | ||
| 359 | INIT_WORK(&bat_work, tosa_bat_work); | 367 | INIT_WORK(&bat_work, tosa_bat_work); |
| 360 | 368 | ||
| 361 | ret = power_supply_register(&dev->dev, &tosa_bat_main.psy); | 369 | main_psy_cfg.drv_data = &tosa_bat_main; |
| 362 | if (ret) | 370 | tosa_bat_main.psy = power_supply_register(&dev->dev, |
| 371 | &tosa_bat_main_desc, | ||
| 372 | &main_psy_cfg); | ||
| 373 | if (IS_ERR(tosa_bat_main.psy)) { | ||
| 374 | ret = PTR_ERR(tosa_bat_main.psy); | ||
| 363 | goto err_psy_reg_main; | 375 | goto err_psy_reg_main; |
| 364 | ret = power_supply_register(&dev->dev, &tosa_bat_jacket.psy); | 376 | } |
| 365 | if (ret) | 377 | |
| 378 | jacket_psy_cfg.drv_data = &tosa_bat_jacket; | ||
| 379 | tosa_bat_jacket.psy = power_supply_register(&dev->dev, | ||
| 380 | &tosa_bat_jacket_desc, | ||
| 381 | &jacket_psy_cfg); | ||
| 382 | if (IS_ERR(tosa_bat_jacket.psy)) { | ||
| 383 | ret = PTR_ERR(tosa_bat_jacket.psy); | ||
| 366 | goto err_psy_reg_jacket; | 384 | goto err_psy_reg_jacket; |
| 367 | ret = power_supply_register(&dev->dev, &tosa_bat_bu.psy); | 385 | } |
| 368 | if (ret) | 386 | |
| 387 | bu_psy_cfg.drv_data = &tosa_bat_bu; | ||
| 388 | tosa_bat_bu.psy = power_supply_register(&dev->dev, &tosa_bat_bu_desc, | ||
| 389 | &bu_psy_cfg); | ||
| 390 | if (IS_ERR(tosa_bat_bu.psy)) { | ||
| 391 | ret = PTR_ERR(tosa_bat_bu.psy); | ||
| 369 | goto err_psy_reg_bu; | 392 | goto err_psy_reg_bu; |
| 393 | } | ||
| 370 | 394 | ||
| 371 | ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), | 395 | ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), |
| 372 | tosa_bat_gpio_isr, | 396 | tosa_bat_gpio_isr, |
| @@ -395,11 +419,11 @@ static int tosa_bat_probe(struct platform_device *dev) | |||
| 395 | err_req_jacket: | 419 | err_req_jacket: |
| 396 | free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); | 420 | free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); |
| 397 | err_req_main: | 421 | err_req_main: |
| 398 | power_supply_unregister(&tosa_bat_bu.psy); | 422 | power_supply_unregister(tosa_bat_bu.psy); |
| 399 | err_psy_reg_bu: | 423 | err_psy_reg_bu: |
| 400 | power_supply_unregister(&tosa_bat_jacket.psy); | 424 | power_supply_unregister(tosa_bat_jacket.psy); |
| 401 | err_psy_reg_jacket: | 425 | err_psy_reg_jacket: |
| 402 | power_supply_unregister(&tosa_bat_main.psy); | 426 | power_supply_unregister(tosa_bat_main.psy); |
| 403 | err_psy_reg_main: | 427 | err_psy_reg_main: |
| 404 | 428 | ||
| 405 | /* see comment in tosa_bat_remove */ | 429 | /* see comment in tosa_bat_remove */ |
| @@ -415,9 +439,9 @@ static int tosa_bat_remove(struct platform_device *dev) | |||
| 415 | free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); | 439 | free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); |
| 416 | free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); | 440 | free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); |
| 417 | 441 | ||
| 418 | power_supply_unregister(&tosa_bat_bu.psy); | 442 | power_supply_unregister(tosa_bat_bu.psy); |
| 419 | power_supply_unregister(&tosa_bat_jacket.psy); | 443 | power_supply_unregister(tosa_bat_jacket.psy); |
| 420 | power_supply_unregister(&tosa_bat_main.psy); | 444 | power_supply_unregister(tosa_bat_main.psy); |
| 421 | 445 | ||
| 422 | /* | 446 | /* |
| 423 | * Now cancel the bat_work. We won't get any more schedules, | 447 | * Now cancel the bat_work. We won't get any more schedules, |
diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index 0f4e5971dff5..7e8fbd29c30e 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c | |||
| @@ -43,7 +43,7 @@ struct tps65090_charger { | |||
| 43 | int irq; | 43 | int irq; |
| 44 | struct task_struct *poll_task; | 44 | struct task_struct *poll_task; |
| 45 | bool passive_mode; | 45 | bool passive_mode; |
| 46 | struct power_supply ac; | 46 | struct power_supply *ac; |
| 47 | struct tps65090_platform_data *pdata; | 47 | struct tps65090_platform_data *pdata; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| @@ -135,8 +135,7 @@ static int tps65090_ac_get_property(struct power_supply *psy, | |||
| 135 | enum power_supply_property psp, | 135 | enum power_supply_property psp, |
| 136 | union power_supply_propval *val) | 136 | union power_supply_propval *val) |
| 137 | { | 137 | { |
| 138 | struct tps65090_charger *charger = container_of(psy, | 138 | struct tps65090_charger *charger = power_supply_get_drvdata(psy); |
| 139 | struct tps65090_charger, ac); | ||
| 140 | 139 | ||
| 141 | if (psp == POWER_SUPPLY_PROP_ONLINE) { | 140 | if (psp == POWER_SUPPLY_PROP_ONLINE) { |
| 142 | val->intval = charger->ac_online; | 141 | val->intval = charger->ac_online; |
| @@ -190,7 +189,7 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) | |||
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | if (charger->prev_ac_online != charger->ac_online) | 191 | if (charger->prev_ac_online != charger->ac_online) |
| 193 | power_supply_changed(&charger->ac); | 192 | power_supply_changed(charger->ac); |
| 194 | 193 | ||
| 195 | return IRQ_HANDLED; | 194 | return IRQ_HANDLED; |
| 196 | } | 195 | } |
| @@ -229,10 +228,19 @@ static int tps65090_charger_poll_task(void *data) | |||
| 229 | return 0; | 228 | return 0; |
| 230 | } | 229 | } |
| 231 | 230 | ||
| 231 | static const struct power_supply_desc tps65090_charger_desc = { | ||
| 232 | .name = "tps65090-ac", | ||
| 233 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 234 | .get_property = tps65090_ac_get_property, | ||
| 235 | .properties = tps65090_ac_props, | ||
| 236 | .num_properties = ARRAY_SIZE(tps65090_ac_props), | ||
| 237 | }; | ||
| 238 | |||
| 232 | static int tps65090_charger_probe(struct platform_device *pdev) | 239 | static int tps65090_charger_probe(struct platform_device *pdev) |
| 233 | { | 240 | { |
| 234 | struct tps65090_charger *cdata; | 241 | struct tps65090_charger *cdata; |
| 235 | struct tps65090_platform_data *pdata; | 242 | struct tps65090_platform_data *pdata; |
| 243 | struct power_supply_config psy_cfg = {}; | ||
| 236 | uint8_t status1 = 0; | 244 | uint8_t status1 = 0; |
| 237 | int ret; | 245 | int ret; |
| 238 | int irq; | 246 | int irq; |
| @@ -259,19 +267,16 @@ static int tps65090_charger_probe(struct platform_device *pdev) | |||
| 259 | cdata->dev = &pdev->dev; | 267 | cdata->dev = &pdev->dev; |
| 260 | cdata->pdata = pdata; | 268 | cdata->pdata = pdata; |
| 261 | 269 | ||
| 262 | cdata->ac.name = "tps65090-ac"; | 270 | psy_cfg.supplied_to = pdata->supplied_to; |
| 263 | cdata->ac.type = POWER_SUPPLY_TYPE_MAINS; | 271 | psy_cfg.num_supplicants = pdata->num_supplicants; |
| 264 | cdata->ac.get_property = tps65090_ac_get_property; | 272 | psy_cfg.of_node = pdev->dev.of_node; |
| 265 | cdata->ac.properties = tps65090_ac_props; | 273 | psy_cfg.drv_data = cdata; |
| 266 | cdata->ac.num_properties = ARRAY_SIZE(tps65090_ac_props); | 274 | |
| 267 | cdata->ac.supplied_to = pdata->supplied_to; | 275 | cdata->ac = power_supply_register(&pdev->dev, &tps65090_charger_desc, |
| 268 | cdata->ac.num_supplicants = pdata->num_supplicants; | 276 | &psy_cfg); |
| 269 | cdata->ac.of_node = pdev->dev.of_node; | 277 | if (IS_ERR(cdata->ac)) { |
| 270 | |||
| 271 | ret = power_supply_register(&pdev->dev, &cdata->ac); | ||
| 272 | if (ret) { | ||
| 273 | dev_err(&pdev->dev, "failed: power supply register\n"); | 278 | dev_err(&pdev->dev, "failed: power supply register\n"); |
| 274 | return ret; | 279 | return PTR_ERR(cdata->ac); |
| 275 | } | 280 | } |
| 276 | 281 | ||
| 277 | irq = platform_get_irq(pdev, 0); | 282 | irq = platform_get_irq(pdev, 0); |
| @@ -301,7 +306,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) | |||
| 301 | goto fail_unregister_supply; | 306 | goto fail_unregister_supply; |
| 302 | } | 307 | } |
| 303 | cdata->ac_online = 1; | 308 | cdata->ac_online = 1; |
| 304 | power_supply_changed(&cdata->ac); | 309 | power_supply_changed(cdata->ac); |
| 305 | } | 310 | } |
| 306 | 311 | ||
| 307 | if (irq != -ENXIO) { | 312 | if (irq != -ENXIO) { |
| @@ -328,7 +333,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) | |||
| 328 | return 0; | 333 | return 0; |
| 329 | 334 | ||
| 330 | fail_unregister_supply: | 335 | fail_unregister_supply: |
| 331 | power_supply_unregister(&cdata->ac); | 336 | power_supply_unregister(cdata->ac); |
| 332 | 337 | ||
| 333 | return ret; | 338 | return ret; |
| 334 | } | 339 | } |
| @@ -339,12 +344,12 @@ static int tps65090_charger_remove(struct platform_device *pdev) | |||
| 339 | 344 | ||
| 340 | if (cdata->irq == -ENXIO) | 345 | if (cdata->irq == -ENXIO) |
| 341 | kthread_stop(cdata->poll_task); | 346 | kthread_stop(cdata->poll_task); |
| 342 | power_supply_unregister(&cdata->ac); | 347 | power_supply_unregister(cdata->ac); |
| 343 | 348 | ||
| 344 | return 0; | 349 | return 0; |
| 345 | } | 350 | } |
| 346 | 351 | ||
| 347 | static struct of_device_id of_tps65090_charger_match[] = { | 352 | static const struct of_device_id of_tps65090_charger_match[] = { |
| 348 | { .compatible = "ti,tps65090-charger", }, | 353 | { .compatible = "ti,tps65090-charger", }, |
| 349 | { /* end */ } | 354 | { /* end */ } |
| 350 | }; | 355 | }; |
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index d35b83e635b5..02a522cb7753 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c | |||
| @@ -87,8 +87,8 @@ MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current"); | |||
| 87 | 87 | ||
| 88 | struct twl4030_bci { | 88 | struct twl4030_bci { |
| 89 | struct device *dev; | 89 | struct device *dev; |
| 90 | struct power_supply ac; | 90 | struct power_supply *ac; |
| 91 | struct power_supply usb; | 91 | struct power_supply *usb; |
| 92 | struct usb_phy *transceiver; | 92 | struct usb_phy *transceiver; |
| 93 | struct notifier_block usb_nb; | 93 | struct notifier_block usb_nb; |
| 94 | struct work_struct work; | 94 | struct work_struct work; |
| @@ -318,8 +318,8 @@ static irqreturn_t twl4030_charger_interrupt(int irq, void *arg) | |||
| 318 | struct twl4030_bci *bci = arg; | 318 | struct twl4030_bci *bci = arg; |
| 319 | 319 | ||
| 320 | dev_dbg(bci->dev, "CHG_PRES irq\n"); | 320 | dev_dbg(bci->dev, "CHG_PRES irq\n"); |
| 321 | power_supply_changed(&bci->ac); | 321 | power_supply_changed(bci->ac); |
| 322 | power_supply_changed(&bci->usb); | 322 | power_supply_changed(bci->usb); |
| 323 | 323 | ||
| 324 | return IRQ_HANDLED; | 324 | return IRQ_HANDLED; |
| 325 | } | 325 | } |
| @@ -347,8 +347,8 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg) | |||
| 347 | 347 | ||
| 348 | if (irqs1 & (TWL4030_ICHGLOW | TWL4030_ICHGEOC)) { | 348 | if (irqs1 & (TWL4030_ICHGLOW | TWL4030_ICHGEOC)) { |
| 349 | /* charger state change, inform the core */ | 349 | /* charger state change, inform the core */ |
| 350 | power_supply_changed(&bci->ac); | 350 | power_supply_changed(bci->ac); |
| 351 | power_supply_changed(&bci->usb); | 351 | power_supply_changed(bci->usb); |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | /* various monitoring events, for now we just log them here */ | 354 | /* various monitoring events, for now we just log them here */ |
| @@ -463,7 +463,7 @@ static int twl4030_bci_get_property(struct power_supply *psy, | |||
| 463 | enum power_supply_property psp, | 463 | enum power_supply_property psp, |
| 464 | union power_supply_propval *val) | 464 | union power_supply_propval *val) |
| 465 | { | 465 | { |
| 466 | struct twl4030_bci *bci = dev_get_drvdata(psy->dev->parent); | 466 | struct twl4030_bci *bci = dev_get_drvdata(psy->dev.parent); |
| 467 | int is_charging; | 467 | int is_charging; |
| 468 | int state; | 468 | int state; |
| 469 | int ret; | 469 | int ret; |
| @@ -472,7 +472,7 @@ static int twl4030_bci_get_property(struct power_supply *psy, | |||
| 472 | if (state < 0) | 472 | if (state < 0) |
| 473 | return state; | 473 | return state; |
| 474 | 474 | ||
| 475 | if (psy->type == POWER_SUPPLY_TYPE_USB) | 475 | if (psy->desc->type == POWER_SUPPLY_TYPE_USB) |
| 476 | is_charging = state & TWL4030_MSTATEC_USB; | 476 | is_charging = state & TWL4030_MSTATEC_USB; |
| 477 | else | 477 | else |
| 478 | is_charging = state & TWL4030_MSTATEC_AC; | 478 | is_charging = state & TWL4030_MSTATEC_AC; |
| @@ -488,7 +488,7 @@ static int twl4030_bci_get_property(struct power_supply *psy, | |||
| 488 | /* charging must be active for meaningful result */ | 488 | /* charging must be active for meaningful result */ |
| 489 | if (!is_charging) | 489 | if (!is_charging) |
| 490 | return -ENODATA; | 490 | return -ENODATA; |
| 491 | if (psy->type == POWER_SUPPLY_TYPE_USB) { | 491 | if (psy->desc->type == POWER_SUPPLY_TYPE_USB) { |
| 492 | ret = twl4030bci_read_adc_val(TWL4030_BCIVBUS); | 492 | ret = twl4030bci_read_adc_val(TWL4030_BCIVBUS); |
| 493 | if (ret < 0) | 493 | if (ret < 0) |
| 494 | return ret; | 494 | return ret; |
| @@ -558,6 +558,22 @@ twl4030_bci_parse_dt(struct device *dev) | |||
| 558 | } | 558 | } |
| 559 | #endif | 559 | #endif |
| 560 | 560 | ||
| 561 | static const struct power_supply_desc twl4030_bci_ac_desc = { | ||
| 562 | .name = "twl4030_ac", | ||
| 563 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 564 | .properties = twl4030_charger_props, | ||
| 565 | .num_properties = ARRAY_SIZE(twl4030_charger_props), | ||
| 566 | .get_property = twl4030_bci_get_property, | ||
| 567 | }; | ||
| 568 | |||
| 569 | static const struct power_supply_desc twl4030_bci_usb_desc = { | ||
| 570 | .name = "twl4030_usb", | ||
| 571 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 572 | .properties = twl4030_charger_props, | ||
| 573 | .num_properties = ARRAY_SIZE(twl4030_charger_props), | ||
| 574 | .get_property = twl4030_bci_get_property, | ||
| 575 | }; | ||
| 576 | |||
| 561 | static int __init twl4030_bci_probe(struct platform_device *pdev) | 577 | static int __init twl4030_bci_probe(struct platform_device *pdev) |
| 562 | { | 578 | { |
| 563 | struct twl4030_bci *bci; | 579 | struct twl4030_bci *bci; |
| @@ -584,28 +600,21 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
| 584 | } | 600 | } |
| 585 | 601 | ||
| 586 | platform_set_drvdata(pdev, bci); | 602 | platform_set_drvdata(pdev, bci); |
| 587 | bci->ac.name = "twl4030_ac"; | ||
| 588 | bci->ac.type = POWER_SUPPLY_TYPE_MAINS; | ||
| 589 | bci->ac.properties = twl4030_charger_props; | ||
| 590 | bci->ac.num_properties = ARRAY_SIZE(twl4030_charger_props); | ||
| 591 | bci->ac.get_property = twl4030_bci_get_property; | ||
| 592 | 603 | ||
| 593 | ret = power_supply_register(&pdev->dev, &bci->ac); | 604 | bci->ac = power_supply_register(&pdev->dev, &twl4030_bci_ac_desc, |
| 594 | if (ret) { | 605 | NULL); |
| 606 | if (IS_ERR(bci->ac)) { | ||
| 607 | ret = PTR_ERR(bci->ac); | ||
| 595 | dev_err(&pdev->dev, "failed to register ac: %d\n", ret); | 608 | dev_err(&pdev->dev, "failed to register ac: %d\n", ret); |
| 596 | goto fail_register_ac; | 609 | goto fail_register_ac; |
| 597 | } | 610 | } |
| 598 | 611 | ||
| 599 | bci->usb.name = "twl4030_usb"; | ||
| 600 | bci->usb.type = POWER_SUPPLY_TYPE_USB; | ||
| 601 | bci->usb.properties = twl4030_charger_props; | ||
| 602 | bci->usb.num_properties = ARRAY_SIZE(twl4030_charger_props); | ||
| 603 | bci->usb.get_property = twl4030_bci_get_property; | ||
| 604 | |||
| 605 | bci->usb_reg = regulator_get(bci->dev, "bci3v1"); | 612 | bci->usb_reg = regulator_get(bci->dev, "bci3v1"); |
| 606 | 613 | ||
| 607 | ret = power_supply_register(&pdev->dev, &bci->usb); | 614 | bci->usb = power_supply_register(&pdev->dev, &twl4030_bci_usb_desc, |
| 608 | if (ret) { | 615 | NULL); |
| 616 | if (IS_ERR(bci->usb)) { | ||
| 617 | ret = PTR_ERR(bci->usb); | ||
| 609 | dev_err(&pdev->dev, "failed to register usb: %d\n", ret); | 618 | dev_err(&pdev->dev, "failed to register usb: %d\n", ret); |
| 610 | goto fail_register_usb; | 619 | goto fail_register_usb; |
| 611 | } | 620 | } |
| @@ -670,9 +679,9 @@ fail_unmask_interrupts: | |||
| 670 | fail_bci_irq: | 679 | fail_bci_irq: |
| 671 | free_irq(bci->irq_chg, bci); | 680 | free_irq(bci->irq_chg, bci); |
| 672 | fail_chg_irq: | 681 | fail_chg_irq: |
| 673 | power_supply_unregister(&bci->usb); | 682 | power_supply_unregister(bci->usb); |
| 674 | fail_register_usb: | 683 | fail_register_usb: |
| 675 | power_supply_unregister(&bci->ac); | 684 | power_supply_unregister(bci->ac); |
| 676 | fail_register_ac: | 685 | fail_register_ac: |
| 677 | fail_no_battery: | 686 | fail_no_battery: |
| 678 | kfree(bci); | 687 | kfree(bci); |
| @@ -700,8 +709,8 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) | |||
| 700 | } | 709 | } |
| 701 | free_irq(bci->irq_bci, bci); | 710 | free_irq(bci->irq_bci, bci); |
| 702 | free_irq(bci->irq_chg, bci); | 711 | free_irq(bci->irq_chg, bci); |
| 703 | power_supply_unregister(&bci->usb); | 712 | power_supply_unregister(bci->usb); |
| 704 | power_supply_unregister(&bci->ac); | 713 | power_supply_unregister(bci->ac); |
| 705 | kfree(bci); | 714 | kfree(bci); |
| 706 | 715 | ||
| 707 | return 0; | 716 | return 0; |
diff --git a/drivers/power/twl4030_madc_battery.c b/drivers/power/twl4030_madc_battery.c index 7ef445a6cfa6..f5817e422d64 100644 --- a/drivers/power/twl4030_madc_battery.c +++ b/drivers/power/twl4030_madc_battery.c | |||
| @@ -19,10 +19,14 @@ | |||
| 19 | #include <linux/sort.h> | 19 | #include <linux/sort.h> |
| 20 | #include <linux/i2c/twl4030-madc.h> | 20 | #include <linux/i2c/twl4030-madc.h> |
| 21 | #include <linux/power/twl4030_madc_battery.h> | 21 | #include <linux/power/twl4030_madc_battery.h> |
| 22 | #include <linux/iio/consumer.h> | ||
| 22 | 23 | ||
| 23 | struct twl4030_madc_battery { | 24 | struct twl4030_madc_battery { |
| 24 | struct power_supply psy; | 25 | struct power_supply *psy; |
| 25 | struct twl4030_madc_bat_platform_data *pdata; | 26 | struct twl4030_madc_bat_platform_data *pdata; |
| 27 | struct iio_channel *channel_temp; | ||
| 28 | struct iio_channel *channel_ichg; | ||
| 29 | struct iio_channel *channel_vbat; | ||
| 26 | }; | 30 | }; |
| 27 | 31 | ||
| 28 | static enum power_supply_property twl4030_madc_bat_props[] = { | 32 | static enum power_supply_property twl4030_madc_bat_props[] = { |
| @@ -38,43 +42,34 @@ static enum power_supply_property twl4030_madc_bat_props[] = { | |||
| 38 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, | 42 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, |
| 39 | }; | 43 | }; |
| 40 | 44 | ||
| 41 | static int madc_read(int index) | 45 | static int madc_read(struct iio_channel *channel) |
| 42 | { | 46 | { |
| 43 | struct twl4030_madc_request req; | 47 | int val, err; |
| 44 | int val; | 48 | err = iio_read_channel_processed(channel, &val); |
| 49 | if (err < 0) | ||
| 50 | return err; | ||
| 45 | 51 | ||
| 46 | req.channels = index; | 52 | return val; |
| 47 | req.method = TWL4030_MADC_SW2; | ||
| 48 | req.type = TWL4030_MADC_WAIT; | ||
| 49 | req.do_avg = 0; | ||
| 50 | req.raw = false; | ||
| 51 | req.func_cb = NULL; | ||
| 52 | |||
| 53 | val = twl4030_madc_conversion(&req); | ||
| 54 | if (val < 0) | ||
| 55 | return val; | ||
| 56 | |||
| 57 | return req.rbuf[ffs(index) - 1]; | ||
| 58 | } | 53 | } |
| 59 | 54 | ||
| 60 | static int twl4030_madc_bat_get_charging_status(void) | 55 | static int twl4030_madc_bat_get_charging_status(struct twl4030_madc_battery *bt) |
| 61 | { | 56 | { |
| 62 | return (madc_read(TWL4030_MADC_ICHG) > 0) ? 1 : 0; | 57 | return (madc_read(bt->channel_ichg) > 0) ? 1 : 0; |
| 63 | } | 58 | } |
| 64 | 59 | ||
| 65 | static int twl4030_madc_bat_get_voltage(void) | 60 | static int twl4030_madc_bat_get_voltage(struct twl4030_madc_battery *bt) |
| 66 | { | 61 | { |
| 67 | return madc_read(TWL4030_MADC_VBAT); | 62 | return madc_read(bt->channel_vbat); |
| 68 | } | 63 | } |
| 69 | 64 | ||
| 70 | static int twl4030_madc_bat_get_current(void) | 65 | static int twl4030_madc_bat_get_current(struct twl4030_madc_battery *bt) |
| 71 | { | 66 | { |
| 72 | return madc_read(TWL4030_MADC_ICHG) * 1000; | 67 | return madc_read(bt->channel_ichg) * 1000; |
| 73 | } | 68 | } |
| 74 | 69 | ||
| 75 | static int twl4030_madc_bat_get_temp(void) | 70 | static int twl4030_madc_bat_get_temp(struct twl4030_madc_battery *bt) |
| 76 | { | 71 | { |
| 77 | return madc_read(TWL4030_MADC_BTEMP) * 10; | 72 | return madc_read(bt->channel_temp) * 10; |
| 78 | } | 73 | } |
| 79 | 74 | ||
| 80 | static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, | 75 | static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, |
| @@ -84,7 +79,7 @@ static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat, | |||
| 84 | int i, res = 0; | 79 | int i, res = 0; |
| 85 | 80 | ||
| 86 | /* choose charging curve */ | 81 | /* choose charging curve */ |
| 87 | if (twl4030_madc_bat_get_charging_status()) | 82 | if (twl4030_madc_bat_get_charging_status(bat)) |
| 88 | calibration = bat->pdata->charging; | 83 | calibration = bat->pdata->charging; |
| 89 | else | 84 | else |
| 90 | calibration = bat->pdata->discharging; | 85 | calibration = bat->pdata->discharging; |
| @@ -113,29 +108,28 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy, | |||
| 113 | enum power_supply_property psp, | 108 | enum power_supply_property psp, |
| 114 | union power_supply_propval *val) | 109 | union power_supply_propval *val) |
| 115 | { | 110 | { |
| 116 | struct twl4030_madc_battery *bat = container_of(psy, | 111 | struct twl4030_madc_battery *bat = power_supply_get_drvdata(psy); |
| 117 | struct twl4030_madc_battery, psy); | ||
| 118 | 112 | ||
| 119 | switch (psp) { | 113 | switch (psp) { |
| 120 | case POWER_SUPPLY_PROP_STATUS: | 114 | case POWER_SUPPLY_PROP_STATUS: |
| 121 | if (twl4030_madc_bat_voltscale(bat, | 115 | if (twl4030_madc_bat_voltscale(bat, |
| 122 | twl4030_madc_bat_get_voltage()) > 95) | 116 | twl4030_madc_bat_get_voltage(bat)) > 95) |
| 123 | val->intval = POWER_SUPPLY_STATUS_FULL; | 117 | val->intval = POWER_SUPPLY_STATUS_FULL; |
| 124 | else { | 118 | else { |
| 125 | if (twl4030_madc_bat_get_charging_status()) | 119 | if (twl4030_madc_bat_get_charging_status(bat)) |
| 126 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 120 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
| 127 | else | 121 | else |
| 128 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 122 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
| 129 | } | 123 | } |
| 130 | break; | 124 | break; |
| 131 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 125 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
| 132 | val->intval = twl4030_madc_bat_get_voltage() * 1000; | 126 | val->intval = twl4030_madc_bat_get_voltage(bat) * 1000; |
| 133 | break; | 127 | break; |
| 134 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 128 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| 135 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; | 129 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; |
| 136 | break; | 130 | break; |
| 137 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 131 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
| 138 | val->intval = twl4030_madc_bat_get_current(); | 132 | val->intval = twl4030_madc_bat_get_current(bat); |
| 139 | break; | 133 | break; |
| 140 | case POWER_SUPPLY_PROP_PRESENT: | 134 | case POWER_SUPPLY_PROP_PRESENT: |
| 141 | /* assume battery is always present */ | 135 | /* assume battery is always present */ |
| @@ -143,23 +137,23 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy, | |||
| 143 | break; | 137 | break; |
| 144 | case POWER_SUPPLY_PROP_CHARGE_NOW: { | 138 | case POWER_SUPPLY_PROP_CHARGE_NOW: { |
| 145 | int percent = twl4030_madc_bat_voltscale(bat, | 139 | int percent = twl4030_madc_bat_voltscale(bat, |
| 146 | twl4030_madc_bat_get_voltage()); | 140 | twl4030_madc_bat_get_voltage(bat)); |
| 147 | val->intval = (percent * bat->pdata->capacity) / 100; | 141 | val->intval = (percent * bat->pdata->capacity) / 100; |
| 148 | break; | 142 | break; |
| 149 | } | 143 | } |
| 150 | case POWER_SUPPLY_PROP_CAPACITY: | 144 | case POWER_SUPPLY_PROP_CAPACITY: |
| 151 | val->intval = twl4030_madc_bat_voltscale(bat, | 145 | val->intval = twl4030_madc_bat_voltscale(bat, |
| 152 | twl4030_madc_bat_get_voltage()); | 146 | twl4030_madc_bat_get_voltage(bat)); |
| 153 | break; | 147 | break; |
| 154 | case POWER_SUPPLY_PROP_CHARGE_FULL: | 148 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
| 155 | val->intval = bat->pdata->capacity; | 149 | val->intval = bat->pdata->capacity; |
| 156 | break; | 150 | break; |
| 157 | case POWER_SUPPLY_PROP_TEMP: | 151 | case POWER_SUPPLY_PROP_TEMP: |
| 158 | val->intval = twl4030_madc_bat_get_temp(); | 152 | val->intval = twl4030_madc_bat_get_temp(bat); |
| 159 | break; | 153 | break; |
| 160 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: { | 154 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: { |
| 161 | int percent = twl4030_madc_bat_voltscale(bat, | 155 | int percent = twl4030_madc_bat_voltscale(bat, |
| 162 | twl4030_madc_bat_get_voltage()); | 156 | twl4030_madc_bat_get_voltage(bat)); |
| 163 | /* in mAh */ | 157 | /* in mAh */ |
| 164 | int chg = (percent * (bat->pdata->capacity/1000))/100; | 158 | int chg = (percent * (bat->pdata->capacity/1000))/100; |
| 165 | 159 | ||
| @@ -176,12 +170,19 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy, | |||
| 176 | 170 | ||
| 177 | static void twl4030_madc_bat_ext_changed(struct power_supply *psy) | 171 | static void twl4030_madc_bat_ext_changed(struct power_supply *psy) |
| 178 | { | 172 | { |
| 179 | struct twl4030_madc_battery *bat = container_of(psy, | 173 | power_supply_changed(psy); |
| 180 | struct twl4030_madc_battery, psy); | ||
| 181 | |||
| 182 | power_supply_changed(&bat->psy); | ||
| 183 | } | 174 | } |
| 184 | 175 | ||
| 176 | static const struct power_supply_desc twl4030_madc_bat_desc = { | ||
| 177 | .name = "twl4030_battery", | ||
| 178 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 179 | .properties = twl4030_madc_bat_props, | ||
| 180 | .num_properties = ARRAY_SIZE(twl4030_madc_bat_props), | ||
| 181 | .get_property = twl4030_madc_bat_get_property, | ||
| 182 | .external_power_changed = twl4030_madc_bat_ext_changed, | ||
| 183 | |||
| 184 | }; | ||
| 185 | |||
| 185 | static int twl4030_cmp(const void *a, const void *b) | 186 | static int twl4030_cmp(const void *a, const void *b) |
| 186 | { | 187 | { |
| 187 | return ((struct twl4030_madc_bat_calibration *)b)->voltage - | 188 | return ((struct twl4030_madc_bat_calibration *)b)->voltage - |
| @@ -192,19 +193,31 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev) | |||
| 192 | { | 193 | { |
| 193 | struct twl4030_madc_battery *twl4030_madc_bat; | 194 | struct twl4030_madc_battery *twl4030_madc_bat; |
| 194 | struct twl4030_madc_bat_platform_data *pdata = pdev->dev.platform_data; | 195 | struct twl4030_madc_bat_platform_data *pdata = pdev->dev.platform_data; |
| 196 | struct power_supply_config psy_cfg = {}; | ||
| 197 | int ret = 0; | ||
| 195 | 198 | ||
| 196 | twl4030_madc_bat = kzalloc(sizeof(*twl4030_madc_bat), GFP_KERNEL); | 199 | twl4030_madc_bat = devm_kzalloc(&pdev->dev, sizeof(*twl4030_madc_bat), |
| 200 | GFP_KERNEL); | ||
| 197 | if (!twl4030_madc_bat) | 201 | if (!twl4030_madc_bat) |
| 198 | return -ENOMEM; | 202 | return -ENOMEM; |
| 199 | 203 | ||
| 200 | twl4030_madc_bat->psy.name = "twl4030_battery"; | 204 | twl4030_madc_bat->channel_temp = iio_channel_get(&pdev->dev, "temp"); |
| 201 | twl4030_madc_bat->psy.type = POWER_SUPPLY_TYPE_BATTERY; | 205 | if (IS_ERR(twl4030_madc_bat->channel_temp)) { |
| 202 | twl4030_madc_bat->psy.properties = twl4030_madc_bat_props; | 206 | ret = PTR_ERR(twl4030_madc_bat->channel_temp); |
| 203 | twl4030_madc_bat->psy.num_properties = | 207 | goto err; |
| 204 | ARRAY_SIZE(twl4030_madc_bat_props); | 208 | } |
| 205 | twl4030_madc_bat->psy.get_property = twl4030_madc_bat_get_property; | 209 | |
| 206 | twl4030_madc_bat->psy.external_power_changed = | 210 | twl4030_madc_bat->channel_ichg = iio_channel_get(&pdev->dev, "ichg"); |
| 207 | twl4030_madc_bat_ext_changed; | 211 | if (IS_ERR(twl4030_madc_bat->channel_ichg)) { |
| 212 | ret = PTR_ERR(twl4030_madc_bat->channel_ichg); | ||
| 213 | goto err_temp; | ||
| 214 | } | ||
| 215 | |||
| 216 | twl4030_madc_bat->channel_vbat = iio_channel_get(&pdev->dev, "vbat"); | ||
| 217 | if (IS_ERR(twl4030_madc_bat->channel_vbat)) { | ||
| 218 | ret = PTR_ERR(twl4030_madc_bat->channel_vbat); | ||
| 219 | goto err_ichg; | ||
| 220 | } | ||
| 208 | 221 | ||
| 209 | /* sort charging and discharging calibration data */ | 222 | /* sort charging and discharging calibration data */ |
| 210 | sort(pdata->charging, pdata->charging_size, | 223 | sort(pdata->charging, pdata->charging_size, |
| @@ -216,17 +229,36 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev) | |||
| 216 | 229 | ||
| 217 | twl4030_madc_bat->pdata = pdata; | 230 | twl4030_madc_bat->pdata = pdata; |
| 218 | platform_set_drvdata(pdev, twl4030_madc_bat); | 231 | platform_set_drvdata(pdev, twl4030_madc_bat); |
| 219 | power_supply_register(&pdev->dev, &twl4030_madc_bat->psy); | 232 | psy_cfg.drv_data = twl4030_madc_bat; |
| 233 | twl4030_madc_bat->psy = power_supply_register(&pdev->dev, | ||
| 234 | &twl4030_madc_bat_desc, | ||
| 235 | &psy_cfg); | ||
| 236 | if (IS_ERR(twl4030_madc_bat->psy)) { | ||
| 237 | ret = PTR_ERR(twl4030_madc_bat->psy); | ||
| 238 | goto err_vbat; | ||
| 239 | } | ||
| 220 | 240 | ||
| 221 | return 0; | 241 | return 0; |
| 242 | |||
| 243 | err_vbat: | ||
| 244 | iio_channel_release(twl4030_madc_bat->channel_vbat); | ||
| 245 | err_ichg: | ||
| 246 | iio_channel_release(twl4030_madc_bat->channel_ichg); | ||
| 247 | err_temp: | ||
| 248 | iio_channel_release(twl4030_madc_bat->channel_temp); | ||
| 249 | err: | ||
| 250 | return ret; | ||
| 222 | } | 251 | } |
| 223 | 252 | ||
| 224 | static int twl4030_madc_battery_remove(struct platform_device *pdev) | 253 | static int twl4030_madc_battery_remove(struct platform_device *pdev) |
| 225 | { | 254 | { |
| 226 | struct twl4030_madc_battery *bat = platform_get_drvdata(pdev); | 255 | struct twl4030_madc_battery *bat = platform_get_drvdata(pdev); |
| 227 | 256 | ||
| 228 | power_supply_unregister(&bat->psy); | 257 | power_supply_unregister(bat->psy); |
| 229 | kfree(bat); | 258 | |
| 259 | iio_channel_release(bat->channel_vbat); | ||
| 260 | iio_channel_release(bat->channel_ichg); | ||
| 261 | iio_channel_release(bat->channel_temp); | ||
| 230 | 262 | ||
| 231 | return 0; | 263 | return 0; |
| 232 | } | 264 | } |
| @@ -243,3 +275,4 @@ module_platform_driver(twl4030_madc_battery_driver); | |||
| 243 | MODULE_LICENSE("GPL"); | 275 | MODULE_LICENSE("GPL"); |
| 244 | MODULE_AUTHOR("Lukas Märdian <lukas@goldelico.com>"); | 276 | MODULE_AUTHOR("Lukas Märdian <lukas@goldelico.com>"); |
| 245 | MODULE_DESCRIPTION("twl4030_madc battery driver"); | 277 | MODULE_DESCRIPTION("twl4030_madc battery driver"); |
| 278 | MODULE_ALIAS("platform:twl4030_madc_battery"); | ||
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 56fb509f4be0..2e33109ca8c7 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c | |||
| @@ -21,7 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | struct wm831x_backup { | 22 | struct wm831x_backup { |
| 23 | struct wm831x *wm831x; | 23 | struct wm831x *wm831x; |
| 24 | struct power_supply backup; | 24 | struct power_supply *backup; |
| 25 | struct power_supply_desc backup_desc; | ||
| 25 | char name[20]; | 26 | char name[20]; |
| 26 | }; | 27 | }; |
| 27 | 28 | ||
| @@ -115,7 +116,7 @@ static int wm831x_backup_get_prop(struct power_supply *psy, | |||
| 115 | enum power_supply_property psp, | 116 | enum power_supply_property psp, |
| 116 | union power_supply_propval *val) | 117 | union power_supply_propval *val) |
| 117 | { | 118 | { |
| 118 | struct wm831x_backup *devdata = dev_get_drvdata(psy->dev->parent); | 119 | struct wm831x_backup *devdata = dev_get_drvdata(psy->dev.parent); |
| 119 | struct wm831x *wm831x = devdata->wm831x; | 120 | struct wm831x *wm831x = devdata->wm831x; |
| 120 | int ret = 0; | 121 | int ret = 0; |
| 121 | 122 | ||
| @@ -166,8 +167,6 @@ static int wm831x_backup_probe(struct platform_device *pdev) | |||
| 166 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 167 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
| 167 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; | 168 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; |
| 168 | struct wm831x_backup *devdata; | 169 | struct wm831x_backup *devdata; |
| 169 | struct power_supply *backup; | ||
| 170 | int ret; | ||
| 171 | 170 | ||
| 172 | devdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_backup), | 171 | devdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_backup), |
| 173 | GFP_KERNEL); | 172 | GFP_KERNEL); |
| @@ -177,8 +176,6 @@ static int wm831x_backup_probe(struct platform_device *pdev) | |||
| 177 | devdata->wm831x = wm831x; | 176 | devdata->wm831x = wm831x; |
| 178 | platform_set_drvdata(pdev, devdata); | 177 | platform_set_drvdata(pdev, devdata); |
| 179 | 178 | ||
| 180 | backup = &devdata->backup; | ||
| 181 | |||
| 182 | /* We ignore configuration failures since we can still read | 179 | /* We ignore configuration failures since we can still read |
| 183 | * back the status without enabling the charger (which may | 180 | * back the status without enabling the charger (which may |
| 184 | * already be enabled anyway). | 181 | * already be enabled anyway). |
| @@ -192,21 +189,22 @@ static int wm831x_backup_probe(struct platform_device *pdev) | |||
| 192 | snprintf(devdata->name, sizeof(devdata->name), | 189 | snprintf(devdata->name, sizeof(devdata->name), |
| 193 | "wm831x-backup"); | 190 | "wm831x-backup"); |
| 194 | 191 | ||
| 195 | backup->name = devdata->name; | 192 | devdata->backup_desc.name = devdata->name; |
| 196 | backup->type = POWER_SUPPLY_TYPE_BATTERY; | 193 | devdata->backup_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 197 | backup->properties = wm831x_backup_props; | 194 | devdata->backup_desc.properties = wm831x_backup_props; |
| 198 | backup->num_properties = ARRAY_SIZE(wm831x_backup_props); | 195 | devdata->backup_desc.num_properties = ARRAY_SIZE(wm831x_backup_props); |
| 199 | backup->get_property = wm831x_backup_get_prop; | 196 | devdata->backup_desc.get_property = wm831x_backup_get_prop; |
| 200 | ret = power_supply_register(&pdev->dev, backup); | 197 | devdata->backup = power_supply_register(&pdev->dev, |
| 198 | &devdata->backup_desc, NULL); | ||
| 201 | 199 | ||
| 202 | return ret; | 200 | return PTR_ERR_OR_ZERO(devdata->backup); |
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | static int wm831x_backup_remove(struct platform_device *pdev) | 203 | static int wm831x_backup_remove(struct platform_device *pdev) |
| 206 | { | 204 | { |
| 207 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); | 205 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); |
| 208 | 206 | ||
| 209 | power_supply_unregister(&devdata->backup); | 207 | power_supply_unregister(devdata->backup); |
| 210 | 208 | ||
| 211 | return 0; | 209 | return 0; |
| 212 | } | 210 | } |
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index 3bed2f55cf7d..0161bdabd5a3 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c | |||
| @@ -21,9 +21,12 @@ | |||
| 21 | 21 | ||
| 22 | struct wm831x_power { | 22 | struct wm831x_power { |
| 23 | struct wm831x *wm831x; | 23 | struct wm831x *wm831x; |
| 24 | struct power_supply wall; | 24 | struct power_supply *wall; |
| 25 | struct power_supply usb; | 25 | struct power_supply *usb; |
| 26 | struct power_supply battery; | 26 | struct power_supply *battery; |
| 27 | struct power_supply_desc wall_desc; | ||
| 28 | struct power_supply_desc usb_desc; | ||
| 29 | struct power_supply_desc battery_desc; | ||
| 27 | char wall_name[20]; | 30 | char wall_name[20]; |
| 28 | char usb_name[20]; | 31 | char usb_name[20]; |
| 29 | char battery_name[20]; | 32 | char battery_name[20]; |
| @@ -67,7 +70,7 @@ static int wm831x_wall_get_prop(struct power_supply *psy, | |||
| 67 | enum power_supply_property psp, | 70 | enum power_supply_property psp, |
| 68 | union power_supply_propval *val) | 71 | union power_supply_propval *val) |
| 69 | { | 72 | { |
| 70 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); | 73 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); |
| 71 | struct wm831x *wm831x = wm831x_power->wm831x; | 74 | struct wm831x *wm831x = wm831x_power->wm831x; |
| 72 | int ret = 0; | 75 | int ret = 0; |
| 73 | 76 | ||
| @@ -98,7 +101,7 @@ static int wm831x_usb_get_prop(struct power_supply *psy, | |||
| 98 | enum power_supply_property psp, | 101 | enum power_supply_property psp, |
| 99 | union power_supply_propval *val) | 102 | union power_supply_propval *val) |
| 100 | { | 103 | { |
| 101 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); | 104 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); |
| 102 | struct wm831x *wm831x = wm831x_power->wm831x; | 105 | struct wm831x *wm831x = wm831x_power->wm831x; |
| 103 | int ret = 0; | 106 | int ret = 0; |
| 104 | 107 | ||
| @@ -393,7 +396,7 @@ static int wm831x_bat_get_prop(struct power_supply *psy, | |||
| 393 | enum power_supply_property psp, | 396 | enum power_supply_property psp, |
| 394 | union power_supply_propval *val) | 397 | union power_supply_propval *val) |
| 395 | { | 398 | { |
| 396 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); | 399 | struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); |
| 397 | struct wm831x *wm831x = wm831x_power->wm831x; | 400 | struct wm831x *wm831x = wm831x_power->wm831x; |
| 398 | int ret = 0; | 401 | int ret = 0; |
| 399 | 402 | ||
| @@ -451,7 +454,7 @@ static irqreturn_t wm831x_bat_irq(int irq, void *data) | |||
| 451 | /* The battery charger is autonomous so we don't need to do | 454 | /* The battery charger is autonomous so we don't need to do |
| 452 | * anything except kick user space */ | 455 | * anything except kick user space */ |
| 453 | if (wm831x_power->have_battery) | 456 | if (wm831x_power->have_battery) |
| 454 | power_supply_changed(&wm831x_power->battery); | 457 | power_supply_changed(wm831x_power->battery); |
| 455 | 458 | ||
| 456 | return IRQ_HANDLED; | 459 | return IRQ_HANDLED; |
| 457 | } | 460 | } |
| @@ -482,9 +485,9 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data) | |||
| 482 | 485 | ||
| 483 | /* Just notify for everything - little harm in overnotifying. */ | 486 | /* Just notify for everything - little harm in overnotifying. */ |
| 484 | if (wm831x_power->have_battery) | 487 | if (wm831x_power->have_battery) |
| 485 | power_supply_changed(&wm831x_power->battery); | 488 | power_supply_changed(wm831x_power->battery); |
| 486 | power_supply_changed(&wm831x_power->usb); | 489 | power_supply_changed(wm831x_power->usb); |
| 487 | power_supply_changed(&wm831x_power->wall); | 490 | power_supply_changed(wm831x_power->wall); |
| 488 | 491 | ||
| 489 | return IRQ_HANDLED; | 492 | return IRQ_HANDLED; |
| 490 | } | 493 | } |
| @@ -494,9 +497,6 @@ static int wm831x_power_probe(struct platform_device *pdev) | |||
| 494 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 497 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
| 495 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; | 498 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; |
| 496 | struct wm831x_power *power; | 499 | struct wm831x_power *power; |
| 497 | struct power_supply *usb; | ||
| 498 | struct power_supply *battery; | ||
| 499 | struct power_supply *wall; | ||
| 500 | int ret, irq, i; | 500 | int ret, irq, i; |
| 501 | 501 | ||
| 502 | power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL); | 502 | power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL); |
| @@ -506,10 +506,6 @@ static int wm831x_power_probe(struct platform_device *pdev) | |||
| 506 | power->wm831x = wm831x; | 506 | power->wm831x = wm831x; |
| 507 | platform_set_drvdata(pdev, power); | 507 | platform_set_drvdata(pdev, power); |
| 508 | 508 | ||
| 509 | usb = &power->usb; | ||
| 510 | battery = &power->battery; | ||
| 511 | wall = &power->wall; | ||
| 512 | |||
| 513 | if (wm831x_pdata && wm831x_pdata->wm831x_num) { | 509 | if (wm831x_pdata && wm831x_pdata->wm831x_num) { |
| 514 | snprintf(power->wall_name, sizeof(power->wall_name), | 510 | snprintf(power->wall_name, sizeof(power->wall_name), |
| 515 | "wm831x-wall.%d", wm831x_pdata->wm831x_num); | 511 | "wm831x-wall.%d", wm831x_pdata->wm831x_num); |
| @@ -531,23 +527,28 @@ static int wm831x_power_probe(struct platform_device *pdev) | |||
| 531 | */ | 527 | */ |
| 532 | wm831x_config_battery(wm831x); | 528 | wm831x_config_battery(wm831x); |
| 533 | 529 | ||
| 534 | wall->name = power->wall_name; | 530 | power->wall_desc.name = power->wall_name; |
| 535 | wall->type = POWER_SUPPLY_TYPE_MAINS; | 531 | power->wall_desc.type = POWER_SUPPLY_TYPE_MAINS; |
| 536 | wall->properties = wm831x_wall_props; | 532 | power->wall_desc.properties = wm831x_wall_props; |
| 537 | wall->num_properties = ARRAY_SIZE(wm831x_wall_props); | 533 | power->wall_desc.num_properties = ARRAY_SIZE(wm831x_wall_props); |
| 538 | wall->get_property = wm831x_wall_get_prop; | 534 | power->wall_desc.get_property = wm831x_wall_get_prop; |
| 539 | ret = power_supply_register(&pdev->dev, wall); | 535 | power->wall = power_supply_register(&pdev->dev, &power->wall_desc, |
| 540 | if (ret) | 536 | NULL); |
| 537 | if (IS_ERR(power->wall)) { | ||
| 538 | ret = PTR_ERR(power->wall); | ||
| 541 | goto err_kmalloc; | 539 | goto err_kmalloc; |
| 540 | } | ||
| 542 | 541 | ||
| 543 | usb->name = power->usb_name, | 542 | power->usb_desc.name = power->usb_name, |
| 544 | usb->type = POWER_SUPPLY_TYPE_USB; | 543 | power->usb_desc.type = POWER_SUPPLY_TYPE_USB; |
| 545 | usb->properties = wm831x_usb_props; | 544 | power->usb_desc.properties = wm831x_usb_props; |
| 546 | usb->num_properties = ARRAY_SIZE(wm831x_usb_props); | 545 | power->usb_desc.num_properties = ARRAY_SIZE(wm831x_usb_props); |
| 547 | usb->get_property = wm831x_usb_get_prop; | 546 | power->usb_desc.get_property = wm831x_usb_get_prop; |
| 548 | ret = power_supply_register(&pdev->dev, usb); | 547 | power->usb = power_supply_register(&pdev->dev, &power->usb_desc, NULL); |
| 549 | if (ret) | 548 | if (IS_ERR(power->usb)) { |
| 549 | ret = PTR_ERR(power->usb); | ||
| 550 | goto err_wall; | 550 | goto err_wall; |
| 551 | } | ||
| 551 | 552 | ||
| 552 | ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1); | 553 | ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1); |
| 553 | if (ret < 0) | 554 | if (ret < 0) |
| @@ -555,14 +556,18 @@ static int wm831x_power_probe(struct platform_device *pdev) | |||
| 555 | power->have_battery = ret & WM831X_CHG_ENA; | 556 | power->have_battery = ret & WM831X_CHG_ENA; |
| 556 | 557 | ||
| 557 | if (power->have_battery) { | 558 | if (power->have_battery) { |
| 558 | battery->name = power->battery_name; | 559 | power->battery_desc.name = power->battery_name; |
| 559 | battery->properties = wm831x_bat_props; | 560 | power->battery_desc.properties = wm831x_bat_props; |
| 560 | battery->num_properties = ARRAY_SIZE(wm831x_bat_props); | 561 | power->battery_desc.num_properties = ARRAY_SIZE(wm831x_bat_props); |
| 561 | battery->get_property = wm831x_bat_get_prop; | 562 | power->battery_desc.get_property = wm831x_bat_get_prop; |
| 562 | battery->use_for_apm = 1; | 563 | power->battery_desc.use_for_apm = 1; |
| 563 | ret = power_supply_register(&pdev->dev, battery); | 564 | power->battery = power_supply_register(&pdev->dev, |
| 564 | if (ret) | 565 | &power->battery_desc, |
| 565 | goto err_usb; | 566 | NULL); |
| 567 | if (IS_ERR(power->battery)) { | ||
| 568 | ret = PTR_ERR(power->battery); | ||
| 569 | goto err_usb; | ||
| 570 | } | ||
| 566 | } | 571 | } |
| 567 | 572 | ||
| 568 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO")); | 573 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO")); |
| @@ -615,11 +620,11 @@ err_syslo: | |||
| 615 | free_irq(irq, power); | 620 | free_irq(irq, power); |
| 616 | err_battery: | 621 | err_battery: |
| 617 | if (power->have_battery) | 622 | if (power->have_battery) |
| 618 | power_supply_unregister(battery); | 623 | power_supply_unregister(power->battery); |
| 619 | err_usb: | 624 | err_usb: |
| 620 | power_supply_unregister(usb); | 625 | power_supply_unregister(power->usb); |
| 621 | err_wall: | 626 | err_wall: |
| 622 | power_supply_unregister(wall); | 627 | power_supply_unregister(power->wall); |
| 623 | err_kmalloc: | 628 | err_kmalloc: |
| 624 | kfree(power); | 629 | kfree(power); |
| 625 | return ret; | 630 | return ret; |
| @@ -645,9 +650,9 @@ static int wm831x_power_remove(struct platform_device *pdev) | |||
| 645 | free_irq(irq, wm831x_power); | 650 | free_irq(irq, wm831x_power); |
| 646 | 651 | ||
| 647 | if (wm831x_power->have_battery) | 652 | if (wm831x_power->have_battery) |
| 648 | power_supply_unregister(&wm831x_power->battery); | 653 | power_supply_unregister(wm831x_power->battery); |
| 649 | power_supply_unregister(&wm831x_power->wall); | 654 | power_supply_unregister(wm831x_power->wall); |
| 650 | power_supply_unregister(&wm831x_power->usb); | 655 | power_supply_unregister(wm831x_power->usb); |
| 651 | kfree(wm831x_power); | 656 | kfree(wm831x_power); |
| 652 | return 0; | 657 | return 0; |
| 653 | } | 658 | } |
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c index b3607e2906d2..5c5880664e09 100644 --- a/drivers/power/wm8350_power.c +++ b/drivers/power/wm8350_power.c | |||
| @@ -196,14 +196,14 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data) | |||
| 196 | break; | 196 | break; |
| 197 | case WM8350_IRQ_CHG_TO: | 197 | case WM8350_IRQ_CHG_TO: |
| 198 | dev_err(wm8350->dev, "charger timeout\n"); | 198 | dev_err(wm8350->dev, "charger timeout\n"); |
| 199 | power_supply_changed(&power->battery); | 199 | power_supply_changed(power->battery); |
| 200 | break; | 200 | break; |
| 201 | 201 | ||
| 202 | case WM8350_IRQ_CHG_BAT_HOT: | 202 | case WM8350_IRQ_CHG_BAT_HOT: |
| 203 | case WM8350_IRQ_CHG_BAT_COLD: | 203 | case WM8350_IRQ_CHG_BAT_COLD: |
| 204 | case WM8350_IRQ_CHG_START: | 204 | case WM8350_IRQ_CHG_START: |
| 205 | case WM8350_IRQ_CHG_END: | 205 | case WM8350_IRQ_CHG_END: |
| 206 | power_supply_changed(&power->battery); | 206 | power_supply_changed(power->battery); |
| 207 | break; | 207 | break; |
| 208 | 208 | ||
| 209 | case WM8350_IRQ_CHG_FAST_RDY: | 209 | case WM8350_IRQ_CHG_FAST_RDY: |
| @@ -231,9 +231,9 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data) | |||
| 231 | case WM8350_IRQ_EXT_WALL_FB: | 231 | case WM8350_IRQ_EXT_WALL_FB: |
| 232 | wm8350_charger_config(wm8350, policy); | 232 | wm8350_charger_config(wm8350, policy); |
| 233 | case WM8350_IRQ_EXT_BAT_FB: /* Fall through */ | 233 | case WM8350_IRQ_EXT_BAT_FB: /* Fall through */ |
| 234 | power_supply_changed(&power->battery); | 234 | power_supply_changed(power->battery); |
| 235 | power_supply_changed(&power->usb); | 235 | power_supply_changed(power->usb); |
| 236 | power_supply_changed(&power->ac); | 236 | power_supply_changed(power->ac); |
| 237 | break; | 237 | break; |
| 238 | 238 | ||
| 239 | default: | 239 | default: |
| @@ -250,7 +250,7 @@ static int wm8350_ac_get_prop(struct power_supply *psy, | |||
| 250 | enum power_supply_property psp, | 250 | enum power_supply_property psp, |
| 251 | union power_supply_propval *val) | 251 | union power_supply_propval *val) |
| 252 | { | 252 | { |
| 253 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); | 253 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent); |
| 254 | int ret = 0; | 254 | int ret = 0; |
| 255 | 255 | ||
| 256 | switch (psp) { | 256 | switch (psp) { |
| @@ -280,7 +280,7 @@ static int wm8350_usb_get_prop(struct power_supply *psy, | |||
| 280 | enum power_supply_property psp, | 280 | enum power_supply_property psp, |
| 281 | union power_supply_propval *val) | 281 | union power_supply_propval *val) |
| 282 | { | 282 | { |
| 283 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); | 283 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent); |
| 284 | int ret = 0; | 284 | int ret = 0; |
| 285 | 285 | ||
| 286 | switch (psp) { | 286 | switch (psp) { |
| @@ -346,7 +346,7 @@ static int wm8350_bat_get_property(struct power_supply *psy, | |||
| 346 | enum power_supply_property psp, | 346 | enum power_supply_property psp, |
| 347 | union power_supply_propval *val) | 347 | union power_supply_propval *val) |
| 348 | { | 348 | { |
| 349 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); | 349 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev.parent); |
| 350 | int ret = 0; | 350 | int ret = 0; |
| 351 | 351 | ||
| 352 | switch (psp) { | 352 | switch (psp) { |
| @@ -382,6 +382,30 @@ static enum power_supply_property wm8350_bat_props[] = { | |||
| 382 | POWER_SUPPLY_PROP_CHARGE_TYPE, | 382 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
| 383 | }; | 383 | }; |
| 384 | 384 | ||
| 385 | static const struct power_supply_desc wm8350_ac_desc = { | ||
| 386 | .name = "wm8350-ac", | ||
| 387 | .type = POWER_SUPPLY_TYPE_MAINS, | ||
| 388 | .properties = wm8350_ac_props, | ||
| 389 | .num_properties = ARRAY_SIZE(wm8350_ac_props), | ||
| 390 | .get_property = wm8350_ac_get_prop, | ||
| 391 | }; | ||
| 392 | |||
| 393 | static const struct power_supply_desc wm8350_battery_desc = { | ||
| 394 | .name = "wm8350-battery", | ||
| 395 | .properties = wm8350_bat_props, | ||
| 396 | .num_properties = ARRAY_SIZE(wm8350_bat_props), | ||
| 397 | .get_property = wm8350_bat_get_property, | ||
| 398 | .use_for_apm = 1, | ||
| 399 | }; | ||
| 400 | |||
| 401 | static const struct power_supply_desc wm8350_usb_desc = { | ||
| 402 | .name = "wm8350-usb", | ||
| 403 | .type = POWER_SUPPLY_TYPE_USB, | ||
| 404 | .properties = wm8350_usb_props, | ||
| 405 | .num_properties = ARRAY_SIZE(wm8350_usb_props), | ||
| 406 | .get_property = wm8350_usb_get_prop, | ||
| 407 | }; | ||
| 408 | |||
| 385 | /********************************************************************* | 409 | /********************************************************************* |
| 386 | * Initialisation | 410 | * Initialisation |
| 387 | *********************************************************************/ | 411 | *********************************************************************/ |
| @@ -447,37 +471,24 @@ static int wm8350_power_probe(struct platform_device *pdev) | |||
| 447 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | 471 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
| 448 | struct wm8350_power *power = &wm8350->power; | 472 | struct wm8350_power *power = &wm8350->power; |
| 449 | struct wm8350_charger_policy *policy = power->policy; | 473 | struct wm8350_charger_policy *policy = power->policy; |
| 450 | struct power_supply *usb = &power->usb; | ||
| 451 | struct power_supply *battery = &power->battery; | ||
| 452 | struct power_supply *ac = &power->ac; | ||
| 453 | int ret; | 474 | int ret; |
| 454 | 475 | ||
| 455 | ac->name = "wm8350-ac"; | 476 | power->ac = power_supply_register(&pdev->dev, &wm8350_ac_desc, NULL); |
| 456 | ac->type = POWER_SUPPLY_TYPE_MAINS; | 477 | if (IS_ERR(power->ac)) |
| 457 | ac->properties = wm8350_ac_props; | 478 | return PTR_ERR(power->ac); |
| 458 | ac->num_properties = ARRAY_SIZE(wm8350_ac_props); | 479 | |
| 459 | ac->get_property = wm8350_ac_get_prop; | 480 | power->battery = power_supply_register(&pdev->dev, &wm8350_battery_desc, |
| 460 | ret = power_supply_register(&pdev->dev, ac); | 481 | NULL); |
| 461 | if (ret) | 482 | if (IS_ERR(power->battery)) { |
| 462 | return ret; | 483 | ret = PTR_ERR(power->battery); |
| 463 | |||
| 464 | battery->name = "wm8350-battery"; | ||
| 465 | battery->properties = wm8350_bat_props; | ||
| 466 | battery->num_properties = ARRAY_SIZE(wm8350_bat_props); | ||
| 467 | battery->get_property = wm8350_bat_get_property; | ||
| 468 | battery->use_for_apm = 1; | ||
| 469 | ret = power_supply_register(&pdev->dev, battery); | ||
| 470 | if (ret) | ||
| 471 | goto battery_failed; | 484 | goto battery_failed; |
| 485 | } | ||
| 472 | 486 | ||
| 473 | usb->name = "wm8350-usb", | 487 | power->usb = power_supply_register(&pdev->dev, &wm8350_usb_desc, NULL); |
| 474 | usb->type = POWER_SUPPLY_TYPE_USB; | 488 | if (IS_ERR(power->usb)) { |
| 475 | usb->properties = wm8350_usb_props; | 489 | ret = PTR_ERR(power->usb); |
| 476 | usb->num_properties = ARRAY_SIZE(wm8350_usb_props); | ||
| 477 | usb->get_property = wm8350_usb_get_prop; | ||
| 478 | ret = power_supply_register(&pdev->dev, usb); | ||
| 479 | if (ret) | ||
| 480 | goto usb_failed; | 490 | goto usb_failed; |
| 491 | } | ||
| 481 | 492 | ||
| 482 | ret = device_create_file(&pdev->dev, &dev_attr_charger_state); | 493 | ret = device_create_file(&pdev->dev, &dev_attr_charger_state); |
| 483 | if (ret < 0) | 494 | if (ret < 0) |
| @@ -494,9 +505,9 @@ static int wm8350_power_probe(struct platform_device *pdev) | |||
| 494 | return ret; | 505 | return ret; |
| 495 | 506 | ||
| 496 | usb_failed: | 507 | usb_failed: |
| 497 | power_supply_unregister(battery); | 508 | power_supply_unregister(power->battery); |
| 498 | battery_failed: | 509 | battery_failed: |
| 499 | power_supply_unregister(ac); | 510 | power_supply_unregister(power->ac); |
| 500 | 511 | ||
| 501 | return ret; | 512 | return ret; |
| 502 | } | 513 | } |
| @@ -508,9 +519,9 @@ static int wm8350_power_remove(struct platform_device *pdev) | |||
| 508 | 519 | ||
| 509 | free_charger_irq(wm8350); | 520 | free_charger_irq(wm8350); |
| 510 | device_remove_file(&pdev->dev, &dev_attr_charger_state); | 521 | device_remove_file(&pdev->dev, &dev_attr_charger_state); |
| 511 | power_supply_unregister(&power->battery); | 522 | power_supply_unregister(power->battery); |
| 512 | power_supply_unregister(&power->ac); | 523 | power_supply_unregister(power->ac); |
| 513 | power_supply_unregister(&power->usb); | 524 | power_supply_unregister(power->usb); |
| 514 | return 0; | 525 | return 0; |
| 515 | } | 526 | } |
| 516 | 527 | ||
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index a8e6203673ad..c2f09ed35050 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
| @@ -32,20 +32,20 @@ static enum power_supply_property *prop; | |||
| 32 | 32 | ||
| 33 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) | 33 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) |
| 34 | { | 34 | { |
| 35 | struct wm97xx_pdata *wmdata = bat_ps->dev->parent->platform_data; | 35 | struct wm97xx_pdata *wmdata = bat_ps->dev.parent->platform_data; |
| 36 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; | 36 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; |
| 37 | 37 | ||
| 38 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), | 38 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev.parent), |
| 39 | pdata->batt_aux) * pdata->batt_mult / | 39 | pdata->batt_aux) * pdata->batt_mult / |
| 40 | pdata->batt_div; | 40 | pdata->batt_div; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) | 43 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) |
| 44 | { | 44 | { |
| 45 | struct wm97xx_pdata *wmdata = bat_ps->dev->parent->platform_data; | 45 | struct wm97xx_pdata *wmdata = bat_ps->dev.parent->platform_data; |
| 46 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; | 46 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; |
| 47 | 47 | ||
| 48 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), | 48 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev.parent), |
| 49 | pdata->temp_aux) * pdata->temp_mult / | 49 | pdata->temp_aux) * pdata->temp_mult / |
| 50 | pdata->temp_div; | 50 | pdata->temp_div; |
| 51 | } | 51 | } |
| @@ -54,7 +54,7 @@ static int wm97xx_bat_get_property(struct power_supply *bat_ps, | |||
| 54 | enum power_supply_property psp, | 54 | enum power_supply_property psp, |
| 55 | union power_supply_propval *val) | 55 | union power_supply_propval *val) |
| 56 | { | 56 | { |
| 57 | struct wm97xx_pdata *wmdata = bat_ps->dev->parent->platform_data; | 57 | struct wm97xx_pdata *wmdata = bat_ps->dev.parent->platform_data; |
| 58 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; | 58 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; |
| 59 | 59 | ||
| 60 | switch (psp) { | 60 | switch (psp) { |
| @@ -105,7 +105,7 @@ static void wm97xx_bat_external_power_changed(struct power_supply *bat_ps) | |||
| 105 | static void wm97xx_bat_update(struct power_supply *bat_ps) | 105 | static void wm97xx_bat_update(struct power_supply *bat_ps) |
| 106 | { | 106 | { |
| 107 | int old_status = bat_status; | 107 | int old_status = bat_status; |
| 108 | struct wm97xx_pdata *wmdata = bat_ps->dev->parent->platform_data; | 108 | struct wm97xx_pdata *wmdata = bat_ps->dev.parent->platform_data; |
| 109 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; | 109 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; |
| 110 | 110 | ||
| 111 | mutex_lock(&work_lock); | 111 | mutex_lock(&work_lock); |
| @@ -117,7 +117,7 @@ static void wm97xx_bat_update(struct power_supply *bat_ps) | |||
| 117 | POWER_SUPPLY_STATUS_UNKNOWN; | 117 | POWER_SUPPLY_STATUS_UNKNOWN; |
| 118 | 118 | ||
| 119 | if (old_status != bat_status) { | 119 | if (old_status != bat_status) { |
| 120 | pr_debug("%s: %i -> %i\n", bat_ps->name, old_status, | 120 | pr_debug("%s: %i -> %i\n", bat_ps->desc->name, old_status, |
| 121 | bat_status); | 121 | bat_status); |
| 122 | power_supply_changed(bat_ps); | 122 | power_supply_changed(bat_ps); |
| 123 | } | 123 | } |
| @@ -125,7 +125,8 @@ static void wm97xx_bat_update(struct power_supply *bat_ps) | |||
| 125 | mutex_unlock(&work_lock); | 125 | mutex_unlock(&work_lock); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static struct power_supply bat_ps = { | 128 | static struct power_supply *bat_psy; |
| 129 | static struct power_supply_desc bat_psy_desc = { | ||
| 129 | .type = POWER_SUPPLY_TYPE_BATTERY, | 130 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 130 | .get_property = wm97xx_bat_get_property, | 131 | .get_property = wm97xx_bat_get_property, |
| 131 | .external_power_changed = wm97xx_bat_external_power_changed, | 132 | .external_power_changed = wm97xx_bat_external_power_changed, |
| @@ -134,7 +135,7 @@ static struct power_supply bat_ps = { | |||
| 134 | 135 | ||
| 135 | static void wm97xx_bat_work(struct work_struct *work) | 136 | static void wm97xx_bat_work(struct work_struct *work) |
| 136 | { | 137 | { |
| 137 | wm97xx_bat_update(&bat_ps); | 138 | wm97xx_bat_update(bat_psy); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 140 | static irqreturn_t wm97xx_chrg_irq(int irq, void *data) | 141 | static irqreturn_t wm97xx_chrg_irq(int irq, void *data) |
| @@ -237,18 +238,20 @@ static int wm97xx_bat_probe(struct platform_device *dev) | |||
| 237 | dev_info(&dev->dev, "Please consider setting proper battery " | 238 | dev_info(&dev->dev, "Please consider setting proper battery " |
| 238 | "name in platform definition file, falling " | 239 | "name in platform definition file, falling " |
| 239 | "back to name \"wm97xx-batt\"\n"); | 240 | "back to name \"wm97xx-batt\"\n"); |
| 240 | bat_ps.name = "wm97xx-batt"; | 241 | bat_psy_desc.name = "wm97xx-batt"; |
| 241 | } else | 242 | } else |
| 242 | bat_ps.name = pdata->batt_name; | 243 | bat_psy_desc.name = pdata->batt_name; |
| 243 | 244 | ||
| 244 | bat_ps.properties = prop; | 245 | bat_psy_desc.properties = prop; |
| 245 | bat_ps.num_properties = props; | 246 | bat_psy_desc.num_properties = props; |
| 246 | 247 | ||
| 247 | ret = power_supply_register(&dev->dev, &bat_ps); | 248 | bat_psy = power_supply_register(&dev->dev, &bat_psy_desc, NULL); |
| 248 | if (!ret) | 249 | if (!IS_ERR(bat_psy)) { |
| 249 | schedule_work(&bat_work); | 250 | schedule_work(&bat_work); |
| 250 | else | 251 | } else { |
| 252 | ret = PTR_ERR(bat_psy); | ||
| 251 | goto err4; | 253 | goto err4; |
| 254 | } | ||
| 252 | 255 | ||
| 253 | return 0; | 256 | return 0; |
| 254 | err4: | 257 | err4: |
| @@ -273,7 +276,7 @@ static int wm97xx_bat_remove(struct platform_device *dev) | |||
| 273 | gpio_free(pdata->charge_gpio); | 276 | gpio_free(pdata->charge_gpio); |
| 274 | } | 277 | } |
| 275 | cancel_work_sync(&bat_work); | 278 | cancel_work_sync(&bat_work); |
| 276 | power_supply_unregister(&bat_ps); | 279 | power_supply_unregister(bat_psy); |
| 277 | kfree(prop); | 280 | kfree(prop); |
| 278 | return 0; | 281 | return 0; |
| 279 | } | 282 | } |
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c index 814d2e31f0c9..b201e3facf73 100644 --- a/drivers/power/z2_battery.c +++ b/drivers/power/z2_battery.c | |||
| @@ -21,12 +21,13 @@ | |||
| 21 | #define Z2_DEFAULT_NAME "Z2" | 21 | #define Z2_DEFAULT_NAME "Z2" |
| 22 | 22 | ||
| 23 | struct z2_charger { | 23 | struct z2_charger { |
| 24 | struct z2_battery_info *info; | 24 | struct z2_battery_info *info; |
| 25 | int bat_status; | 25 | int bat_status; |
| 26 | struct i2c_client *client; | 26 | struct i2c_client *client; |
| 27 | struct power_supply batt_ps; | 27 | struct power_supply *batt_ps; |
| 28 | struct mutex work_lock; | 28 | struct power_supply_desc batt_ps_desc; |
| 29 | struct work_struct bat_work; | 29 | struct mutex work_lock; |
| 30 | struct work_struct bat_work; | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | static unsigned long z2_read_bat(struct z2_charger *charger) | 33 | static unsigned long z2_read_bat(struct z2_charger *charger) |
| @@ -44,8 +45,7 @@ static int z2_batt_get_property(struct power_supply *batt_ps, | |||
| 44 | enum power_supply_property psp, | 45 | enum power_supply_property psp, |
| 45 | union power_supply_propval *val) | 46 | union power_supply_propval *val) |
| 46 | { | 47 | { |
| 47 | struct z2_charger *charger = container_of(batt_ps, struct z2_charger, | 48 | struct z2_charger *charger = power_supply_get_drvdata(batt_ps); |
| 48 | batt_ps); | ||
| 49 | struct z2_battery_info *info = charger->info; | 49 | struct z2_battery_info *info = charger->info; |
| 50 | 50 | ||
| 51 | switch (psp) { | 51 | switch (psp) { |
| @@ -85,8 +85,8 @@ static int z2_batt_get_property(struct power_supply *batt_ps, | |||
| 85 | 85 | ||
| 86 | static void z2_batt_ext_power_changed(struct power_supply *batt_ps) | 86 | static void z2_batt_ext_power_changed(struct power_supply *batt_ps) |
| 87 | { | 87 | { |
| 88 | struct z2_charger *charger = container_of(batt_ps, struct z2_charger, | 88 | struct z2_charger *charger = power_supply_get_drvdata(batt_ps); |
| 89 | batt_ps); | 89 | |
| 90 | schedule_work(&charger->bat_work); | 90 | schedule_work(&charger->bat_work); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| @@ -106,9 +106,10 @@ static void z2_batt_update(struct z2_charger *charger) | |||
| 106 | POWER_SUPPLY_STATUS_UNKNOWN; | 106 | POWER_SUPPLY_STATUS_UNKNOWN; |
| 107 | 107 | ||
| 108 | if (old_status != charger->bat_status) { | 108 | if (old_status != charger->bat_status) { |
| 109 | pr_debug("%s: %i -> %i\n", charger->batt_ps.name, old_status, | 109 | pr_debug("%s: %i -> %i\n", charger->batt_ps->desc->name, |
| 110 | charger->bat_status); | 110 | old_status, |
| 111 | power_supply_changed(&charger->batt_ps); | 111 | charger->bat_status); |
| 112 | power_supply_changed(charger->batt_ps); | ||
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | mutex_unlock(&charger->work_lock); | 115 | mutex_unlock(&charger->work_lock); |
| @@ -166,16 +167,17 @@ static int z2_batt_ps_init(struct z2_charger *charger, int props) | |||
| 166 | "Please consider setting proper battery " | 167 | "Please consider setting proper battery " |
| 167 | "name in platform definition file, falling " | 168 | "name in platform definition file, falling " |
| 168 | "back to name \" Z2_DEFAULT_NAME \"\n"); | 169 | "back to name \" Z2_DEFAULT_NAME \"\n"); |
| 169 | charger->batt_ps.name = Z2_DEFAULT_NAME; | 170 | charger->batt_ps_desc.name = Z2_DEFAULT_NAME; |
| 170 | } else | 171 | } else |
| 171 | charger->batt_ps.name = info->batt_name; | 172 | charger->batt_ps_desc.name = info->batt_name; |
| 172 | 173 | ||
| 173 | charger->batt_ps.properties = prop; | 174 | charger->batt_ps_desc.properties = prop; |
| 174 | charger->batt_ps.num_properties = props; | 175 | charger->batt_ps_desc.num_properties = props; |
| 175 | charger->batt_ps.type = POWER_SUPPLY_TYPE_BATTERY; | 176 | charger->batt_ps_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
| 176 | charger->batt_ps.get_property = z2_batt_get_property; | 177 | charger->batt_ps_desc.get_property = z2_batt_get_property; |
| 177 | charger->batt_ps.external_power_changed = z2_batt_ext_power_changed; | 178 | charger->batt_ps_desc.external_power_changed = |
| 178 | charger->batt_ps.use_for_apm = 1; | 179 | z2_batt_ext_power_changed; |
| 180 | charger->batt_ps_desc.use_for_apm = 1; | ||
| 179 | 181 | ||
| 180 | return 0; | 182 | return 0; |
| 181 | } | 183 | } |
| @@ -187,6 +189,7 @@ static int z2_batt_probe(struct i2c_client *client, | |||
| 187 | int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ | 189 | int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ |
| 188 | struct z2_charger *charger; | 190 | struct z2_charger *charger; |
| 189 | struct z2_battery_info *info = client->dev.platform_data; | 191 | struct z2_battery_info *info = client->dev.platform_data; |
| 192 | struct power_supply_config psy_cfg = {}; | ||
| 190 | 193 | ||
| 191 | if (info == NULL) { | 194 | if (info == NULL) { |
| 192 | dev_err(&client->dev, | 195 | dev_err(&client->dev, |
| @@ -203,6 +206,7 @@ static int z2_batt_probe(struct i2c_client *client, | |||
| 203 | charger->info = info; | 206 | charger->info = info; |
| 204 | charger->client = client; | 207 | charger->client = client; |
| 205 | i2c_set_clientdata(client, charger); | 208 | i2c_set_clientdata(client, charger); |
| 209 | psy_cfg.drv_data = charger; | ||
| 206 | 210 | ||
| 207 | mutex_init(&charger->work_lock); | 211 | mutex_init(&charger->work_lock); |
| 208 | 212 | ||
| @@ -230,16 +234,20 @@ static int z2_batt_probe(struct i2c_client *client, | |||
| 230 | 234 | ||
| 231 | INIT_WORK(&charger->bat_work, z2_batt_work); | 235 | INIT_WORK(&charger->bat_work, z2_batt_work); |
| 232 | 236 | ||
| 233 | ret = power_supply_register(&client->dev, &charger->batt_ps); | 237 | charger->batt_ps = power_supply_register(&client->dev, |
| 234 | if (ret) | 238 | &charger->batt_ps_desc, |
| 239 | &psy_cfg); | ||
| 240 | if (IS_ERR(charger->batt_ps)) { | ||
| 241 | ret = PTR_ERR(charger->batt_ps); | ||
| 235 | goto err4; | 242 | goto err4; |
| 243 | } | ||
| 236 | 244 | ||
| 237 | schedule_work(&charger->bat_work); | 245 | schedule_work(&charger->bat_work); |
| 238 | 246 | ||
| 239 | return 0; | 247 | return 0; |
| 240 | 248 | ||
| 241 | err4: | 249 | err4: |
| 242 | kfree(charger->batt_ps.properties); | 250 | kfree(charger->batt_ps_desc.properties); |
| 243 | err3: | 251 | err3: |
| 244 | if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) | 252 | if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) |
| 245 | free_irq(gpio_to_irq(info->charge_gpio), charger); | 253 | free_irq(gpio_to_irq(info->charge_gpio), charger); |
| @@ -257,9 +265,9 @@ static int z2_batt_remove(struct i2c_client *client) | |||
| 257 | struct z2_battery_info *info = charger->info; | 265 | struct z2_battery_info *info = charger->info; |
| 258 | 266 | ||
| 259 | cancel_work_sync(&charger->bat_work); | 267 | cancel_work_sync(&charger->bat_work); |
| 260 | power_supply_unregister(&charger->batt_ps); | 268 | power_supply_unregister(charger->batt_ps); |
| 261 | 269 | ||
| 262 | kfree(charger->batt_ps.properties); | 270 | kfree(charger->batt_ps_desc.properties); |
| 263 | if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { | 271 | if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { |
| 264 | free_irq(gpio_to_irq(info->charge_gpio), charger); | 272 | free_irq(gpio_to_irq(info->charge_gpio), charger); |
| 265 | gpio_free(info->charge_gpio); | 273 | gpio_free(info->charge_gpio); |
diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 6a1459d4f8fb..30b66c3c9b73 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c | |||
| @@ -82,8 +82,8 @@ struct bat_response { | |||
| 82 | }; | 82 | }; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static struct power_supply nvec_bat_psy; | 85 | static struct power_supply *nvec_bat_psy; |
| 86 | static struct power_supply nvec_psy; | 86 | static struct power_supply *nvec_psy; |
| 87 | 87 | ||
| 88 | static int nvec_power_notifier(struct notifier_block *nb, | 88 | static int nvec_power_notifier(struct notifier_block *nb, |
| 89 | unsigned long event_type, void *data) | 89 | unsigned long event_type, void *data) |
| @@ -98,7 +98,7 @@ static int nvec_power_notifier(struct notifier_block *nb, | |||
| 98 | if (res->sub_type == 0) { | 98 | if (res->sub_type == 0) { |
| 99 | if (power->on != res->plu) { | 99 | if (power->on != res->plu) { |
| 100 | power->on = res->plu; | 100 | power->on = res->plu; |
| 101 | power_supply_changed(&nvec_psy); | 101 | power_supply_changed(nvec_psy); |
| 102 | } | 102 | } |
| 103 | return NOTIFY_STOP; | 103 | return NOTIFY_STOP; |
| 104 | } | 104 | } |
| @@ -167,7 +167,7 @@ static int nvec_power_bat_notifier(struct notifier_block *nb, | |||
| 167 | } | 167 | } |
| 168 | power->bat_cap = res->plc[1]; | 168 | power->bat_cap = res->plc[1]; |
| 169 | if (status_changed) | 169 | if (status_changed) |
| 170 | power_supply_changed(&nvec_bat_psy); | 170 | power_supply_changed(nvec_bat_psy); |
| 171 | break; | 171 | break; |
| 172 | case VOLTAGE: | 172 | case VOLTAGE: |
| 173 | power->bat_voltage_now = res->plu * 1000; | 173 | power->bat_voltage_now = res->plu * 1000; |
| @@ -225,7 +225,7 @@ static int nvec_power_get_property(struct power_supply *psy, | |||
| 225 | enum power_supply_property psp, | 225 | enum power_supply_property psp, |
| 226 | union power_supply_propval *val) | 226 | union power_supply_propval *val) |
| 227 | { | 227 | { |
| 228 | struct nvec_power *power = dev_get_drvdata(psy->dev->parent); | 228 | struct nvec_power *power = dev_get_drvdata(psy->dev.parent); |
| 229 | 229 | ||
| 230 | switch (psp) { | 230 | switch (psp) { |
| 231 | case POWER_SUPPLY_PROP_ONLINE: | 231 | case POWER_SUPPLY_PROP_ONLINE: |
| @@ -241,7 +241,7 @@ static int nvec_battery_get_property(struct power_supply *psy, | |||
| 241 | enum power_supply_property psp, | 241 | enum power_supply_property psp, |
| 242 | union power_supply_propval *val) | 242 | union power_supply_propval *val) |
| 243 | { | 243 | { |
| 244 | struct nvec_power *power = dev_get_drvdata(psy->dev->parent); | 244 | struct nvec_power *power = dev_get_drvdata(psy->dev.parent); |
| 245 | 245 | ||
| 246 | switch (psp) { | 246 | switch (psp) { |
| 247 | case POWER_SUPPLY_PROP_STATUS: | 247 | case POWER_SUPPLY_PROP_STATUS: |
| @@ -323,7 +323,7 @@ static char *nvec_power_supplied_to[] = { | |||
| 323 | "battery", | 323 | "battery", |
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | static struct power_supply nvec_bat_psy = { | 326 | static const struct power_supply_desc nvec_bat_psy_desc = { |
| 327 | .name = "battery", | 327 | .name = "battery", |
| 328 | .type = POWER_SUPPLY_TYPE_BATTERY, | 328 | .type = POWER_SUPPLY_TYPE_BATTERY, |
| 329 | .properties = nvec_battery_props, | 329 | .properties = nvec_battery_props, |
| @@ -331,11 +331,9 @@ static struct power_supply nvec_bat_psy = { | |||
| 331 | .get_property = nvec_battery_get_property, | 331 | .get_property = nvec_battery_get_property, |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | static struct power_supply nvec_psy = { | 334 | static const struct power_supply_desc nvec_psy_desc = { |
| 335 | .name = "ac", | 335 | .name = "ac", |
| 336 | .type = POWER_SUPPLY_TYPE_MAINS, | 336 | .type = POWER_SUPPLY_TYPE_MAINS, |
| 337 | .supplied_to = nvec_power_supplied_to, | ||
| 338 | .num_supplicants = ARRAY_SIZE(nvec_power_supplied_to), | ||
| 339 | .properties = nvec_power_props, | 337 | .properties = nvec_power_props, |
| 340 | .num_properties = ARRAY_SIZE(nvec_power_props), | 338 | .num_properties = ARRAY_SIZE(nvec_power_props), |
| 341 | .get_property = nvec_power_get_property, | 339 | .get_property = nvec_power_get_property, |
| @@ -373,9 +371,11 @@ static void nvec_power_poll(struct work_struct *work) | |||
| 373 | 371 | ||
| 374 | static int nvec_power_probe(struct platform_device *pdev) | 372 | static int nvec_power_probe(struct platform_device *pdev) |
| 375 | { | 373 | { |
| 376 | struct power_supply *psy; | 374 | struct power_supply **psy; |
| 375 | const struct power_supply_desc *psy_desc; | ||
| 377 | struct nvec_power *power; | 376 | struct nvec_power *power; |
| 378 | struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); | 377 | struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); |
| 378 | struct power_supply_config psy_cfg = {}; | ||
| 379 | 379 | ||
| 380 | power = devm_kzalloc(&pdev->dev, sizeof(struct nvec_power), GFP_NOWAIT); | 380 | power = devm_kzalloc(&pdev->dev, sizeof(struct nvec_power), GFP_NOWAIT); |
| 381 | if (power == NULL) | 381 | if (power == NULL) |
| @@ -387,6 +387,9 @@ static int nvec_power_probe(struct platform_device *pdev) | |||
| 387 | switch (pdev->id) { | 387 | switch (pdev->id) { |
| 388 | case AC: | 388 | case AC: |
| 389 | psy = &nvec_psy; | 389 | psy = &nvec_psy; |
| 390 | psy_desc = &nvec_psy_desc; | ||
| 391 | psy_cfg.supplied_to = nvec_power_supplied_to; | ||
| 392 | psy_cfg.num_supplicants = ARRAY_SIZE(nvec_power_supplied_to); | ||
| 390 | 393 | ||
| 391 | power->notifier.notifier_call = nvec_power_notifier; | 394 | power->notifier.notifier_call = nvec_power_notifier; |
| 392 | 395 | ||
| @@ -395,6 +398,7 @@ static int nvec_power_probe(struct platform_device *pdev) | |||
| 395 | break; | 398 | break; |
| 396 | case BAT: | 399 | case BAT: |
| 397 | psy = &nvec_bat_psy; | 400 | psy = &nvec_bat_psy; |
| 401 | psy_desc = &nvec_bat_psy_desc; | ||
| 398 | 402 | ||
| 399 | power->notifier.notifier_call = nvec_power_bat_notifier; | 403 | power->notifier.notifier_call = nvec_power_bat_notifier; |
| 400 | break; | 404 | break; |
| @@ -407,7 +411,9 @@ static int nvec_power_probe(struct platform_device *pdev) | |||
| 407 | if (pdev->id == BAT) | 411 | if (pdev->id == BAT) |
| 408 | get_bat_mfg_data(power); | 412 | get_bat_mfg_data(power); |
| 409 | 413 | ||
| 410 | return power_supply_register(&pdev->dev, psy); | 414 | *psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg); |
| 415 | |||
| 416 | return PTR_ERR_OR_ZERO(*psy); | ||
| 411 | } | 417 | } |
| 412 | 418 | ||
| 413 | static int nvec_power_remove(struct platform_device *pdev) | 419 | static int nvec_power_remove(struct platform_device *pdev) |
| @@ -418,10 +424,10 @@ static int nvec_power_remove(struct platform_device *pdev) | |||
| 418 | nvec_unregister_notifier(power->nvec, &power->notifier); | 424 | nvec_unregister_notifier(power->nvec, &power->notifier); |
| 419 | switch (pdev->id) { | 425 | switch (pdev->id) { |
| 420 | case AC: | 426 | case AC: |
| 421 | power_supply_unregister(&nvec_psy); | 427 | power_supply_unregister(nvec_psy); |
| 422 | break; | 428 | break; |
| 423 | case BAT: | 429 | case BAT: |
| 424 | power_supply_unregister(&nvec_bat_psy); | 430 | power_supply_unregister(nvec_bat_psy); |
| 425 | } | 431 | } |
| 426 | 432 | ||
| 427 | return 0; | 433 | return 0; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index efc7787a41a8..f94cf28e4b7c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -514,10 +514,10 @@ struct hid_device { /* device report descriptor */ | |||
| 514 | #ifdef CONFIG_HID_BATTERY_STRENGTH | 514 | #ifdef CONFIG_HID_BATTERY_STRENGTH |
| 515 | /* | 515 | /* |
| 516 | * Power supply information for HID devices which report | 516 | * Power supply information for HID devices which report |
| 517 | * battery strength. power_supply is registered iff | 517 | * battery strength. power_supply was successfully registered if |
| 518 | * battery.name is non-NULL. | 518 | * battery is non-NULL. |
| 519 | */ | 519 | */ |
| 520 | struct power_supply battery; | 520 | struct power_supply *battery; |
| 521 | __s32 battery_min; | 521 | __s32 battery_min; |
| 522 | __s32 battery_max; | 522 | __s32 battery_max; |
| 523 | __s32 battery_report_type; | 523 | __s32 battery_report_type; |
diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index 234c99143bf7..67703f23e7ba 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h | |||
| @@ -9,8 +9,13 @@ | |||
| 9 | 9 | ||
| 10 | #include <linux/power_supply.h> | 10 | #include <linux/power_supply.h> |
| 11 | 11 | ||
| 12 | #define psy_to_ux500_charger(x) container_of((x), \ | 12 | /* |
| 13 | struct ux500_charger, psy) | 13 | * Valid only for supplies of type: |
| 14 | * - POWER_SUPPLY_TYPE_MAINS, | ||
| 15 | * - POWER_SUPPLY_TYPE_USB, | ||
| 16 | * because only them store as drv_data pointer to struct ux500_charger. | ||
| 17 | */ | ||
| 18 | #define psy_to_ux500_charger(x) power_supply_get_drvdata(psy) | ||
| 14 | 19 | ||
| 15 | /* Forward declaration */ | 20 | /* Forward declaration */ |
| 16 | struct ux500_charger; | 21 | struct ux500_charger; |
| @@ -35,7 +40,7 @@ struct ux500_charger_ops { | |||
| 35 | * @power_path USB power path support | 40 | * @power_path USB power path support |
| 36 | */ | 41 | */ |
| 37 | struct ux500_charger { | 42 | struct ux500_charger { |
| 38 | struct power_supply psy; | 43 | struct power_supply *psy; |
| 39 | struct ux500_charger_ops ops; | 44 | struct ux500_charger_ops ops; |
| 40 | int max_out_volt; | 45 | int max_out_volt; |
| 41 | int max_out_curr; | 46 | int max_out_curr; |
diff --git a/include/linux/mfd/rt5033.h b/include/linux/mfd/rt5033.h index 010cff49a98e..6cff5cf458d2 100644 --- a/include/linux/mfd/rt5033.h +++ b/include/linux/mfd/rt5033.h | |||
| @@ -39,7 +39,7 @@ struct rt5033_battery { | |||
| 39 | struct i2c_client *client; | 39 | struct i2c_client *client; |
| 40 | struct rt5033_dev *rt5033; | 40 | struct rt5033_dev *rt5033; |
| 41 | struct regmap *regmap; | 41 | struct regmap *regmap; |
| 42 | struct power_supply psy; | 42 | struct power_supply *psy; |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | /* RT5033 charger platform data */ | 45 | /* RT5033 charger platform data */ |
diff --git a/include/linux/mfd/wm8350/supply.h b/include/linux/mfd/wm8350/supply.h index 2b9479310bbd..8dc93673e34a 100644 --- a/include/linux/mfd/wm8350/supply.h +++ b/include/linux/mfd/wm8350/supply.h | |||
| @@ -123,9 +123,9 @@ struct wm8350_charger_policy { | |||
| 123 | 123 | ||
| 124 | struct wm8350_power { | 124 | struct wm8350_power { |
| 125 | struct platform_device *pdev; | 125 | struct platform_device *pdev; |
| 126 | struct power_supply battery; | 126 | struct power_supply *battery; |
| 127 | struct power_supply usb; | 127 | struct power_supply *usb; |
| 128 | struct power_supply ac; | 128 | struct power_supply *ac; |
| 129 | struct wm8350_charger_policy *policy; | 129 | struct wm8350_charger_policy *policy; |
| 130 | 130 | ||
| 131 | int rev_g_coeff; | 131 | int rev_g_coeff; |
diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h index 416ebeb6ee1e..eadf28cb2fc9 100644 --- a/include/linux/power/charger-manager.h +++ b/include/linux/power/charger-manager.h | |||
| @@ -242,7 +242,8 @@ struct charger_manager { | |||
| 242 | int emergency_stop; | 242 | int emergency_stop; |
| 243 | 243 | ||
| 244 | char psy_name_buf[PSY_NAME_MAX + 1]; | 244 | char psy_name_buf[PSY_NAME_MAX + 1]; |
| 245 | struct power_supply charger_psy; | 245 | struct power_supply_desc charger_psy_desc; |
| 246 | struct power_supply *charger_psy; | ||
| 246 | 247 | ||
| 247 | u64 charging_start_time; | 248 | u64 charging_start_time; |
| 248 | u64 charging_end_time; | 249 | u64 charging_end_time; |
diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h index 89dd84f47c6e..cf112b4075c8 100644 --- a/include/linux/power/max17042_battery.h +++ b/include/linux/power/max17042_battery.h | |||
| @@ -126,7 +126,14 @@ enum max17047_register { | |||
| 126 | MAX17047_QRTbl30 = 0x42, | 126 | MAX17047_QRTbl30 = 0x42, |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | enum max170xx_chip_type {MAX17042, MAX17047}; | 129 | enum max170xx_chip_type { |
| 130 | MAXIM_DEVICE_TYPE_UNKNOWN = 0, | ||
| 131 | MAXIM_DEVICE_TYPE_MAX17042, | ||
| 132 | MAXIM_DEVICE_TYPE_MAX17047, | ||
| 133 | MAXIM_DEVICE_TYPE_MAX17050, | ||
| 134 | |||
| 135 | MAXIM_DEVICE_TYPE_NUM | ||
| 136 | }; | ||
| 130 | 137 | ||
| 131 | /* | 138 | /* |
| 132 | * used for setting a register to a desired value | 139 | * used for setting a register to a desired value |
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 096dbced02ac..75a1dd8dc56e 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #ifndef __LINUX_POWER_SUPPLY_H__ | 13 | #ifndef __LINUX_POWER_SUPPLY_H__ |
| 14 | #define __LINUX_POWER_SUPPLY_H__ | 14 | #define __LINUX_POWER_SUPPLY_H__ |
| 15 | 15 | ||
| 16 | #include <linux/device.h> | ||
| 16 | #include <linux/workqueue.h> | 17 | #include <linux/workqueue.h> |
| 17 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
| 18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
| @@ -173,22 +174,32 @@ union power_supply_propval { | |||
| 173 | const char *strval; | 174 | const char *strval; |
| 174 | }; | 175 | }; |
| 175 | 176 | ||
| 176 | struct device; | ||
| 177 | struct device_node; | 177 | struct device_node; |
| 178 | struct power_supply; | ||
| 178 | 179 | ||
| 179 | struct power_supply { | 180 | /* Run-time specific power supply configuration */ |
| 180 | const char *name; | 181 | struct power_supply_config { |
| 181 | enum power_supply_type type; | 182 | struct device_node *of_node; |
| 182 | enum power_supply_property *properties; | 183 | /* Driver private data */ |
| 183 | size_t num_properties; | 184 | void *drv_data; |
| 184 | 185 | ||
| 185 | char **supplied_to; | 186 | char **supplied_to; |
| 186 | size_t num_supplicants; | 187 | size_t num_supplicants; |
| 188 | }; | ||
| 187 | 189 | ||
| 188 | char **supplied_from; | 190 | /* Description of power supply */ |
| 189 | size_t num_supplies; | 191 | struct power_supply_desc { |
| 190 | struct device_node *of_node; | 192 | const char *name; |
| 193 | enum power_supply_type type; | ||
| 194 | enum power_supply_property *properties; | ||
| 195 | size_t num_properties; | ||
| 191 | 196 | ||
| 197 | /* | ||
| 198 | * Functions for drivers implementing power supply class. | ||
| 199 | * These shouldn't be called directly by other drivers for accessing | ||
| 200 | * this power supply. Instead use power_supply_*() functions (for | ||
| 201 | * example power_supply_get_property()). | ||
| 202 | */ | ||
| 192 | int (*get_property)(struct power_supply *psy, | 203 | int (*get_property)(struct power_supply *psy, |
| 193 | enum power_supply_property psp, | 204 | enum power_supply_property psp, |
| 194 | union power_supply_propval *val); | 205 | union power_supply_propval *val); |
| @@ -208,12 +219,27 @@ struct power_supply { | |||
| 208 | bool no_thermal; | 219 | bool no_thermal; |
| 209 | /* For APM emulation, think legacy userspace. */ | 220 | /* For APM emulation, think legacy userspace. */ |
| 210 | int use_for_apm; | 221 | int use_for_apm; |
| 222 | }; | ||
| 223 | |||
| 224 | struct power_supply { | ||
| 225 | const struct power_supply_desc *desc; | ||
| 226 | |||
| 227 | char **supplied_to; | ||
| 228 | size_t num_supplicants; | ||
| 229 | |||
| 230 | char **supplied_from; | ||
| 231 | size_t num_supplies; | ||
| 232 | struct device_node *of_node; | ||
| 233 | |||
| 234 | /* Driver private data */ | ||
| 235 | void *drv_data; | ||
| 211 | 236 | ||
| 212 | /* private */ | 237 | /* private */ |
| 213 | struct device *dev; | 238 | struct device dev; |
| 214 | struct work_struct changed_work; | 239 | struct work_struct changed_work; |
| 215 | spinlock_t changed_lock; | 240 | spinlock_t changed_lock; |
| 216 | bool changed; | 241 | bool changed; |
| 242 | atomic_t use_cnt; | ||
| 217 | #ifdef CONFIG_THERMAL | 243 | #ifdef CONFIG_THERMAL |
| 218 | struct thermal_zone_device *tzd; | 244 | struct thermal_zone_device *tzd; |
| 219 | struct thermal_cooling_device *tcd; | 245 | struct thermal_cooling_device *tcd; |
| @@ -256,6 +282,7 @@ extern struct atomic_notifier_head power_supply_notifier; | |||
| 256 | extern int power_supply_reg_notifier(struct notifier_block *nb); | 282 | extern int power_supply_reg_notifier(struct notifier_block *nb); |
| 257 | extern void power_supply_unreg_notifier(struct notifier_block *nb); | 283 | extern void power_supply_unreg_notifier(struct notifier_block *nb); |
| 258 | extern struct power_supply *power_supply_get_by_name(const char *name); | 284 | extern struct power_supply *power_supply_get_by_name(const char *name); |
| 285 | extern void power_supply_put(struct power_supply *psy); | ||
| 259 | #ifdef CONFIG_OF | 286 | #ifdef CONFIG_OF |
| 260 | extern struct power_supply *power_supply_get_by_phandle(struct device_node *np, | 287 | extern struct power_supply *power_supply_get_by_phandle(struct device_node *np, |
| 261 | const char *property); | 288 | const char *property); |
| @@ -274,13 +301,36 @@ extern int power_supply_is_system_supplied(void); | |||
| 274 | static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } | 301 | static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } |
| 275 | #endif | 302 | #endif |
| 276 | 303 | ||
| 277 | extern int power_supply_register(struct device *parent, | 304 | extern int power_supply_get_property(struct power_supply *psy, |
| 278 | struct power_supply *psy); | 305 | enum power_supply_property psp, |
| 279 | extern int power_supply_register_no_ws(struct device *parent, | 306 | union power_supply_propval *val); |
| 280 | struct power_supply *psy); | 307 | extern int power_supply_set_property(struct power_supply *psy, |
| 308 | enum power_supply_property psp, | ||
| 309 | const union power_supply_propval *val); | ||
| 310 | extern int power_supply_property_is_writeable(struct power_supply *psy, | ||
| 311 | enum power_supply_property psp); | ||
| 312 | extern void power_supply_external_power_changed(struct power_supply *psy); | ||
| 313 | |||
| 314 | extern struct power_supply *__must_check | ||
| 315 | power_supply_register(struct device *parent, | ||
| 316 | const struct power_supply_desc *desc, | ||
| 317 | const struct power_supply_config *cfg); | ||
| 318 | extern struct power_supply *__must_check | ||
| 319 | power_supply_register_no_ws(struct device *parent, | ||
| 320 | const struct power_supply_desc *desc, | ||
| 321 | const struct power_supply_config *cfg); | ||
| 322 | extern struct power_supply *__must_check | ||
| 323 | devm_power_supply_register(struct device *parent, | ||
| 324 | const struct power_supply_desc *desc, | ||
| 325 | const struct power_supply_config *cfg); | ||
| 326 | extern struct power_supply *__must_check | ||
| 327 | devm_power_supply_register_no_ws(struct device *parent, | ||
| 328 | const struct power_supply_desc *desc, | ||
| 329 | const struct power_supply_config *cfg); | ||
| 281 | extern void power_supply_unregister(struct power_supply *psy); | 330 | extern void power_supply_unregister(struct power_supply *psy); |
| 282 | extern int power_supply_powers(struct power_supply *psy, struct device *dev); | 331 | extern int power_supply_powers(struct power_supply *psy, struct device *dev); |
| 283 | 332 | ||
| 333 | extern void *power_supply_get_drvdata(struct power_supply *psy); | ||
| 284 | /* For APM emulation, think legacy userspace. */ | 334 | /* For APM emulation, think legacy userspace. */ |
| 285 | extern struct class *power_supply_class; | 335 | extern struct class *power_supply_class; |
| 286 | 336 | ||
