Merge tag 'for-v6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull power supply and reset updates from Sebastian Reichel:
"Power-supply core:
- battery-info: replace any DT specific bits with fwnode usage
- replace any device-tree code with generic fwnode based handling

Power-supply drivers:
- ug3105_battery: use battery-info API
- qcom_battmgr: report capacity
- qcom_battmgr: support LiPo battery reporting
- add missing missing power-supply ref to a bunch of DT bindings
- update drivers regarding pm_runtime_autosuspend() usage
- misc minor fixes and cleanups

Reset drivers:
- misc minor cleanups"

* tag 'for-v6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (32 commits)
power: supply: core: fix static checker warning
power: supply: twl4030_charger: Remove redundant pm_runtime_mark_last_busy() calls
power: supply: bq24190: Remove redundant pm_runtime_mark_last_busy() calls
MAINTAINERS: rectify file entry in QUALCOMM SMB CHARGER DRIVER
power: supply: max1720x correct capacity computation
MAINTAINERS: add myself as smbx charger driver maintainer
power: supply: pmi8998_charger: rename to qcom_smbx
power: supply: qcom_pmi8998_charger: fix wakeirq
power: supply: max14577: Handle NULL pdata when CONFIG_OF is not set
power: return the correct error code
power: reset: POWER_RESET_TORADEX_EC should depend on ARCH_MXC
power: supply: cpcap-charger: Fix null check for power_supply_get_by_name
power: supply: bq25980_charger: Constify reg_default array
power: supply: bq256xx_charger: Constify reg_default array
power: reset: at91-sama5d2_shdwc: Refactor wake-up source logging to use dev_info
power: reset: qcom-pon: Rename variables to use generic naming
power: supply: qcom_battmgr: Add lithium-polymer entry
power: supply: qcom_battmgr: Report battery capacity
power: supply: bq24190: Free battery_info
power: supply: ug3105_battery: Switch to power_supply_batinfo_ocv2cap()
...

+285 -333
-1
Documentation/devicetree/bindings/power/supply/bq24190.yaml
··· 48 battery device. 49 50 monitored-battery: 51 - $ref: /schemas/types.yaml#/definitions/phandle 52 description: | 53 phandle to a "simple-battery" compatible node. 54
··· 48 battery device. 49 50 monitored-battery: 51 description: | 52 phandle to a "simple-battery" compatible node. 53
+4 -3
Documentation/devicetree/bindings/power/supply/bq2515x.yaml
··· 53 minimum: 50000 54 maximum: 500000 55 56 - monitored-battery: 57 - $ref: /schemas/types.yaml#/definitions/phandle 58 - description: phandle to the battery node being monitored 59 60 required: 61 - compatible 62 - reg 63 - monitored-battery 64 65 additionalProperties: false 66
··· 53 minimum: 50000 54 maximum: 500000 55 56 + monitored-battery: true 57 58 required: 59 - compatible 60 - reg 61 - monitored-battery 62 + 63 + allOf: 64 + - $ref: power-supply.yaml# 65 66 additionalProperties: false 67
+2 -3
Documentation/devicetree/bindings/power/supply/bq256xx.yaml
··· 58 minimum: 100000 59 maximum: 3200000 60 61 - monitored-battery: 62 - $ref: /schemas/types.yaml#/definitions/phandle 63 - description: phandle to the battery node being monitored 64 65 interrupts: 66 maxItems: 1 ··· 76 - monitored-battery 77 78 allOf: 79 - if: 80 properties: 81 compatible:
··· 58 minimum: 100000 59 maximum: 3200000 60 61 + monitored-battery: true 62 63 interrupts: 64 maxItems: 1 ··· 78 - monitored-battery 79 80 allOf: 81 + - $ref: power-supply.yaml# 82 - if: 83 properties: 84 compatible:
+1 -3
Documentation/devicetree/bindings/power/supply/bq25980.yaml
··· 73 description: | 74 Indicates that the device state has changed. 75 76 - monitored-battery: 77 - $ref: /schemas/types.yaml#/definitions/phandle 78 - description: phandle to the battery node being monitored 79 80 required: 81 - compatible
··· 73 description: | 74 Indicates that the device state has changed. 75 76 + monitored-battery: true 77 78 required: 79 - compatible
+1 -4
Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml
··· 43 minItems: 1 44 maxItems: 8 # Should be enough 45 46 - monitored-battery: 47 - description: 48 - Specifies the phandle of a simple-battery connected to this gauge 49 - $ref: /schemas/types.yaml#/definitions/phandle 50 51 required: 52 - compatible
··· 43 minItems: 1 44 maxItems: 8 # Should be enough 45 46 + monitored-battery: true 47 48 required: 49 - compatible
+4 -3
Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml
··· 38 - const: usbin_i 39 - const: usbin_v 40 41 - monitored-battery: 42 - description: phandle to the simple-battery node 43 - $ref: /schemas/types.yaml#/definitions/phandle 44 45 required: 46 - compatible ··· 48 - io-channels 49 - io-channel-names 50 - monitored-battery 51 52 additionalProperties: false 53
··· 38 - const: usbin_i 39 - const: usbin_v 40 41 + monitored-battery: true 42 43 required: 44 - compatible ··· 50 - io-channels 51 - io-channel-names 52 - monitored-battery 53 + 54 + allOf: 55 + - $ref: power-supply.yaml# 56 57 additionalProperties: false 58
+3 -1
Documentation/devicetree/bindings/power/supply/richtek,rt5033-charger.yaml
··· 18 const: richtek,rt5033-charger 19 20 monitored-battery: 21 - $ref: /schemas/types.yaml#/definitions/phandle 22 description: | 23 Phandle to the monitored battery according to battery.yaml. The battery 24 node needs to contain five parameters. ··· 52 53 required: 54 - monitored-battery 55 56 additionalProperties: false 57
··· 18 const: richtek,rt5033-charger 19 20 monitored-battery: 21 description: | 22 Phandle to the monitored battery according to battery.yaml. The battery 23 node needs to contain five parameters. ··· 53 54 required: 55 - monitored-battery 56 + 57 + allOf: 58 + - $ref: power-supply.yaml# 59 60 additionalProperties: false 61
+1 -3
Documentation/devicetree/bindings/power/supply/stericsson,ab8500-btemp.yaml
··· 17 compatible: 18 const: stericsson,ab8500-btemp 19 20 - monitored-battery: 21 - $ref: /schemas/types.yaml#/definitions/phandle 22 - description: phandle to battery node 23 24 battery: 25 $ref: /schemas/types.yaml#/definitions/phandle
··· 17 compatible: 18 const: stericsson,ab8500-btemp 19 20 + monitored-battery: true 21 22 battery: 23 $ref: /schemas/types.yaml#/definitions/phandle
+1 -3
Documentation/devicetree/bindings/power/supply/stericsson,ab8500-chargalg.yaml
··· 17 compatible: 18 const: stericsson,ab8500-chargalg 19 20 - monitored-battery: 21 - $ref: /schemas/types.yaml#/definitions/phandle 22 - description: phandle to battery node 23 24 battery: 25 $ref: /schemas/types.yaml#/definitions/phandle
··· 17 compatible: 18 const: stericsson,ab8500-chargalg 19 20 + monitored-battery: true 21 22 battery: 23 $ref: /schemas/types.yaml#/definitions/phandle
+1 -3
Documentation/devicetree/bindings/power/supply/stericsson,ab8500-charger.yaml
··· 17 compatible: 18 const: stericsson,ab8500-charger 19 20 - monitored-battery: 21 - $ref: /schemas/types.yaml#/definitions/phandle 22 - description: phandle to battery node 23 24 battery: 25 $ref: /schemas/types.yaml#/definitions/phandle
··· 17 compatible: 18 const: stericsson,ab8500-charger 19 20 + monitored-battery: true 21 22 battery: 23 $ref: /schemas/types.yaml#/definitions/phandle
+1 -3
Documentation/devicetree/bindings/power/supply/stericsson,ab8500-fg.yaml
··· 17 compatible: 18 const: stericsson,ab8500-fg 19 20 - monitored-battery: 21 - $ref: /schemas/types.yaml#/definitions/phandle 22 - description: phandle to battery node 23 24 battery: 25 $ref: /schemas/types.yaml#/definitions/phandle
··· 17 compatible: 18 const: stericsson,ab8500-fg 19 20 + monitored-battery: true 21 22 battery: 23 $ref: /schemas/types.yaml#/definitions/phandle
+2 -3
Documentation/devicetree/bindings/power/supply/summit,smb347-charger.yaml
··· 23 interrupts: 24 maxItems: 1 25 26 - monitored-battery: 27 - description: phandle to the battery node 28 - $ref: /schemas/types.yaml#/definitions/phandle 29 30 summit,enable-usb-charging: 31 type: boolean ··· 92 unevaluatedProperties: false 93 94 allOf: 95 - if: 96 properties: 97 compatible:
··· 23 interrupts: 24 maxItems: 1 25 26 + monitored-battery: true 27 28 summit,enable-usb-charging: 29 type: boolean ··· 94 unevaluatedProperties: false 95 96 allOf: 97 + - $ref: power-supply.yaml# 98 - if: 99 properties: 100 compatible:
+1 -5
Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
··· 26 - const: x-powers,axp813-battery-power-supply 27 - const: x-powers,axp813-battery-power-supply 28 29 - monitored-battery: 30 - description: 31 - Specifies the phandle of an optional simple-battery connected to 32 - this gauge. 33 - $ref: /schemas/types.yaml#/definitions/phandle 34 35 x-powers,no-thermistor: 36 type: boolean
··· 26 - const: x-powers,axp813-battery-power-supply 27 - const: x-powers,axp813-battery-power-supply 28 29 + monitored-battery: true 30 31 x-powers,no-thermistor: 32 type: boolean
+7
MAINTAINERS
··· 20815 F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml 20816 F: drivers/mtd/nand/raw/qcom_nandc.c 20817 20818 QUALCOMM QSEECOM DRIVER 20819 M: Maximilian Luz <luzmaximilian@gmail.com> 20820 L: linux-arm-msm@vger.kernel.org
··· 20815 F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml 20816 F: drivers/mtd/nand/raw/qcom_nandc.c 20817 20818 + QUALCOMM SMB CHARGER DRIVER 20819 + M: Casey Connolly <casey.connolly@linaro.org> 20820 + L: linux-arm-msm@vger.kernel.org 20821 + S: Maintained 20822 + F: Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml 20823 + F: drivers/power/supply/qcom_smbx.c 20824 + 20825 QUALCOMM QSEECOM DRIVER 20826 M: Maximilian Luz <luzmaximilian@gmail.com> 20827 L: linux-arm-msm@vger.kernel.org
+1 -1
drivers/phy/allwinner/phy-sun4i-usb.c
··· 754 } 755 756 if (of_property_present(np, "usb0_vbus_power-supply")) { 757 - data->vbus_power_supply = devm_power_supply_get_by_phandle(dev, 758 "usb0_vbus_power-supply"); 759 if (IS_ERR(data->vbus_power_supply)) { 760 dev_err(dev, "Couldn't get the VBUS power supply\n");
··· 754 } 755 756 if (of_property_present(np, "usb0_vbus_power-supply")) { 757 + data->vbus_power_supply = devm_power_supply_get_by_reference(dev, 758 "usb0_vbus_power-supply"); 759 if (IS_ERR(data->vbus_power_supply)) { 760 dev_err(dev, "Couldn't get the VBUS power supply\n");
+1
drivers/power/reset/Kconfig
··· 227 228 config POWER_RESET_TORADEX_EC 229 tristate "Toradex Embedded Controller power-off and reset driver" 230 depends on I2C 231 select REGMAP_I2C 232 help
··· 227 228 config POWER_RESET_TORADEX_EC 229 tristate "Toradex Embedded Controller power-off and reset driver" 230 + depends on ARCH_MXC || COMPILE_TEST 231 depends on I2C 232 select REGMAP_I2C 233 help
+1 -1
drivers/power/reset/at91-sama5d2_shdwc.c
··· 129 else if (SHDW_RTTWK(reg, &rcfg->shdwc)) 130 reason = "RTT"; 131 132 - pr_info("AT91: Wake-Up source: %s\n", reason); 133 } 134 135 static void at91_poweroff(void)
··· 129 else if (SHDW_RTTWK(reg, &rcfg->shdwc)) 130 reason = "RTT"; 131 132 + dev_info(&pdev->dev, "Wake-Up source: %s\n", reason); 133 } 134 135 static void at91_poweroff(void)
+15 -15
drivers/power/reset/qcom-pon.c
··· 19 20 #define NO_REASON_SHIFT 0 21 22 - struct pm8916_pon { 23 struct device *dev; 24 struct regmap *regmap; 25 u32 baseaddr; ··· 27 long reason_shift; 28 }; 29 30 - static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot, 31 unsigned int magic) 32 { 33 - struct pm8916_pon *pon = container_of 34 - (reboot, struct pm8916_pon, reboot_mode); 35 int ret; 36 37 ret = regmap_update_bits(pon->regmap, ··· 44 return ret; 45 } 46 47 - static int pm8916_pon_probe(struct platform_device *pdev) 48 { 49 - struct pm8916_pon *pon; 50 long reason_shift; 51 int error; 52 ··· 72 if (reason_shift != NO_REASON_SHIFT) { 73 pon->reboot_mode.dev = &pdev->dev; 74 pon->reason_shift = reason_shift; 75 - pon->reboot_mode.write = pm8916_reboot_mode_write; 76 error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode); 77 if (error) { 78 dev_err(&pdev->dev, "can't register reboot mode\n"); ··· 85 return devm_of_platform_populate(&pdev->dev); 86 } 87 88 - static const struct of_device_id pm8916_pon_id_table[] = { 89 { .compatible = "qcom,pm8916-pon", .data = (void *)GEN1_REASON_SHIFT }, 90 { .compatible = "qcom,pm8941-pon", .data = (void *)NO_REASON_SHIFT }, 91 { .compatible = "qcom,pms405-pon", .data = (void *)GEN1_REASON_SHIFT }, ··· 93 { .compatible = "qcom,pmk8350-pon", .data = (void *)GEN2_REASON_SHIFT }, 94 { } 95 }; 96 - MODULE_DEVICE_TABLE(of, pm8916_pon_id_table); 97 98 - static struct platform_driver pm8916_pon_driver = { 99 - .probe = pm8916_pon_probe, 100 .driver = { 101 - .name = "pm8916-pon", 102 - .of_match_table = pm8916_pon_id_table, 103 }, 104 }; 105 - module_platform_driver(pm8916_pon_driver); 106 107 - MODULE_DESCRIPTION("pm8916 Power On driver"); 108 MODULE_LICENSE("GPL v2");
··· 19 20 #define NO_REASON_SHIFT 0 21 22 + struct qcom_pon { 23 struct device *dev; 24 struct regmap *regmap; 25 u32 baseaddr; ··· 27 long reason_shift; 28 }; 29 30 + static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot, 31 unsigned int magic) 32 { 33 + struct qcom_pon *pon = container_of 34 + (reboot, struct qcom_pon, reboot_mode); 35 int ret; 36 37 ret = regmap_update_bits(pon->regmap, ··· 44 return ret; 45 } 46 47 + static int qcom_pon_probe(struct platform_device *pdev) 48 { 49 + struct qcom_pon *pon; 50 long reason_shift; 51 int error; 52 ··· 72 if (reason_shift != NO_REASON_SHIFT) { 73 pon->reboot_mode.dev = &pdev->dev; 74 pon->reason_shift = reason_shift; 75 + pon->reboot_mode.write = qcom_pon_reboot_mode_write; 76 error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode); 77 if (error) { 78 dev_err(&pdev->dev, "can't register reboot mode\n"); ··· 85 return devm_of_platform_populate(&pdev->dev); 86 } 87 88 + static const struct of_device_id qcom_pon_id_table[] = { 89 { .compatible = "qcom,pm8916-pon", .data = (void *)GEN1_REASON_SHIFT }, 90 { .compatible = "qcom,pm8941-pon", .data = (void *)NO_REASON_SHIFT }, 91 { .compatible = "qcom,pms405-pon", .data = (void *)GEN1_REASON_SHIFT }, ··· 93 { .compatible = "qcom,pmk8350-pon", .data = (void *)GEN2_REASON_SHIFT }, 94 { } 95 }; 96 + MODULE_DEVICE_TABLE(of, qcom_pon_id_table); 97 98 + static struct platform_driver qcom_pon_driver = { 99 + .probe = qcom_pon_probe, 100 .driver = { 101 + .name = "qcom-pon", 102 + .of_match_table = qcom_pon_id_table, 103 }, 104 }; 105 + module_platform_driver(qcom_pon_driver); 106 107 + MODULE_DESCRIPTION("Qualcomm Power On driver"); 108 MODULE_LICENSE("GPL v2");
+1 -1
drivers/power/supply/Makefile
··· 120 obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o 121 obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o 122 obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o 123 - obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_pmi8998_charger.o 124 obj-$(CONFIG_FUEL_GAUGE_MM8013) += mm8013.o
··· 120 obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o 121 obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o 122 obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o 123 + obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_smbx.o 124 obj-$(CONFIG_FUEL_GAUGE_MM8013) += mm8013.o
+1 -1
drivers/power/supply/bq2415x_charger.c
··· 1674 /* Query for initial reported_mode and set it */ 1675 if (bq->nb.notifier_call) { 1676 if (np) { 1677 - notify_psy = power_supply_get_by_phandle(np, 1678 "ti,usb-charger-detection"); 1679 if (IS_ERR(notify_psy)) 1680 notify_psy = NULL;
··· 1674 /* Query for initial reported_mode and set it */ 1675 if (bq->nb.notifier_call) { 1676 if (np) { 1677 + notify_psy = power_supply_get_by_reference(of_fwnode_handle(np), 1678 "ti,usb-charger-detection"); 1679 if (IS_ERR(notify_psy)) 1680 notify_psy = NULL;
+2 -14
drivers/power/supply/bq24190_charger.c
··· 504 else 505 count = sysfs_emit(buf, "%hhx\n", v); 506 507 - pm_runtime_mark_last_busy(bdi->dev); 508 pm_runtime_put_autosuspend(bdi->dev); 509 510 return count; ··· 534 if (ret) 535 count = ret; 536 537 - pm_runtime_mark_last_busy(bdi->dev); 538 pm_runtime_put_autosuspend(bdi->dev); 539 540 return count; ··· 560 else 561 ret = bq24190_charger_set_charge_type(bdi, &val); 562 563 - pm_runtime_mark_last_busy(bdi->dev); 564 pm_runtime_put_autosuspend(bdi->dev); 565 566 return ret; ··· 602 } 603 604 out: 605 - pm_runtime_mark_last_busy(bdi->dev); 606 pm_runtime_put_autosuspend(bdi->dev); 607 608 return ret; ··· 634 BQ24190_REG_POC_CHG_CONFIG_MASK, 635 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val); 636 637 - pm_runtime_mark_last_busy(bdi->dev); 638 pm_runtime_put_autosuspend(bdi->dev); 639 640 if (ret) ··· 670 BQ24296_REG_POC_OTG_CONFIG_MASK, 671 BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val); 672 673 - pm_runtime_mark_last_busy(bdi->dev); 674 pm_runtime_put_autosuspend(bdi->dev); 675 676 if (ret) ··· 1370 ret = -ENODATA; 1371 } 1372 1373 - pm_runtime_mark_last_busy(bdi->dev); 1374 pm_runtime_put_autosuspend(bdi->dev); 1375 1376 return ret; ··· 1412 ret = -EINVAL; 1413 } 1414 1415 - pm_runtime_mark_last_busy(bdi->dev); 1416 pm_runtime_put_autosuspend(bdi->dev); 1417 1418 return ret; ··· 1674 ret = -ENODATA; 1675 } 1676 1677 - pm_runtime_mark_last_busy(bdi->dev); 1678 pm_runtime_put_autosuspend(bdi->dev); 1679 1680 return ret; ··· 1704 ret = -EINVAL; 1705 } 1706 1707 - pm_runtime_mark_last_busy(bdi->dev); 1708 pm_runtime_put_autosuspend(bdi->dev); 1709 1710 return ret; ··· 1851 return IRQ_NONE; 1852 } 1853 bq24190_check_status(bdi); 1854 - pm_runtime_mark_last_busy(bdi->dev); 1855 pm_runtime_put_autosuspend(bdi->dev); 1856 bdi->irq_event = false; 1857 ··· 1972 v = info->constant_charge_voltage_max_uv; 1973 if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max) 1974 bdi->vreg = bdi->vreg_max = v; 1975 } 1976 1977 return 0; ··· 2177 2178 enable_irq_wake(client->irq); 2179 2180 - pm_runtime_mark_last_busy(dev); 2181 pm_runtime_put_autosuspend(dev); 2182 2183 return 0; ··· 2263 bq24190_register_reset(bdi); 2264 2265 if (error >= 0) { 2266 - pm_runtime_mark_last_busy(bdi->dev); 2267 pm_runtime_put_autosuspend(bdi->dev); 2268 } 2269 ··· 2287 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); 2288 2289 if (error >= 0) { 2290 - pm_runtime_mark_last_busy(bdi->dev); 2291 pm_runtime_put_autosuspend(bdi->dev); 2292 } 2293
··· 504 else 505 count = sysfs_emit(buf, "%hhx\n", v); 506 507 pm_runtime_put_autosuspend(bdi->dev); 508 509 return count; ··· 535 if (ret) 536 count = ret; 537 538 pm_runtime_put_autosuspend(bdi->dev); 539 540 return count; ··· 562 else 563 ret = bq24190_charger_set_charge_type(bdi, &val); 564 565 pm_runtime_put_autosuspend(bdi->dev); 566 567 return ret; ··· 605 } 606 607 out: 608 pm_runtime_put_autosuspend(bdi->dev); 609 610 return ret; ··· 638 BQ24190_REG_POC_CHG_CONFIG_MASK, 639 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val); 640 641 pm_runtime_put_autosuspend(bdi->dev); 642 643 if (ret) ··· 675 BQ24296_REG_POC_OTG_CONFIG_MASK, 676 BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val); 677 678 pm_runtime_put_autosuspend(bdi->dev); 679 680 if (ret) ··· 1376 ret = -ENODATA; 1377 } 1378 1379 pm_runtime_put_autosuspend(bdi->dev); 1380 1381 return ret; ··· 1419 ret = -EINVAL; 1420 } 1421 1422 pm_runtime_put_autosuspend(bdi->dev); 1423 1424 return ret; ··· 1682 ret = -ENODATA; 1683 } 1684 1685 pm_runtime_put_autosuspend(bdi->dev); 1686 1687 return ret; ··· 1713 ret = -EINVAL; 1714 } 1715 1716 pm_runtime_put_autosuspend(bdi->dev); 1717 1718 return ret; ··· 1861 return IRQ_NONE; 1862 } 1863 bq24190_check_status(bdi); 1864 pm_runtime_put_autosuspend(bdi->dev); 1865 bdi->irq_event = false; 1866 ··· 1983 v = info->constant_charge_voltage_max_uv; 1984 if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max) 1985 bdi->vreg = bdi->vreg_max = v; 1986 + 1987 + power_supply_put_battery_info(bdi->charger, info); 1988 } 1989 1990 return 0; ··· 2186 2187 enable_irq_wake(client->irq); 2188 2189 pm_runtime_put_autosuspend(dev); 2190 2191 return 0; ··· 2273 bq24190_register_reset(bdi); 2274 2275 if (error >= 0) { 2276 pm_runtime_put_autosuspend(bdi->dev); 2277 } 2278 ··· 2298 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); 2299 2300 if (error >= 0) { 2301 pm_runtime_put_autosuspend(bdi->dev); 2302 } 2303
+3 -3
drivers/power/supply/bq256xx_charger.c
··· 387 } 388 } 389 390 - static struct reg_default bq2560x_reg_defs[] = { 391 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 392 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 393 {BQ256XX_CHARGE_CURRENT_LIMIT, 0xa2}, ··· 398 {BQ256XX_CHARGER_CONTROL_3, 0x4c}, 399 }; 400 401 - static struct reg_default bq25611d_reg_defs[] = { 402 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 403 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 404 {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91}, ··· 411 {BQ256XX_CHARGER_CONTROL_4, 0x75}, 412 }; 413 414 - static struct reg_default bq25618_619_reg_defs[] = { 415 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 416 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 417 {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},
··· 387 } 388 } 389 390 + static const struct reg_default bq2560x_reg_defs[] = { 391 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 392 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 393 {BQ256XX_CHARGE_CURRENT_LIMIT, 0xa2}, ··· 398 {BQ256XX_CHARGER_CONTROL_3, 0x4c}, 399 }; 400 401 + static const struct reg_default bq25611d_reg_defs[] = { 402 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 403 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 404 {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91}, ··· 411 {BQ256XX_CHARGER_CONTROL_4, 0x75}, 412 }; 413 414 + static const struct reg_default bq25618_619_reg_defs[] = { 415 {BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, 416 {BQ256XX_CHARGER_CONTROL_0, 0x1a}, 417 {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},
+3 -3
drivers/power/supply/bq25980_charger.c
··· 104 int watchdog_timer; 105 }; 106 107 - static struct reg_default bq25980_reg_defs[] = { 108 {BQ25980_BATOVP, 0x5A}, 109 {BQ25980_BATOVP_ALM, 0x46}, 110 {BQ25980_BATOCP, 0x51}, ··· 159 {BQ25980_CHRGR_CTRL_6, 0x0}, 160 }; 161 162 - static struct reg_default bq25975_reg_defs[] = { 163 {BQ25980_BATOVP, 0x5A}, 164 {BQ25980_BATOVP_ALM, 0x46}, 165 {BQ25980_BATOCP, 0x51}, ··· 214 {BQ25980_CHRGR_CTRL_6, 0x0}, 215 }; 216 217 - static struct reg_default bq25960_reg_defs[] = { 218 {BQ25980_BATOVP, 0x5A}, 219 {BQ25980_BATOVP_ALM, 0x46}, 220 {BQ25980_BATOCP, 0x51},
··· 104 int watchdog_timer; 105 }; 106 107 + static const struct reg_default bq25980_reg_defs[] = { 108 {BQ25980_BATOVP, 0x5A}, 109 {BQ25980_BATOVP_ALM, 0x46}, 110 {BQ25980_BATOCP, 0x51}, ··· 159 {BQ25980_CHRGR_CTRL_6, 0x0}, 160 }; 161 162 + static const struct reg_default bq25975_reg_defs[] = { 163 {BQ25980_BATOVP, 0x5A}, 164 {BQ25980_BATOVP_ALM, 0x46}, 165 {BQ25980_BATOCP, 0x51}, ··· 214 {BQ25980_CHRGR_CTRL_6, 0x0}, 215 }; 216 217 + static const struct reg_default bq25960_reg_defs[] = { 218 {BQ25980_BATOVP, 0x5A}, 219 {BQ25980_BATOVP_ALM, 0x46}, 220 {BQ25980_BATOCP, 0x51},
+2 -3
drivers/power/supply/cpcap-charger.c
··· 689 struct power_supply *battery; 690 691 battery = power_supply_get_by_name("battery"); 692 - if (IS_ERR_OR_NULL(battery)) { 693 - dev_err(ddata->dev, "battery power_supply not available %li\n", 694 - PTR_ERR(battery)); 695 return; 696 } 697
··· 689 struct power_supply *battery; 690 691 battery = power_supply_get_by_name("battery"); 692 + if (!battery) { 693 + dev_err(ddata->dev, "battery power_supply not available\n"); 694 return; 695 } 696
+2 -2
drivers/power/supply/max14577_charger.c
··· 501 static struct max14577_charger_platform_data *max14577_charger_dt_init( 502 struct platform_device *pdev) 503 { 504 - return NULL; 505 } 506 #endif /* CONFIG_OF */ 507 ··· 572 chg->max14577 = max14577; 573 574 chg->pdata = max14577_charger_dt_init(pdev); 575 - if (IS_ERR_OR_NULL(chg->pdata)) 576 return PTR_ERR(chg->pdata); 577 578 ret = max14577_charger_reg_init(chg);
··· 501 static struct max14577_charger_platform_data *max14577_charger_dt_init( 502 struct platform_device *pdev) 503 { 504 + return ERR_PTR(-ENODATA); 505 } 506 #endif /* CONFIG_OF */ 507 ··· 572 chg->max14577 = max14577; 573 574 chg->pdata = max14577_charger_dt_init(pdev); 575 + if (IS_ERR(chg->pdata)) 576 return PTR_ERR(chg->pdata); 577 578 ret = max14577_charger_reg_init(chg);
+8 -5
drivers/power/supply/max1720x_battery.c
··· 288 return reg * 1250; /* in uV */ 289 } 290 291 - static int max172xx_capacity_to_ps(unsigned int reg) 292 { 293 - return reg * 500; /* in uAh */ 294 } 295 296 /* ··· 395 break; 396 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 397 ret = regmap_read(info->regmap, MAX172XX_DESIGN_CAP, &reg_val); 398 - val->intval = max172xx_capacity_to_ps(reg_val); 399 break; 400 case POWER_SUPPLY_PROP_CHARGE_AVG: 401 ret = regmap_read(info->regmap, MAX172XX_REPCAP, &reg_val); 402 - val->intval = max172xx_capacity_to_ps(reg_val); 403 break; 404 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 405 ret = regmap_read(info->regmap, MAX172XX_TTE, &reg_val); ··· 423 break; 424 case POWER_SUPPLY_PROP_CHARGE_FULL: 425 ret = regmap_read(info->regmap, MAX172XX_FULL_CAP, &reg_val); 426 - val->intval = max172xx_capacity_to_ps(reg_val); 427 break; 428 case POWER_SUPPLY_PROP_MODEL_NAME: 429 ret = regmap_read(info->regmap, MAX172XX_DEV_NAME, &reg_val); 430 reg_val = FIELD_GET(MAX172XX_DEV_NAME_TYPE_MASK, reg_val); 431 if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17201) 432 val->strval = max17201_model;
··· 288 return reg * 1250; /* in uV */ 289 } 290 291 + static int max172xx_capacity_to_ps(unsigned int reg, 292 + struct max1720x_device_info *info) 293 { 294 + return reg * (500000 / info->rsense); /* in uAh */ 295 } 296 297 /* ··· 394 break; 395 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 396 ret = regmap_read(info->regmap, MAX172XX_DESIGN_CAP, &reg_val); 397 + val->intval = max172xx_capacity_to_ps(reg_val, info); 398 break; 399 case POWER_SUPPLY_PROP_CHARGE_AVG: 400 ret = regmap_read(info->regmap, MAX172XX_REPCAP, &reg_val); 401 + val->intval = max172xx_capacity_to_ps(reg_val, info); 402 break; 403 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 404 ret = regmap_read(info->regmap, MAX172XX_TTE, &reg_val); ··· 422 break; 423 case POWER_SUPPLY_PROP_CHARGE_FULL: 424 ret = regmap_read(info->regmap, MAX172XX_FULL_CAP, &reg_val); 425 + val->intval = max172xx_capacity_to_ps(reg_val, info); 426 break; 427 case POWER_SUPPLY_PROP_MODEL_NAME: 428 ret = regmap_read(info->regmap, MAX172XX_DEV_NAME, &reg_val); 429 + if (ret) 430 + return ret; 431 reg_val = FIELD_GET(MAX172XX_DEV_NAME_TYPE_MASK, reg_val); 432 if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17201) 433 val->strval = max17201_model;
+95 -90
drivers/power/supply/power_supply_core.c
··· 18 #include <linux/device.h> 19 #include <linux/notifier.h> 20 #include <linux/err.h> 21 - #include <linux/of.h> 22 #include <linux/power_supply.h> 23 #include <linux/property.h> 24 #include <linux/thermal.h> ··· 195 void *data) 196 { 197 struct power_supply *psy = data; 198 - struct device_node *np; 199 int i = 0; 200 201 do { 202 - np = of_parse_phandle(psy->dev.of_node, "power-supplies", i++); 203 - if (!np) 204 break; 205 206 - if (np == epsy->dev.of_node) { 207 dev_dbg(&psy->dev, "%s: Found supply : %s\n", 208 psy->desc->name, epsy->desc->name); 209 psy->supplied_from[i-1] = (char *)epsy->desc->name; 210 psy->num_supplies++; 211 - of_node_put(np); 212 break; 213 } 214 - of_node_put(np); 215 - } while (np); 216 217 return 0; 218 } ··· 231 static int __power_supply_find_supply_from_node(struct power_supply *epsy, 232 void *data) 233 { 234 - struct device_node *np = data; 235 236 /* returning non-zero breaks out of power_supply_for_each_psy loop */ 237 - if (epsy->dev.of_node == np) 238 return 1; 239 240 return 0; 241 } 242 243 - static int power_supply_find_supply_from_node(struct device_node *supply_node) 244 { 245 int error; 246 ··· 248 * power_supply_for_each_psy() either returns its own errors or values 249 * returned by __power_supply_find_supply_from_node(). 250 * 251 - * __power_supply_find_supply_from_node() will return 0 (no match) 252 * or 1 (match). 253 * 254 * We return 0 if power_supply_for_each_psy() returned 1, -EPROBE_DEFER if ··· 261 262 static int power_supply_check_supplies(struct power_supply *psy) 263 { 264 - struct device_node *np; 265 int cnt = 0; 266 267 /* If there is already a list honor it */ ··· 269 return 0; 270 271 /* No device node found, nothing to do */ 272 - if (!psy->dev.of_node) 273 return 0; 274 275 do { 276 int ret; 277 278 - np = of_parse_phandle(psy->dev.of_node, "power-supplies", cnt++); 279 - if (!np) 280 break; 281 282 - ret = power_supply_find_supply_from_node(np); 283 - of_node_put(np); 284 285 if (ret) { 286 dev_dbg(&psy->dev, "Failed to find supply!\n"); 287 return ret; 288 } 289 - } while (np); 290 291 /* Missing valid "power-supplies" entries */ 292 if (cnt == 1) ··· 496 } 497 EXPORT_SYMBOL_GPL(power_supply_put); 498 499 - #ifdef CONFIG_OF 500 - static int power_supply_match_device_node(struct device *dev, const void *data) 501 { 502 - return dev->parent && dev->parent->of_node == data; 503 } 504 505 /** 506 - * power_supply_get_by_phandle() - Search for a power supply and returns its ref 507 - * @np: Pointer to device node holding phandle property 508 * @property: Name of property holding a power supply name 509 * 510 * If power supply was found, it increases reference count for the ··· 513 * Return: On success returns a reference to a power supply with 514 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 515 */ 516 - struct power_supply *power_supply_get_by_phandle(struct device_node *np, 517 - const char *property) 518 { 519 - struct device_node *power_supply_np; 520 struct power_supply *psy = NULL; 521 struct device *dev; 522 523 - power_supply_np = of_parse_phandle(np, property, 0); 524 - if (!power_supply_np) 525 - return ERR_PTR(-ENODEV); 526 527 - dev = class_find_device(&power_supply_class, NULL, power_supply_np, 528 - power_supply_match_device_node); 529 530 - of_node_put(power_supply_np); 531 532 if (dev) { 533 psy = dev_to_psy(dev); ··· 536 537 return psy; 538 } 539 - EXPORT_SYMBOL_GPL(power_supply_get_by_phandle); 540 541 static void devm_power_supply_put(struct device *dev, void *res) 542 { ··· 546 } 547 548 /** 549 - * devm_power_supply_get_by_phandle() - Resource managed version of 550 - * power_supply_get_by_phandle() 551 * @dev: Pointer to device holding phandle property 552 * @property: Name of property holding a power supply phandle 553 * 554 * Return: On success returns a reference to a power supply with 555 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 556 */ 557 - struct power_supply *devm_power_supply_get_by_phandle(struct device *dev, 558 - const char *property) 559 { 560 struct power_supply **ptr, *psy; 561 562 - if (!dev->of_node) 563 return ERR_PTR(-ENODEV); 564 565 ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL); 566 if (!ptr) 567 return ERR_PTR(-ENOMEM); 568 569 - psy = power_supply_get_by_phandle(dev->of_node, property); 570 if (IS_ERR_OR_NULL(psy)) { 571 devres_free(ptr); 572 } else { ··· 575 } 576 return psy; 577 } 578 - EXPORT_SYMBOL_GPL(devm_power_supply_get_by_phandle); 579 - #endif /* CONFIG_OF */ 580 581 int power_supply_get_battery_info(struct power_supply *psy, 582 struct power_supply_battery_info **info_out) 583 { 584 struct power_supply_resistance_temp_table *resist_table; 585 struct power_supply_battery_info *info; 586 - struct device_node *battery_np = NULL; 587 - struct fwnode_reference_args args; 588 - struct fwnode_handle *fwnode = NULL; 589 const char *value; 590 - int err, len, index; 591 - const __be32 *list; 592 u32 min_max[2]; 593 594 - if (psy->dev.of_node) { 595 - battery_np = of_parse_phandle(psy->dev.of_node, "monitored-battery", 0); 596 - if (!battery_np) 597 - return -ENODEV; 598 599 - fwnode = fwnode_handle_get(of_fwnode_handle(battery_np)); 600 - } else if (psy->dev.parent) { 601 - err = fwnode_property_get_reference_args( 602 - dev_fwnode(psy->dev.parent), 603 - "monitored-battery", NULL, 0, 0, &args); 604 - if (err) 605 - return err; 606 - 607 - fwnode = args.fwnode; 608 - } 609 - 610 - if (!fwnode) 611 - return -ENOENT; 612 613 err = fwnode_property_read_string(fwnode, "compatible", &value); 614 if (err) ··· 724 info->temp_max = min_max[1]; 725 } 726 727 - /* 728 - * The below code uses raw of-data parsing to parse 729 - * /schemas/types.yaml#/definitions/uint32-matrix 730 - * data, so for now this is only support with of. 731 - */ 732 - if (!battery_np) 733 - goto out_ret_pointer; 734 - 735 - len = of_property_count_u32_elems(battery_np, "ocv-capacity-celsius"); 736 if (len < 0 && len != -EINVAL) { 737 err = len; 738 goto out_put_node; ··· 733 err = -EINVAL; 734 goto out_put_node; 735 } else if (len > 0) { 736 - of_property_read_u32_array(battery_np, "ocv-capacity-celsius", 737 info->ocv_temp, len); 738 } 739 740 for (index = 0; index < len; index++) { 741 struct power_supply_battery_ocv_table *table; 742 - int i, tab_len, size; 743 744 char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", 745 index); ··· 748 err = -ENOMEM; 749 goto out_put_node; 750 } 751 - list = of_get_property(battery_np, propname, &size); 752 - if (!list || !size) { 753 dev_err(&psy->dev, "failed to get %s\n", propname); 754 power_supply_put_battery_info(psy, info); 755 err = -EINVAL; 756 goto out_put_node; 757 } 758 759 - tab_len = size / (2 * sizeof(__be32)); 760 info->ocv_table_size[index] = tab_len; 761 762 info->ocv_table[index] = table = ··· 781 } 782 783 for (i = 0; i < tab_len; i++) { 784 - table[i].ocv = be32_to_cpu(*list); 785 - list++; 786 - table[i].capacity = be32_to_cpu(*list); 787 - list++; 788 } 789 } 790 791 - list = of_get_property(battery_np, "resistance-temp-table", &len); 792 - if (!list || !len) 793 goto out_ret_pointer; 794 795 - info->resist_table_size = len / (2 * sizeof(__be32)); 796 info->resist_table = resist_table = devm_kcalloc(&psy->dev, 797 info->resist_table_size, 798 sizeof(*resist_table), ··· 822 } 823 824 for (index = 0; index < info->resist_table_size; index++) { 825 - resist_table[index].temp = be32_to_cpu(*list++); 826 - resist_table[index].resistance = be32_to_cpu(*list++); 827 } 828 829 out_ret_pointer: ··· 832 833 out_put_node: 834 fwnode_handle_put(fwnode); 835 - of_node_put(battery_np); 836 return err; 837 } 838 EXPORT_SYMBOL_GPL(power_supply_get_battery_info); ··· 1593 dev_set_drvdata(dev, psy); 1594 psy->desc = desc; 1595 if (cfg) { 1596 dev->groups = cfg->attr_grp; 1597 psy->drv_data = cfg->drv_data; 1598 - dev->of_node = 1599 - cfg->fwnode ? to_of_node(cfg->fwnode) : cfg->of_node; 1600 psy->supplied_to = cfg->supplied_to; 1601 psy->num_supplicants = cfg->num_supplicants; 1602 }
··· 18 #include <linux/device.h> 19 #include <linux/notifier.h> 20 #include <linux/err.h> 21 #include <linux/power_supply.h> 22 #include <linux/property.h> 23 #include <linux/thermal.h> ··· 196 void *data) 197 { 198 struct power_supply *psy = data; 199 + struct fwnode_handle *np; 200 int i = 0; 201 202 do { 203 + np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", i++); 204 + if (IS_ERR(np)) 205 break; 206 207 + if (np == epsy->dev.fwnode) { 208 dev_dbg(&psy->dev, "%s: Found supply : %s\n", 209 psy->desc->name, epsy->desc->name); 210 psy->supplied_from[i-1] = (char *)epsy->desc->name; 211 psy->num_supplies++; 212 + fwnode_handle_put(np); 213 break; 214 } 215 + fwnode_handle_put(np); 216 + } while (true); 217 218 return 0; 219 } ··· 232 static int __power_supply_find_supply_from_node(struct power_supply *epsy, 233 void *data) 234 { 235 + struct fwnode_handle *fwnode = data; 236 237 /* returning non-zero breaks out of power_supply_for_each_psy loop */ 238 + if (epsy->dev.fwnode == fwnode) 239 return 1; 240 241 return 0; 242 } 243 244 + static int power_supply_find_supply_from_fwnode(struct fwnode_handle *supply_node) 245 { 246 int error; 247 ··· 249 * power_supply_for_each_psy() either returns its own errors or values 250 * returned by __power_supply_find_supply_from_node(). 251 * 252 + * __power_supply_find_supply_from_fwnode() will return 0 (no match) 253 * or 1 (match). 254 * 255 * We return 0 if power_supply_for_each_psy() returned 1, -EPROBE_DEFER if ··· 262 263 static int power_supply_check_supplies(struct power_supply *psy) 264 { 265 + struct fwnode_handle *np; 266 int cnt = 0; 267 268 /* If there is already a list honor it */ ··· 270 return 0; 271 272 /* No device node found, nothing to do */ 273 + if (!psy->dev.fwnode) 274 return 0; 275 276 do { 277 int ret; 278 279 + np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", cnt++); 280 + if (IS_ERR(np)) 281 break; 282 283 + ret = power_supply_find_supply_from_fwnode(np); 284 + fwnode_handle_put(np); 285 286 if (ret) { 287 dev_dbg(&psy->dev, "Failed to find supply!\n"); 288 return ret; 289 } 290 + } while (!IS_ERR(np)); 291 292 /* Missing valid "power-supplies" entries */ 293 if (cnt == 1) ··· 497 } 498 EXPORT_SYMBOL_GPL(power_supply_put); 499 500 + static int power_supply_match_device_fwnode(struct device *dev, const void *data) 501 { 502 + return dev->parent && dev_fwnode(dev->parent) == data; 503 } 504 505 /** 506 + * power_supply_get_by_reference() - Search for a power supply and returns its ref 507 + * @fwnode: Pointer to fwnode holding phandle property 508 * @property: Name of property holding a power supply name 509 * 510 * If power supply was found, it increases reference count for the ··· 515 * Return: On success returns a reference to a power supply with 516 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 517 */ 518 + struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode, 519 + const char *property) 520 { 521 + struct fwnode_handle *power_supply_fwnode; 522 struct power_supply *psy = NULL; 523 struct device *dev; 524 525 + power_supply_fwnode = fwnode_find_reference(fwnode, property, 0); 526 + if (IS_ERR(power_supply_fwnode)) 527 + return ERR_CAST(power_supply_fwnode); 528 529 + dev = class_find_device(&power_supply_class, NULL, power_supply_fwnode, 530 + power_supply_match_device_fwnode); 531 532 + fwnode_handle_put(power_supply_fwnode); 533 534 if (dev) { 535 psy = dev_to_psy(dev); ··· 538 539 return psy; 540 } 541 + EXPORT_SYMBOL_GPL(power_supply_get_by_reference); 542 543 static void devm_power_supply_put(struct device *dev, void *res) 544 { ··· 548 } 549 550 /** 551 + * devm_power_supply_get_by_reference() - Resource managed version of 552 + * power_supply_get_by_reference() 553 * @dev: Pointer to device holding phandle property 554 * @property: Name of property holding a power supply phandle 555 * 556 * Return: On success returns a reference to a power supply with 557 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 558 */ 559 + struct power_supply *devm_power_supply_get_by_reference(struct device *dev, 560 + const char *property) 561 { 562 struct power_supply **ptr, *psy; 563 564 + if (!dev_fwnode(dev)) 565 return ERR_PTR(-ENODEV); 566 567 ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL); 568 if (!ptr) 569 return ERR_PTR(-ENOMEM); 570 571 + psy = power_supply_get_by_reference(dev_fwnode(dev), property); 572 if (IS_ERR_OR_NULL(psy)) { 573 devres_free(ptr); 574 } else { ··· 577 } 578 return psy; 579 } 580 + EXPORT_SYMBOL_GPL(devm_power_supply_get_by_reference); 581 582 int power_supply_get_battery_info(struct power_supply *psy, 583 struct power_supply_battery_info **info_out) 584 { 585 struct power_supply_resistance_temp_table *resist_table; 586 struct power_supply_battery_info *info; 587 + struct fwnode_handle *srcnode, *fwnode; 588 const char *value; 589 + int err, len, index, proplen; 590 + u32 *propdata __free(kfree) = NULL; 591 u32 min_max[2]; 592 593 + srcnode = dev_fwnode(&psy->dev); 594 + if (!srcnode && psy->dev.parent) 595 + srcnode = dev_fwnode(psy->dev.parent); 596 597 + fwnode = fwnode_find_reference(srcnode, "monitored-battery", 0); 598 + if (IS_ERR(fwnode)) 599 + return PTR_ERR(fwnode); 600 601 err = fwnode_property_read_string(fwnode, "compatible", &value); 602 if (err) ··· 740 info->temp_max = min_max[1]; 741 } 742 743 + len = fwnode_property_count_u32(fwnode, "ocv-capacity-celsius"); 744 if (len < 0 && len != -EINVAL) { 745 err = len; 746 goto out_put_node; ··· 757 err = -EINVAL; 758 goto out_put_node; 759 } else if (len > 0) { 760 + fwnode_property_read_u32_array(fwnode, "ocv-capacity-celsius", 761 info->ocv_temp, len); 762 } 763 764 for (index = 0; index < len; index++) { 765 struct power_supply_battery_ocv_table *table; 766 + int i, tab_len; 767 768 char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", 769 index); ··· 772 err = -ENOMEM; 773 goto out_put_node; 774 } 775 + proplen = fwnode_property_count_u32(fwnode, propname); 776 + if (proplen < 0 || proplen % 2 != 0) { 777 dev_err(&psy->dev, "failed to get %s\n", propname); 778 power_supply_put_battery_info(psy, info); 779 err = -EINVAL; 780 goto out_put_node; 781 } 782 783 + u32 *propdata __free(kfree) = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL); 784 + if (!propdata) { 785 + power_supply_put_battery_info(psy, info); 786 + err = -EINVAL; 787 + goto out_put_node; 788 + } 789 + err = fwnode_property_read_u32_array(fwnode, propname, propdata, proplen); 790 + if (err < 0) { 791 + dev_err(&psy->dev, "failed to get %s\n", propname); 792 + power_supply_put_battery_info(psy, info); 793 + goto out_put_node; 794 + } 795 + 796 + tab_len = proplen / 2; 797 info->ocv_table_size[index] = tab_len; 798 799 info->ocv_table[index] = table = ··· 792 } 793 794 for (i = 0; i < tab_len; i++) { 795 + table[i].ocv = propdata[i*2]; 796 + table[i].capacity = propdata[i*2+1]; 797 } 798 } 799 800 + proplen = fwnode_property_count_u32(fwnode, "resistance-temp-table"); 801 + if (proplen == 0 || proplen == -EINVAL) { 802 + err = 0; 803 goto out_ret_pointer; 804 + } else if (proplen < 0 || proplen % 2 != 0) { 805 + power_supply_put_battery_info(psy, info); 806 + err = (proplen < 0) ? proplen : -EINVAL; 807 + goto out_put_node; 808 + } 809 810 + propdata = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL); 811 + if (!propdata) { 812 + power_supply_put_battery_info(psy, info); 813 + err = -ENOMEM; 814 + goto out_put_node; 815 + } 816 + 817 + err = fwnode_property_read_u32_array(fwnode, "resistance-temp-table", 818 + propdata, proplen); 819 + if (err < 0) { 820 + power_supply_put_battery_info(psy, info); 821 + goto out_put_node; 822 + } 823 + 824 + info->resist_table_size = proplen / 2; 825 info->resist_table = resist_table = devm_kcalloc(&psy->dev, 826 info->resist_table_size, 827 sizeof(*resist_table), ··· 815 } 816 817 for (index = 0; index < info->resist_table_size; index++) { 818 + resist_table[index].temp = propdata[index*2]; 819 + resist_table[index].resistance = propdata[index*2+1]; 820 } 821 822 out_ret_pointer: ··· 825 826 out_put_node: 827 fwnode_handle_put(fwnode); 828 return err; 829 } 830 EXPORT_SYMBOL_GPL(power_supply_get_battery_info); ··· 1587 dev_set_drvdata(dev, psy); 1588 psy->desc = desc; 1589 if (cfg) { 1590 + device_set_node(dev, cfg->fwnode); 1591 dev->groups = cfg->attr_grp; 1592 psy->drv_data = cfg->drv_data; 1593 psy->supplied_to = cfg->supplied_to; 1594 psy->num_supplicants = cfg->num_supplicants; 1595 }
+25
drivers/power/supply/qcom_battmgr.c
··· 577 val->intval = battmgr->status.capacity; 578 break; 579 case POWER_SUPPLY_PROP_CAPACITY: 580 val->intval = battmgr->status.percent; 581 break; 582 case POWER_SUPPLY_PROP_TEMP: ··· 619 POWER_SUPPLY_PROP_STATUS, 620 POWER_SUPPLY_PROP_PRESENT, 621 POWER_SUPPLY_PROP_TECHNOLOGY, 622 POWER_SUPPLY_PROP_CYCLE_COUNT, 623 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 624 POWER_SUPPLY_PROP_VOLTAGE_NOW, ··· 984 { 985 if (!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN)) 986 return POWER_SUPPLY_TECHNOLOGY_LION; 987 988 pr_err("Unknown battery technology '%s'\n", chemistry); 989 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; ··· 1068 battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC; 1069 battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB; 1070 battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS; 1071 break; 1072 case BATTMGR_BAT_DISCHARGE_TIME: 1073 battmgr->status.discharge_time = le32_to_cpu(resp->time);
··· 577 val->intval = battmgr->status.capacity; 578 break; 579 case POWER_SUPPLY_PROP_CAPACITY: 580 + if (battmgr->status.percent == (unsigned int)-1) 581 + return -ENODATA; 582 val->intval = battmgr->status.percent; 583 break; 584 case POWER_SUPPLY_PROP_TEMP: ··· 617 POWER_SUPPLY_PROP_STATUS, 618 POWER_SUPPLY_PROP_PRESENT, 619 POWER_SUPPLY_PROP_TECHNOLOGY, 620 + POWER_SUPPLY_PROP_CAPACITY, 621 POWER_SUPPLY_PROP_CYCLE_COUNT, 622 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 623 POWER_SUPPLY_PROP_VOLTAGE_NOW, ··· 981 { 982 if (!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN)) 983 return POWER_SUPPLY_TECHNOLOGY_LION; 984 + if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN)) 985 + return POWER_SUPPLY_TECHNOLOGY_LIPO; 986 987 pr_err("Unknown battery technology '%s'\n", chemistry); 988 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; ··· 1063 battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC; 1064 battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB; 1065 battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS; 1066 + if (battmgr->info.last_full_capacity != 0) { 1067 + /* 1068 + * 100 * battmgr->status.capacity can overflow a 32bit 1069 + * unsigned integer. FW readings are in m{W/A}h, which 1070 + * are multiplied by 1000 converting them to u{W/A}h, 1071 + * the format the power_supply API expects. 1072 + * To avoid overflow use the original value for dividend 1073 + * and convert the divider back to m{W/A}h, which can be 1074 + * done without any loss of precision. 1075 + */ 1076 + battmgr->status.percent = 1077 + (100 * le32_to_cpu(resp->status.capacity)) / 1078 + (battmgr->info.last_full_capacity / 1000); 1079 + } else { 1080 + /* 1081 + * Let the sysfs handler know no data is available at 1082 + * this time. 1083 + */ 1084 + battmgr->status.percent = (unsigned int)-1; 1085 + } 1086 break; 1087 case BATTMGR_BAT_DISCHARGE_TIME: 1088 battmgr->status.discharge_time = le32_to_cpu(resp->time);
+77 -75
drivers/power/supply/qcom_pmi8998_charger.c drivers/power/supply/qcom_smbx.c
··· 362 DISABLE_CHARGE, 363 }; 364 365 - struct smb2_register { 366 u16 addr; 367 u8 mask; 368 u8 val; 369 }; 370 371 /** 372 - * struct smb2_chip - smb2 chip structure 373 * @dev: Device reference for power_supply 374 * @name: The platform device name 375 - * @base: Base address for smb2 registers 376 * @regmap: Register map 377 * @batt_info: Battery data from DT 378 * @status_change_work: Worker to handle plug/unplug events ··· 382 * @usb_in_v_chan: USB_IN voltage measurement channel 383 * @chg_psy: Charger power supply instance 384 */ 385 - struct smb2_chip { 386 struct device *dev; 387 const char *name; 388 unsigned int base; ··· 399 struct power_supply *chg_psy; 400 }; 401 402 - static enum power_supply_property smb2_properties[] = { 403 POWER_SUPPLY_PROP_MANUFACTURER, 404 POWER_SUPPLY_PROP_MODEL_NAME, 405 POWER_SUPPLY_PROP_CURRENT_MAX, ··· 411 POWER_SUPPLY_PROP_USB_TYPE, 412 }; 413 414 - static int smb2_get_prop_usb_online(struct smb2_chip *chip, int *val) 415 { 416 unsigned int stat; 417 int rc; ··· 431 * Qualcomm "automatic power source detection" aka APSD 432 * tells us what type of charger we're connected to. 433 */ 434 - static int smb2_apsd_get_charger_type(struct smb2_chip *chip, int *val) 435 { 436 unsigned int apsd_stat, stat; 437 int usb_online = 0; 438 int rc; 439 440 - rc = smb2_get_prop_usb_online(chip, &usb_online); 441 if (!usb_online) { 442 *val = POWER_SUPPLY_USB_TYPE_UNKNOWN; 443 return rc; ··· 471 return 0; 472 } 473 474 - static int smb2_get_prop_status(struct smb2_chip *chip, int *val) 475 { 476 unsigned char stat[2]; 477 int usb_online = 0; 478 int rc; 479 480 - rc = smb2_get_prop_usb_online(chip, &usb_online); 481 if (!usb_online) { 482 *val = POWER_SUPPLY_STATUS_DISCHARGING; 483 return rc; ··· 519 } 520 } 521 522 - static inline int smb2_get_current_limit(struct smb2_chip *chip, 523 unsigned int *val) 524 { 525 int rc = regmap_read(chip->regmap, chip->base + ICL_STATUS, val); ··· 529 return rc; 530 } 531 532 - static int smb2_set_current_limit(struct smb2_chip *chip, unsigned int val) 533 { 534 unsigned char val_raw; 535 ··· 544 val_raw); 545 } 546 547 - static void smb2_status_change_work(struct work_struct *work) 548 { 549 unsigned int charger_type, current_ua; 550 int usb_online = 0; 551 int count, rc; 552 - struct smb2_chip *chip; 553 554 - chip = container_of(work, struct smb2_chip, status_change_work.work); 555 556 - smb2_get_prop_usb_online(chip, &usb_online); 557 if (!usb_online) 558 return; 559 560 for (count = 0; count < 3; count++) { 561 dev_dbg(chip->dev, "get charger type retry %d\n", count); 562 - rc = smb2_apsd_get_charger_type(chip, &charger_type); 563 if (rc != -EAGAIN) 564 break; 565 msleep(100); ··· 592 break; 593 } 594 595 - smb2_set_current_limit(chip, current_ua); 596 power_supply_changed(chip->chg_psy); 597 } 598 599 - static int smb2_get_iio_chan(struct smb2_chip *chip, struct iio_channel *chan, 600 int *val) 601 { 602 int rc; ··· 617 return iio_read_channel_processed(chan, val); 618 } 619 620 - static int smb2_get_prop_health(struct smb2_chip *chip, int *val) 621 { 622 int rc; 623 unsigned int stat; ··· 651 } 652 } 653 654 - static int smb2_get_property(struct power_supply *psy, 655 enum power_supply_property psp, 656 union power_supply_propval *val) 657 { 658 - struct smb2_chip *chip = power_supply_get_drvdata(psy); 659 660 switch (psp) { 661 case POWER_SUPPLY_PROP_MANUFACTURER: ··· 665 val->strval = chip->name; 666 return 0; 667 case POWER_SUPPLY_PROP_CURRENT_MAX: 668 - return smb2_get_current_limit(chip, &val->intval); 669 case POWER_SUPPLY_PROP_CURRENT_NOW: 670 - return smb2_get_iio_chan(chip, chip->usb_in_i_chan, 671 &val->intval); 672 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 673 - return smb2_get_iio_chan(chip, chip->usb_in_v_chan, 674 &val->intval); 675 case POWER_SUPPLY_PROP_ONLINE: 676 - return smb2_get_prop_usb_online(chip, &val->intval); 677 case POWER_SUPPLY_PROP_STATUS: 678 - return smb2_get_prop_status(chip, &val->intval); 679 case POWER_SUPPLY_PROP_HEALTH: 680 - return smb2_get_prop_health(chip, &val->intval); 681 case POWER_SUPPLY_PROP_USB_TYPE: 682 - return smb2_apsd_get_charger_type(chip, &val->intval); 683 default: 684 dev_err(chip->dev, "invalid property: %d\n", psp); 685 return -EINVAL; 686 } 687 } 688 689 - static int smb2_set_property(struct power_supply *psy, 690 enum power_supply_property psp, 691 const union power_supply_propval *val) 692 { 693 - struct smb2_chip *chip = power_supply_get_drvdata(psy); 694 695 switch (psp) { 696 case POWER_SUPPLY_PROP_CURRENT_MAX: 697 - return smb2_set_current_limit(chip, val->intval); 698 default: 699 dev_err(chip->dev, "No setter for property: %d\n", psp); 700 return -EINVAL; 701 } 702 } 703 704 - static int smb2_property_is_writable(struct power_supply *psy, 705 enum power_supply_property psp) 706 { 707 switch (psp) { ··· 712 } 713 } 714 715 - static irqreturn_t smb2_handle_batt_overvoltage(int irq, void *data) 716 { 717 - struct smb2_chip *chip = data; 718 unsigned int status; 719 720 regmap_read(chip->regmap, chip->base + BATTERY_CHARGER_STATUS_2, ··· 729 return IRQ_HANDLED; 730 } 731 732 - static irqreturn_t smb2_handle_usb_plugin(int irq, void *data) 733 { 734 - struct smb2_chip *chip = data; 735 736 power_supply_changed(chip->chg_psy); 737 ··· 741 return IRQ_HANDLED; 742 } 743 744 - static irqreturn_t smb2_handle_usb_icl_change(int irq, void *data) 745 { 746 - struct smb2_chip *chip = data; 747 748 power_supply_changed(chip->chg_psy); 749 750 return IRQ_HANDLED; 751 } 752 753 - static irqreturn_t smb2_handle_wdog_bark(int irq, void *data) 754 { 755 - struct smb2_chip *chip = data; 756 int rc; 757 758 power_supply_changed(chip->chg_psy); ··· 765 return IRQ_HANDLED; 766 } 767 768 - static const struct power_supply_desc smb2_psy_desc = { 769 .name = "pmi8998_charger", 770 .type = POWER_SUPPLY_TYPE_USB, 771 .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 772 BIT(POWER_SUPPLY_USB_TYPE_CDP) | 773 BIT(POWER_SUPPLY_USB_TYPE_DCP) | 774 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 775 - .properties = smb2_properties, 776 - .num_properties = ARRAY_SIZE(smb2_properties), 777 - .get_property = smb2_get_property, 778 - .set_property = smb2_set_property, 779 - .property_is_writeable = smb2_property_is_writable, 780 }; 781 782 /* Init sequence derived from vendor downstream driver */ 783 - static const struct smb2_register smb2_init_seq[] = { 784 { .addr = AICL_RERUN_TIME_CFG, .mask = AICL_RERUN_TIME_MASK, .val = 0 }, 785 /* 786 * By default configure us as an upstream facing port ··· 882 .val = 1000000 / CURRENT_SCALE_FACTOR }, 883 }; 884 885 - static int smb2_init_hw(struct smb2_chip *chip) 886 { 887 int rc, i; 888 889 - for (i = 0; i < ARRAY_SIZE(smb2_init_seq); i++) { 890 dev_dbg(chip->dev, "%d: Writing 0x%02x to 0x%02x\n", i, 891 - smb2_init_seq[i].val, smb2_init_seq[i].addr); 892 rc = regmap_update_bits(chip->regmap, 893 - chip->base + smb2_init_seq[i].addr, 894 - smb2_init_seq[i].mask, 895 - smb2_init_seq[i].val); 896 if (rc < 0) 897 return dev_err_probe(chip->dev, rc, 898 "%s: init command %d failed\n", ··· 902 return 0; 903 } 904 905 - static int smb2_init_irq(struct smb2_chip *chip, int *irq, const char *name, 906 irqreturn_t (*handler)(int irq, void *data)) 907 { 908 int irqnum; ··· 924 return 0; 925 } 926 927 - static int smb2_probe(struct platform_device *pdev) 928 { 929 struct power_supply_config supply_config = {}; 930 struct power_supply_desc *desc; 931 - struct smb2_chip *chip; 932 int rc, irq; 933 934 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); ··· 959 "Couldn't get usbin_i IIO channel\n"); 960 } 961 962 - rc = smb2_init_hw(chip); 963 if (rc < 0) 964 return rc; 965 966 supply_config.drv_data = chip; 967 supply_config.fwnode = dev_fwnode(&pdev->dev); 968 969 - desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL); 970 if (!desc) 971 return -ENOMEM; 972 - memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc)); 973 desc->name = 974 devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger", 975 (const char *)device_get_match_data(chip->dev)); ··· 988 "Failed to get battery info\n"); 989 990 rc = devm_delayed_work_autocancel(chip->dev, &chip->status_change_work, 991 - smb2_status_change_work); 992 if (rc) 993 return dev_err_probe(chip->dev, rc, 994 "Failed to init status change work\n"); ··· 999 if (rc < 0) 1000 return dev_err_probe(chip->dev, rc, "Couldn't set vbat max\n"); 1001 1002 - rc = smb2_init_irq(chip, &irq, "bat-ov", smb2_handle_batt_overvoltage); 1003 if (rc < 0) 1004 return rc; 1005 1006 - rc = smb2_init_irq(chip, &chip->cable_irq, "usb-plugin", 1007 - smb2_handle_usb_plugin); 1008 if (rc < 0) 1009 return rc; 1010 1011 - rc = smb2_init_irq(chip, &irq, "usbin-icl-change", 1012 - smb2_handle_usb_icl_change); 1013 if (rc < 0) 1014 return rc; 1015 - rc = smb2_init_irq(chip, &irq, "wdog-bark", smb2_handle_wdog_bark); 1016 if (rc < 0) 1017 return rc; 1018 1019 - rc = dev_pm_set_wake_irq(chip->dev, chip->cable_irq); 1020 if (rc < 0) 1021 return dev_err_probe(chip->dev, rc, "Couldn't set wake irq\n"); 1022 ··· 1030 return 0; 1031 } 1032 1033 - static const struct of_device_id smb2_match_id_table[] = { 1034 { .compatible = "qcom,pmi8998-charger", .data = "pmi8998" }, 1035 { .compatible = "qcom,pm660-charger", .data = "pm660" }, 1036 { /* sentinal */ } 1037 }; 1038 - MODULE_DEVICE_TABLE(of, smb2_match_id_table); 1039 1040 - static struct platform_driver qcom_spmi_smb2 = { 1041 - .probe = smb2_probe, 1042 .driver = { 1043 - .name = "qcom-pmi8998/pm660-charger", 1044 - .of_match_table = smb2_match_id_table, 1045 }, 1046 }; 1047 1048 - module_platform_driver(qcom_spmi_smb2); 1049 1050 MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>"); 1051 MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver");
··· 362 DISABLE_CHARGE, 363 }; 364 365 + struct smb_init_register { 366 u16 addr; 367 u8 mask; 368 u8 val; 369 }; 370 371 /** 372 + * struct smb_chip - smb chip structure 373 * @dev: Device reference for power_supply 374 * @name: The platform device name 375 + * @base: Base address for smb registers 376 * @regmap: Register map 377 * @batt_info: Battery data from DT 378 * @status_change_work: Worker to handle plug/unplug events ··· 382 * @usb_in_v_chan: USB_IN voltage measurement channel 383 * @chg_psy: Charger power supply instance 384 */ 385 + struct smb_chip { 386 struct device *dev; 387 const char *name; 388 unsigned int base; ··· 399 struct power_supply *chg_psy; 400 }; 401 402 + static enum power_supply_property smb_properties[] = { 403 POWER_SUPPLY_PROP_MANUFACTURER, 404 POWER_SUPPLY_PROP_MODEL_NAME, 405 POWER_SUPPLY_PROP_CURRENT_MAX, ··· 411 POWER_SUPPLY_PROP_USB_TYPE, 412 }; 413 414 + static int smb_get_prop_usb_online(struct smb_chip *chip, int *val) 415 { 416 unsigned int stat; 417 int rc; ··· 431 * Qualcomm "automatic power source detection" aka APSD 432 * tells us what type of charger we're connected to. 433 */ 434 + static int smb_apsd_get_charger_type(struct smb_chip *chip, int *val) 435 { 436 unsigned int apsd_stat, stat; 437 int usb_online = 0; 438 int rc; 439 440 + rc = smb_get_prop_usb_online(chip, &usb_online); 441 if (!usb_online) { 442 *val = POWER_SUPPLY_USB_TYPE_UNKNOWN; 443 return rc; ··· 471 return 0; 472 } 473 474 + static int smb_get_prop_status(struct smb_chip *chip, int *val) 475 { 476 unsigned char stat[2]; 477 int usb_online = 0; 478 int rc; 479 480 + rc = smb_get_prop_usb_online(chip, &usb_online); 481 if (!usb_online) { 482 *val = POWER_SUPPLY_STATUS_DISCHARGING; 483 return rc; ··· 519 } 520 } 521 522 + static inline int smb_get_current_limit(struct smb_chip *chip, 523 unsigned int *val) 524 { 525 int rc = regmap_read(chip->regmap, chip->base + ICL_STATUS, val); ··· 529 return rc; 530 } 531 532 + static int smb_set_current_limit(struct smb_chip *chip, unsigned int val) 533 { 534 unsigned char val_raw; 535 ··· 544 val_raw); 545 } 546 547 + static void smb_status_change_work(struct work_struct *work) 548 { 549 unsigned int charger_type, current_ua; 550 int usb_online = 0; 551 int count, rc; 552 + struct smb_chip *chip; 553 554 + chip = container_of(work, struct smb_chip, status_change_work.work); 555 556 + smb_get_prop_usb_online(chip, &usb_online); 557 if (!usb_online) 558 return; 559 560 for (count = 0; count < 3; count++) { 561 dev_dbg(chip->dev, "get charger type retry %d\n", count); 562 + rc = smb_apsd_get_charger_type(chip, &charger_type); 563 if (rc != -EAGAIN) 564 break; 565 msleep(100); ··· 592 break; 593 } 594 595 + smb_set_current_limit(chip, current_ua); 596 power_supply_changed(chip->chg_psy); 597 } 598 599 + static int smb_get_iio_chan(struct smb_chip *chip, struct iio_channel *chan, 600 int *val) 601 { 602 int rc; ··· 617 return iio_read_channel_processed(chan, val); 618 } 619 620 + static int smb_get_prop_health(struct smb_chip *chip, int *val) 621 { 622 int rc; 623 unsigned int stat; ··· 651 } 652 } 653 654 + static int smb_get_property(struct power_supply *psy, 655 enum power_supply_property psp, 656 union power_supply_propval *val) 657 { 658 + struct smb_chip *chip = power_supply_get_drvdata(psy); 659 660 switch (psp) { 661 case POWER_SUPPLY_PROP_MANUFACTURER: ··· 665 val->strval = chip->name; 666 return 0; 667 case POWER_SUPPLY_PROP_CURRENT_MAX: 668 + return smb_get_current_limit(chip, &val->intval); 669 case POWER_SUPPLY_PROP_CURRENT_NOW: 670 + return smb_get_iio_chan(chip, chip->usb_in_i_chan, 671 &val->intval); 672 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 673 + return smb_get_iio_chan(chip, chip->usb_in_v_chan, 674 &val->intval); 675 case POWER_SUPPLY_PROP_ONLINE: 676 + return smb_get_prop_usb_online(chip, &val->intval); 677 case POWER_SUPPLY_PROP_STATUS: 678 + return smb_get_prop_status(chip, &val->intval); 679 case POWER_SUPPLY_PROP_HEALTH: 680 + return smb_get_prop_health(chip, &val->intval); 681 case POWER_SUPPLY_PROP_USB_TYPE: 682 + return smb_apsd_get_charger_type(chip, &val->intval); 683 default: 684 dev_err(chip->dev, "invalid property: %d\n", psp); 685 return -EINVAL; 686 } 687 } 688 689 + static int smb_set_property(struct power_supply *psy, 690 enum power_supply_property psp, 691 const union power_supply_propval *val) 692 { 693 + struct smb_chip *chip = power_supply_get_drvdata(psy); 694 695 switch (psp) { 696 case POWER_SUPPLY_PROP_CURRENT_MAX: 697 + return smb_set_current_limit(chip, val->intval); 698 default: 699 dev_err(chip->dev, "No setter for property: %d\n", psp); 700 return -EINVAL; 701 } 702 } 703 704 + static int smb_property_is_writable(struct power_supply *psy, 705 enum power_supply_property psp) 706 { 707 switch (psp) { ··· 712 } 713 } 714 715 + static irqreturn_t smb_handle_batt_overvoltage(int irq, void *data) 716 { 717 + struct smb_chip *chip = data; 718 unsigned int status; 719 720 regmap_read(chip->regmap, chip->base + BATTERY_CHARGER_STATUS_2, ··· 729 return IRQ_HANDLED; 730 } 731 732 + static irqreturn_t smb_handle_usb_plugin(int irq, void *data) 733 { 734 + struct smb_chip *chip = data; 735 736 power_supply_changed(chip->chg_psy); 737 ··· 741 return IRQ_HANDLED; 742 } 743 744 + static irqreturn_t smb_handle_usb_icl_change(int irq, void *data) 745 { 746 + struct smb_chip *chip = data; 747 748 power_supply_changed(chip->chg_psy); 749 750 return IRQ_HANDLED; 751 } 752 753 + static irqreturn_t smb_handle_wdog_bark(int irq, void *data) 754 { 755 + struct smb_chip *chip = data; 756 int rc; 757 758 power_supply_changed(chip->chg_psy); ··· 765 return IRQ_HANDLED; 766 } 767 768 + static const struct power_supply_desc smb_psy_desc = { 769 .name = "pmi8998_charger", 770 .type = POWER_SUPPLY_TYPE_USB, 771 .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 772 BIT(POWER_SUPPLY_USB_TYPE_CDP) | 773 BIT(POWER_SUPPLY_USB_TYPE_DCP) | 774 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 775 + .properties = smb_properties, 776 + .num_properties = ARRAY_SIZE(smb_properties), 777 + .get_property = smb_get_property, 778 + .set_property = smb_set_property, 779 + .property_is_writeable = smb_property_is_writable, 780 }; 781 782 /* Init sequence derived from vendor downstream driver */ 783 + static const struct smb_init_register smb_init_seq[] = { 784 { .addr = AICL_RERUN_TIME_CFG, .mask = AICL_RERUN_TIME_MASK, .val = 0 }, 785 /* 786 * By default configure us as an upstream facing port ··· 882 .val = 1000000 / CURRENT_SCALE_FACTOR }, 883 }; 884 885 + static int smb_init_hw(struct smb_chip *chip) 886 { 887 int rc, i; 888 889 + for (i = 0; i < ARRAY_SIZE(smb_init_seq); i++) { 890 dev_dbg(chip->dev, "%d: Writing 0x%02x to 0x%02x\n", i, 891 + smb_init_seq[i].val, smb_init_seq[i].addr); 892 rc = regmap_update_bits(chip->regmap, 893 + chip->base + smb_init_seq[i].addr, 894 + smb_init_seq[i].mask, 895 + smb_init_seq[i].val); 896 if (rc < 0) 897 return dev_err_probe(chip->dev, rc, 898 "%s: init command %d failed\n", ··· 902 return 0; 903 } 904 905 + static int smb_init_irq(struct smb_chip *chip, int *irq, const char *name, 906 irqreturn_t (*handler)(int irq, void *data)) 907 { 908 int irqnum; ··· 924 return 0; 925 } 926 927 + static int smb_probe(struct platform_device *pdev) 928 { 929 struct power_supply_config supply_config = {}; 930 struct power_supply_desc *desc; 931 + struct smb_chip *chip; 932 int rc, irq; 933 934 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); ··· 959 "Couldn't get usbin_i IIO channel\n"); 960 } 961 962 + rc = smb_init_hw(chip); 963 if (rc < 0) 964 return rc; 965 966 supply_config.drv_data = chip; 967 supply_config.fwnode = dev_fwnode(&pdev->dev); 968 969 + desc = devm_kzalloc(chip->dev, sizeof(smb_psy_desc), GFP_KERNEL); 970 if (!desc) 971 return -ENOMEM; 972 + memcpy(desc, &smb_psy_desc, sizeof(smb_psy_desc)); 973 desc->name = 974 devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger", 975 (const char *)device_get_match_data(chip->dev)); ··· 988 "Failed to get battery info\n"); 989 990 rc = devm_delayed_work_autocancel(chip->dev, &chip->status_change_work, 991 + smb_status_change_work); 992 if (rc) 993 return dev_err_probe(chip->dev, rc, 994 "Failed to init status change work\n"); ··· 999 if (rc < 0) 1000 return dev_err_probe(chip->dev, rc, "Couldn't set vbat max\n"); 1001 1002 + rc = smb_init_irq(chip, &irq, "bat-ov", smb_handle_batt_overvoltage); 1003 if (rc < 0) 1004 return rc; 1005 1006 + rc = smb_init_irq(chip, &chip->cable_irq, "usb-plugin", 1007 + smb_handle_usb_plugin); 1008 if (rc < 0) 1009 return rc; 1010 1011 + rc = smb_init_irq(chip, &irq, "usbin-icl-change", 1012 + smb_handle_usb_icl_change); 1013 if (rc < 0) 1014 return rc; 1015 + rc = smb_init_irq(chip, &irq, "wdog-bark", smb_handle_wdog_bark); 1016 if (rc < 0) 1017 return rc; 1018 1019 + devm_device_init_wakeup(chip->dev); 1020 + 1021 + rc = devm_pm_set_wake_irq(chip->dev, chip->cable_irq); 1022 if (rc < 0) 1023 return dev_err_probe(chip->dev, rc, "Couldn't set wake irq\n"); 1024 ··· 1028 return 0; 1029 } 1030 1031 + static const struct of_device_id smb_match_id_table[] = { 1032 { .compatible = "qcom,pmi8998-charger", .data = "pmi8998" }, 1033 { .compatible = "qcom,pm660-charger", .data = "pm660" }, 1034 { /* sentinal */ } 1035 }; 1036 + MODULE_DEVICE_TABLE(of, smb_match_id_table); 1037 1038 + static struct platform_driver qcom_spmi_smb = { 1039 + .probe = smb_probe, 1040 .driver = { 1041 + .name = "qcom-smbx-charger", 1042 + .of_match_table = smb_match_id_table, 1043 }, 1044 }; 1045 1046 + module_platform_driver(qcom_spmi_smb); 1047 1048 MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>"); 1049 MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver");
-1
drivers/power/supply/twl4030_charger.c
··· 512 ret |= twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a, 513 TWL4030_BCIMDKEY); 514 if (bci->usb_enabled) { 515 - pm_runtime_mark_last_busy(bci->transceiver->dev); 516 pm_runtime_put_autosuspend(bci->transceiver->dev); 517 bci->usb_enabled = 0; 518 }
··· 512 ret |= twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a, 513 TWL4030_BCIMDKEY); 514 if (bci->usb_enabled) { 515 pm_runtime_put_autosuspend(bci->transceiver->dev); 516 bci->usb_enabled = 0; 517 }
+15 -66
drivers/power/supply/ug3105_battery.c
··· 66 #define UG3105_LOW_BAT_UV 3700000 67 #define UG3105_FULL_BAT_HYST_UV 38000 68 69 struct ug3105_chip { 70 struct i2c_client *client; 71 struct power_supply *psy; 72 - struct power_supply_battery_info *info; 73 struct delayed_work work; 74 struct mutex lock; 75 int ocv[UG3105_MOV_AVG_WINDOW]; /* micro-volt */ ··· 104 105 static int ug3105_get_status(struct ug3105_chip *chip) 106 { 107 - int full = chip->info->constant_charge_voltage_max_uv - UG3105_FULL_BAT_HYST_UV; 108 109 if (chip->curr > UG3105_CURR_HYST_UA) 110 return POWER_SUPPLY_STATUS_CHARGING; ··· 117 return POWER_SUPPLY_STATUS_FULL; 118 119 return POWER_SUPPLY_STATUS_NOT_CHARGING; 120 - } 121 - 122 - static int ug3105_get_capacity(struct ug3105_chip *chip) 123 - { 124 - /* 125 - * OCV voltages in uV for 0-110% in 5% increments, the 100-110% is 126 - * for LiPo HV (High-Voltage) bateries which can go up to 4.35V 127 - * instead of the usual 4.2V. 128 - */ 129 - static const int ocv_capacity_tbl[23] = { 130 - 3350000, 131 - 3610000, 132 - 3690000, 133 - 3710000, 134 - 3730000, 135 - 3750000, 136 - 3770000, 137 - 3786667, 138 - 3803333, 139 - 3820000, 140 - 3836667, 141 - 3853333, 142 - 3870000, 143 - 3907500, 144 - 3945000, 145 - 3982500, 146 - 4020000, 147 - 4075000, 148 - 4110000, 149 - 4150000, 150 - 4200000, 151 - 4250000, 152 - 4300000, 153 - }; 154 - int i, ocv_diff, ocv_step; 155 - 156 - if (chip->ocv_avg < ocv_capacity_tbl[0]) 157 - return 0; 158 - 159 - if (chip->status == POWER_SUPPLY_STATUS_FULL) 160 - return 100; 161 - 162 - for (i = 1; i < ARRAY_SIZE(ocv_capacity_tbl); i++) { 163 - if (chip->ocv_avg > ocv_capacity_tbl[i]) 164 - continue; 165 - 166 - ocv_diff = ocv_capacity_tbl[i] - chip->ocv_avg; 167 - ocv_step = ocv_capacity_tbl[i] - ocv_capacity_tbl[i - 1]; 168 - /* scale 0-110% down to 0-100% for LiPo HV */ 169 - if (chip->info->constant_charge_voltage_max_uv >= 4300000) 170 - return (i * 500 - ocv_diff * 500 / ocv_step) / 110; 171 - else 172 - return i * 5 - ocv_diff * 5 / ocv_step; 173 - } 174 - 175 - return 100; 176 } 177 178 static void ug3105_work(struct work_struct *work) ··· 177 178 chip->supplied = power_supply_am_i_supplied(psy); 179 chip->status = ug3105_get_status(chip); 180 - chip->capacity = ug3105_get_capacity(chip); 181 182 /* 183 * Skip internal resistance calc on charger [un]plug and ··· 352 if (IS_ERR(psy)) 353 return PTR_ERR(psy); 354 355 - ret = power_supply_get_battery_info(psy, &chip->info); 356 - if (ret) 357 - return ret; 358 - 359 - if (chip->info->factory_internal_resistance_uohm == -EINVAL || 360 - chip->info->constant_charge_voltage_max_uv == -EINVAL) { 361 dev_err(dev, "error required properties are missing\n"); 362 return -ENODEV; 363 } ··· 371 chip->ua_per_unit = 8100000 / curr_sense_res_uohm; 372 373 /* Use provided internal resistance as start point (in milli-ohm) */ 374 - chip->intern_res_avg = chip->info->factory_internal_resistance_uohm / 1000; 375 /* Also add it to the internal resistance moving average window */ 376 chip->intern_res[0] = chip->intern_res_avg; 377 chip->intern_res_avg_index = 1;
··· 66 #define UG3105_LOW_BAT_UV 3700000 67 #define UG3105_FULL_BAT_HYST_UV 38000 68 69 + #define AMBIENT_TEMP_CELCIUS 25 70 + 71 struct ug3105_chip { 72 struct i2c_client *client; 73 struct power_supply *psy; 74 struct delayed_work work; 75 struct mutex lock; 76 int ocv[UG3105_MOV_AVG_WINDOW]; /* micro-volt */ ··· 103 104 static int ug3105_get_status(struct ug3105_chip *chip) 105 { 106 + int full = chip->psy->battery_info->constant_charge_voltage_max_uv - 107 + UG3105_FULL_BAT_HYST_UV; 108 109 if (chip->curr > UG3105_CURR_HYST_UA) 110 return POWER_SUPPLY_STATUS_CHARGING; ··· 115 return POWER_SUPPLY_STATUS_FULL; 116 117 return POWER_SUPPLY_STATUS_NOT_CHARGING; 118 } 119 120 static void ug3105_work(struct work_struct *work) ··· 231 232 chip->supplied = power_supply_am_i_supplied(psy); 233 chip->status = ug3105_get_status(chip); 234 + if (chip->status == POWER_SUPPLY_STATUS_FULL) 235 + chip->capacity = 100; 236 + else 237 + chip->capacity = power_supply_batinfo_ocv2cap(chip->psy->battery_info, 238 + chip->ocv_avg, 239 + AMBIENT_TEMP_CELCIUS); 240 241 /* 242 * Skip internal resistance calc on charger [un]plug and ··· 401 if (IS_ERR(psy)) 402 return PTR_ERR(psy); 403 404 + if (!psy->battery_info || 405 + psy->battery_info->factory_internal_resistance_uohm == -EINVAL || 406 + psy->battery_info->constant_charge_voltage_max_uv == -EINVAL || 407 + !psy->battery_info->ocv_table[0]) { 408 dev_err(dev, "error required properties are missing\n"); 409 return -ENODEV; 410 } ··· 422 chip->ua_per_unit = 8100000 / curr_sense_res_uohm; 423 424 /* Use provided internal resistance as start point (in milli-ohm) */ 425 + chip->intern_res_avg = psy->battery_info->factory_internal_resistance_uohm / 1000; 426 /* Also add it to the internal resistance moving average window */ 427 chip->intern_res[0] = chip->intern_res_avg; 428 chip->intern_res_avg_index = 1;
+1 -1
drivers/regulator/act8865-regulator.c
··· 643 struct power_supply *charger; 644 struct power_supply_config cfg = { 645 .drv_data = regmap, 646 - .of_node = dev->of_node, 647 }; 648 649 charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
··· 643 struct power_supply *charger; 644 struct power_supply_config cfg = { 645 .drv_data = regmap, 646 + .fwnode = dev_fwnode(dev), 647 }; 648 649 charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
+3 -13
include/linux/power_supply.h
··· 232 233 /* Run-time specific power supply configuration */ 234 struct power_supply_config { 235 - struct device_node *of_node; 236 struct fwnode_handle *fwnode; 237 238 /* Driver private data */ ··· 807 static inline struct power_supply *power_supply_get_by_name(const char *name) 808 { return NULL; } 809 #endif 810 - #ifdef CONFIG_OF 811 - extern struct power_supply *power_supply_get_by_phandle(struct device_node *np, 812 - const char *property); 813 - extern struct power_supply *devm_power_supply_get_by_phandle( 814 struct device *dev, const char *property); 815 - #else /* !CONFIG_OF */ 816 - static inline struct power_supply * 817 - power_supply_get_by_phandle(struct device_node *np, const char *property) 818 - { return NULL; } 819 - static inline struct power_supply * 820 - devm_power_supply_get_by_phandle(struct device *dev, const char *property) 821 - { return NULL; } 822 - #endif /* CONFIG_OF */ 823 824 extern const enum power_supply_property power_supply_battery_info_properties[]; 825 extern const size_t power_supply_battery_info_properties_size;
··· 232 233 /* Run-time specific power supply configuration */ 234 struct power_supply_config { 235 struct fwnode_handle *fwnode; 236 237 /* Driver private data */ ··· 808 static inline struct power_supply *power_supply_get_by_name(const char *name) 809 { return NULL; } 810 #endif 811 + extern struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode, 812 + const char *property); 813 + extern struct power_supply *devm_power_supply_get_by_reference( 814 struct device *dev, const char *property); 815 816 extern const enum power_supply_property power_supply_battery_info_properties[]; 817 extern const size_t power_supply_battery_info_properties_size;