2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

power supply and reset changes for the 6.17 series

* 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
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmiMECsACgkQ2O7X88g7
 +pq18BAAgwWUJyV1YrzODAEC+GAIScV7E9aWHiWBYaR6huI6sXssgM9sUyQvSDw8
 IawbPGVeqgK2g7JHdLqduMILGrmNh268b2l3aJJzN0erM2bcIs9RtB2bMzJgSChH
 eDPOLKlQJJqR/PMQowHE4UEmbIep+8ISLP9GuiIa0e46ckdPWtAKnxWdReC3Pefs
 h9eRnzZof6A3dfoIhpCe182+RXPbVll7eHk8kvSYZgVUHHMfN509JDC7VMv6dG5p
 XOUiS6h2mebqoaNKBF7swr0nmkv4zLpLWBc//rreP+v26C97Ks+tfNrZ/fKrRR7E
 L7M1peg7KPLFooM3dQrngbaO2/h4am2kPb92YreXuDHMEBJQuauhOgAmrPOCFmJi
 l/nN2IbY4J9ArdsVbwATriFMPyem/N60xiq6Tr0F7DS9GBcO5dqX8g9iHY68Qu/g
 9HZAhiqrmxpUQ5cDUG1eYWSoK6YvdoP5bM7wJz8W5kbnIx2ngsMBhWPPh2fTmtoE
 c3qU7gSZK3jKUYAzu4vbFyL/htKc6ZO8ej2VDwjBb2OjVx+leYeC7kasRPDy5MkO
 G8Zuq9DZ1QAPp9aYAFVmZbHH1bTMD0UeYNMnSW/KaJZ5WecbUlzUkgCJvnH3JcYm
 5JbKDFykvItcyiS7+c6fflrJuv510Hf3R3degaqqXby4v80bMnY=
 =Lfxr
 -----END PGP SIGNATURE-----

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()
  ...
This commit is contained in:
Linus Torvalds 2025-07-31 21:39:01 -07:00
commit 07b4382043
33 changed files with 285 additions and 333 deletions

View File

@ -48,7 +48,6 @@ properties:
battery device. battery device.
monitored-battery: monitored-battery:
$ref: /schemas/types.yaml#/definitions/phandle
description: | description: |
phandle to a "simple-battery" compatible node. phandle to a "simple-battery" compatible node.

View File

@ -53,15 +53,16 @@ properties:
minimum: 50000 minimum: 50000
maximum: 500000 maximum: 500000
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the battery node being monitored
required: required:
- compatible - compatible
- reg - reg
- monitored-battery - monitored-battery
allOf:
- $ref: power-supply.yaml#
additionalProperties: false additionalProperties: false
examples: examples:

View File

@ -58,9 +58,7 @@ properties:
minimum: 100000 minimum: 100000
maximum: 3200000 maximum: 3200000
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the battery node being monitored
interrupts: interrupts:
maxItems: 1 maxItems: 1
@ -78,6 +76,7 @@ required:
- monitored-battery - monitored-battery
allOf: allOf:
- $ref: power-supply.yaml#
- if: - if:
properties: properties:
compatible: compatible:

View File

@ -73,9 +73,7 @@ properties:
description: | description: |
Indicates that the device state has changed. Indicates that the device state has changed.
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the battery node being monitored
required: required:
- compatible - compatible

View File

@ -43,10 +43,7 @@ properties:
minItems: 1 minItems: 1
maxItems: 8 # Should be enough maxItems: 8 # Should be enough
monitored-battery: monitored-battery: true
description:
Specifies the phandle of a simple-battery connected to this gauge
$ref: /schemas/types.yaml#/definitions/phandle
required: required:
- compatible - compatible

View File

@ -38,9 +38,7 @@ properties:
- const: usbin_i - const: usbin_i
- const: usbin_v - const: usbin_v
monitored-battery: monitored-battery: true
description: phandle to the simple-battery node
$ref: /schemas/types.yaml#/definitions/phandle
required: required:
- compatible - compatible
@ -51,6 +49,9 @@ required:
- io-channel-names - io-channel-names
- monitored-battery - monitored-battery
allOf:
- $ref: power-supply.yaml#
additionalProperties: false additionalProperties: false
examples: examples:

View File

@ -18,7 +18,6 @@ properties:
const: richtek,rt5033-charger const: richtek,rt5033-charger
monitored-battery: monitored-battery:
$ref: /schemas/types.yaml#/definitions/phandle
description: | description: |
Phandle to the monitored battery according to battery.yaml. The battery Phandle to the monitored battery according to battery.yaml. The battery
node needs to contain five parameters. node needs to contain five parameters.
@ -54,6 +53,9 @@ properties:
required: required:
- monitored-battery - monitored-battery
allOf:
- $ref: power-supply.yaml#
additionalProperties: false additionalProperties: false
examples: examples:

View File

@ -17,9 +17,7 @@ properties:
compatible: compatible:
const: stericsson,ab8500-btemp const: stericsson,ab8500-btemp
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to battery node
battery: battery:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle

View File

@ -17,9 +17,7 @@ properties:
compatible: compatible:
const: stericsson,ab8500-chargalg const: stericsson,ab8500-chargalg
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to battery node
battery: battery:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle

View File

@ -17,9 +17,7 @@ properties:
compatible: compatible:
const: stericsson,ab8500-charger const: stericsson,ab8500-charger
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to battery node
battery: battery:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle

View File

@ -17,9 +17,7 @@ properties:
compatible: compatible:
const: stericsson,ab8500-fg const: stericsson,ab8500-fg
monitored-battery: monitored-battery: true
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to battery node
battery: battery:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle

View File

@ -23,9 +23,7 @@ properties:
interrupts: interrupts:
maxItems: 1 maxItems: 1
monitored-battery: monitored-battery: true
description: phandle to the battery node
$ref: /schemas/types.yaml#/definitions/phandle
summit,enable-usb-charging: summit,enable-usb-charging:
type: boolean type: boolean
@ -94,6 +92,7 @@ properties:
unevaluatedProperties: false unevaluatedProperties: false
allOf: allOf:
- $ref: power-supply.yaml#
- if: - if:
properties: properties:
compatible: compatible:

View File

@ -26,11 +26,7 @@ properties:
- const: x-powers,axp813-battery-power-supply - const: x-powers,axp813-battery-power-supply
- const: x-powers,axp813-battery-power-supply - const: x-powers,axp813-battery-power-supply
monitored-battery: monitored-battery: true
description:
Specifies the phandle of an optional simple-battery connected to
this gauge.
$ref: /schemas/types.yaml#/definitions/phandle
x-powers,no-thermistor: x-powers,no-thermistor:
type: boolean type: boolean

View File

@ -20815,6 +20815,13 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
F: drivers/mtd/nand/raw/qcom_nandc.c F: drivers/mtd/nand/raw/qcom_nandc.c
QUALCOMM SMB CHARGER DRIVER
M: Casey Connolly <casey.connolly@linaro.org>
L: linux-arm-msm@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml
F: drivers/power/supply/qcom_smbx.c
QUALCOMM QSEECOM DRIVER QUALCOMM QSEECOM DRIVER
M: Maximilian Luz <luzmaximilian@gmail.com> M: Maximilian Luz <luzmaximilian@gmail.com>
L: linux-arm-msm@vger.kernel.org L: linux-arm-msm@vger.kernel.org

View File

@ -754,7 +754,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
} }
if (of_property_present(np, "usb0_vbus_power-supply")) { if (of_property_present(np, "usb0_vbus_power-supply")) {
data->vbus_power_supply = devm_power_supply_get_by_phandle(dev, data->vbus_power_supply = devm_power_supply_get_by_reference(dev,
"usb0_vbus_power-supply"); "usb0_vbus_power-supply");
if (IS_ERR(data->vbus_power_supply)) { if (IS_ERR(data->vbus_power_supply)) {
dev_err(dev, "Couldn't get the VBUS power supply\n"); dev_err(dev, "Couldn't get the VBUS power supply\n");

View File

@ -227,6 +227,7 @@ config POWER_RESET_ST
config POWER_RESET_TORADEX_EC config POWER_RESET_TORADEX_EC
tristate "Toradex Embedded Controller power-off and reset driver" tristate "Toradex Embedded Controller power-off and reset driver"
depends on ARCH_MXC || COMPILE_TEST
depends on I2C depends on I2C
select REGMAP_I2C select REGMAP_I2C
help help

View File

@ -129,7 +129,7 @@ static void at91_wakeup_status(struct platform_device *pdev)
else if (SHDW_RTTWK(reg, &rcfg->shdwc)) else if (SHDW_RTTWK(reg, &rcfg->shdwc))
reason = "RTT"; reason = "RTT";
pr_info("AT91: Wake-Up source: %s\n", reason); dev_info(&pdev->dev, "Wake-Up source: %s\n", reason);
} }
static void at91_poweroff(void) static void at91_poweroff(void)

View File

@ -19,7 +19,7 @@
#define NO_REASON_SHIFT 0 #define NO_REASON_SHIFT 0
struct pm8916_pon { struct qcom_pon {
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
u32 baseaddr; u32 baseaddr;
@ -27,11 +27,11 @@ struct pm8916_pon {
long reason_shift; long reason_shift;
}; };
static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot, static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot,
unsigned int magic) unsigned int magic)
{ {
struct pm8916_pon *pon = container_of struct qcom_pon *pon = container_of
(reboot, struct pm8916_pon, reboot_mode); (reboot, struct qcom_pon, reboot_mode);
int ret; int ret;
ret = regmap_update_bits(pon->regmap, ret = regmap_update_bits(pon->regmap,
@ -44,9 +44,9 @@ static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot,
return ret; return ret;
} }
static int pm8916_pon_probe(struct platform_device *pdev) static int qcom_pon_probe(struct platform_device *pdev)
{ {
struct pm8916_pon *pon; struct qcom_pon *pon;
long reason_shift; long reason_shift;
int error; int error;
@ -72,7 +72,7 @@ static int pm8916_pon_probe(struct platform_device *pdev)
if (reason_shift != NO_REASON_SHIFT) { if (reason_shift != NO_REASON_SHIFT) {
pon->reboot_mode.dev = &pdev->dev; pon->reboot_mode.dev = &pdev->dev;
pon->reason_shift = reason_shift; pon->reason_shift = reason_shift;
pon->reboot_mode.write = pm8916_reboot_mode_write; pon->reboot_mode.write = qcom_pon_reboot_mode_write;
error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode); error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode);
if (error) { if (error) {
dev_err(&pdev->dev, "can't register reboot mode\n"); dev_err(&pdev->dev, "can't register reboot mode\n");
@ -85,7 +85,7 @@ static int pm8916_pon_probe(struct platform_device *pdev)
return devm_of_platform_populate(&pdev->dev); return devm_of_platform_populate(&pdev->dev);
} }
static const struct of_device_id pm8916_pon_id_table[] = { static const struct of_device_id qcom_pon_id_table[] = {
{ .compatible = "qcom,pm8916-pon", .data = (void *)GEN1_REASON_SHIFT }, { .compatible = "qcom,pm8916-pon", .data = (void *)GEN1_REASON_SHIFT },
{ .compatible = "qcom,pm8941-pon", .data = (void *)NO_REASON_SHIFT }, { .compatible = "qcom,pm8941-pon", .data = (void *)NO_REASON_SHIFT },
{ .compatible = "qcom,pms405-pon", .data = (void *)GEN1_REASON_SHIFT }, { .compatible = "qcom,pms405-pon", .data = (void *)GEN1_REASON_SHIFT },
@ -93,16 +93,16 @@ static const struct of_device_id pm8916_pon_id_table[] = {
{ .compatible = "qcom,pmk8350-pon", .data = (void *)GEN2_REASON_SHIFT }, { .compatible = "qcom,pmk8350-pon", .data = (void *)GEN2_REASON_SHIFT },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, pm8916_pon_id_table); MODULE_DEVICE_TABLE(of, qcom_pon_id_table);
static struct platform_driver pm8916_pon_driver = { static struct platform_driver qcom_pon_driver = {
.probe = pm8916_pon_probe, .probe = qcom_pon_probe,
.driver = { .driver = {
.name = "pm8916-pon", .name = "qcom-pon",
.of_match_table = pm8916_pon_id_table, .of_match_table = qcom_pon_id_table,
}, },
}; };
module_platform_driver(pm8916_pon_driver); module_platform_driver(qcom_pon_driver);
MODULE_DESCRIPTION("pm8916 Power On driver"); MODULE_DESCRIPTION("Qualcomm Power On driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -120,5 +120,5 @@ obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o
obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o
obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o obj-$(CONFIG_BATTERY_UG3105) += ug3105_battery.o
obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_pmi8998_charger.o obj-$(CONFIG_CHARGER_QCOM_SMB2) += qcom_smbx.o
obj-$(CONFIG_FUEL_GAUGE_MM8013) += mm8013.o obj-$(CONFIG_FUEL_GAUGE_MM8013) += mm8013.o

View File

@ -1674,7 +1674,7 @@ static int bq2415x_probe(struct i2c_client *client)
/* Query for initial reported_mode and set it */ /* Query for initial reported_mode and set it */
if (bq->nb.notifier_call) { if (bq->nb.notifier_call) {
if (np) { if (np) {
notify_psy = power_supply_get_by_phandle(np, notify_psy = power_supply_get_by_reference(of_fwnode_handle(np),
"ti,usb-charger-detection"); "ti,usb-charger-detection");
if (IS_ERR(notify_psy)) if (IS_ERR(notify_psy))
notify_psy = NULL; notify_psy = NULL;

View File

@ -504,7 +504,6 @@ static ssize_t bq24190_sysfs_show(struct device *dev,
else else
count = sysfs_emit(buf, "%hhx\n", v); count = sysfs_emit(buf, "%hhx\n", v);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return count; return count;
@ -535,7 +534,6 @@ static ssize_t bq24190_sysfs_store(struct device *dev,
if (ret) if (ret)
count = ret; count = ret;
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return count; return count;
@ -562,7 +560,6 @@ static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
else else
ret = bq24190_charger_set_charge_type(bdi, &val); ret = bq24190_charger_set_charge_type(bdi, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -605,7 +602,6 @@ static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
} }
out: out:
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -638,7 +634,6 @@ static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
BQ24190_REG_POC_CHG_CONFIG_MASK, BQ24190_REG_POC_CHG_CONFIG_MASK,
BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val); BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
if (ret) if (ret)
@ -675,7 +670,6 @@ static int bq24296_vbus_is_enabled(struct regulator_dev *dev)
BQ24296_REG_POC_OTG_CONFIG_MASK, BQ24296_REG_POC_OTG_CONFIG_MASK,
BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val); BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
if (ret) if (ret)
@ -1376,7 +1370,6 @@ static int bq24190_charger_get_property(struct power_supply *psy,
ret = -ENODATA; ret = -ENODATA;
} }
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -1419,7 +1412,6 @@ static int bq24190_charger_set_property(struct power_supply *psy,
ret = -EINVAL; ret = -EINVAL;
} }
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -1682,7 +1674,6 @@ static int bq24190_battery_get_property(struct power_supply *psy,
ret = -ENODATA; ret = -ENODATA;
} }
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -1713,7 +1704,6 @@ static int bq24190_battery_set_property(struct power_supply *psy,
ret = -EINVAL; ret = -EINVAL;
} }
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
return ret; return ret;
@ -1861,7 +1851,6 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
return IRQ_NONE; return IRQ_NONE;
} }
bq24190_check_status(bdi); bq24190_check_status(bdi);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
bdi->irq_event = false; bdi->irq_event = false;
@ -1983,6 +1972,8 @@ static int bq24190_get_config(struct bq24190_dev_info *bdi)
v = info->constant_charge_voltage_max_uv; v = info->constant_charge_voltage_max_uv;
if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max) if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max)
bdi->vreg = bdi->vreg_max = v; bdi->vreg = bdi->vreg_max = v;
power_supply_put_battery_info(bdi->charger, info);
} }
return 0; return 0;
@ -2186,7 +2177,6 @@ static int bq24190_probe(struct i2c_client *client)
enable_irq_wake(client->irq); enable_irq_wake(client->irq);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev); pm_runtime_put_autosuspend(dev);
return 0; return 0;
@ -2273,7 +2263,6 @@ static __maybe_unused int bq24190_pm_suspend(struct device *dev)
bq24190_register_reset(bdi); bq24190_register_reset(bdi);
if (error >= 0) { if (error >= 0) {
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
} }
@ -2298,7 +2287,6 @@ static __maybe_unused int bq24190_pm_resume(struct device *dev)
bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
if (error >= 0) { if (error >= 0) {
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev); pm_runtime_put_autosuspend(bdi->dev);
} }

View File

@ -387,7 +387,7 @@ static void bq256xx_usb_work(struct work_struct *data)
} }
} }
static struct reg_default bq2560x_reg_defs[] = { static const struct reg_default bq2560x_reg_defs[] = {
{BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, {BQ256XX_INPUT_CURRENT_LIMIT, 0x17},
{BQ256XX_CHARGER_CONTROL_0, 0x1a}, {BQ256XX_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0xa2}, {BQ256XX_CHARGE_CURRENT_LIMIT, 0xa2},
@ -398,7 +398,7 @@ static struct reg_default bq2560x_reg_defs[] = {
{BQ256XX_CHARGER_CONTROL_3, 0x4c}, {BQ256XX_CHARGER_CONTROL_3, 0x4c},
}; };
static struct reg_default bq25611d_reg_defs[] = { static const struct reg_default bq25611d_reg_defs[] = {
{BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, {BQ256XX_INPUT_CURRENT_LIMIT, 0x17},
{BQ256XX_CHARGER_CONTROL_0, 0x1a}, {BQ256XX_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0x91}, {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},
@ -411,7 +411,7 @@ static struct reg_default bq25611d_reg_defs[] = {
{BQ256XX_CHARGER_CONTROL_4, 0x75}, {BQ256XX_CHARGER_CONTROL_4, 0x75},
}; };
static struct reg_default bq25618_619_reg_defs[] = { static const struct reg_default bq25618_619_reg_defs[] = {
{BQ256XX_INPUT_CURRENT_LIMIT, 0x17}, {BQ256XX_INPUT_CURRENT_LIMIT, 0x17},
{BQ256XX_CHARGER_CONTROL_0, 0x1a}, {BQ256XX_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0x91}, {BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},

View File

@ -104,7 +104,7 @@ struct bq25980_device {
int watchdog_timer; int watchdog_timer;
}; };
static struct reg_default bq25980_reg_defs[] = { static const struct reg_default bq25980_reg_defs[] = {
{BQ25980_BATOVP, 0x5A}, {BQ25980_BATOVP, 0x5A},
{BQ25980_BATOVP_ALM, 0x46}, {BQ25980_BATOVP_ALM, 0x46},
{BQ25980_BATOCP, 0x51}, {BQ25980_BATOCP, 0x51},
@ -159,7 +159,7 @@ static struct reg_default bq25980_reg_defs[] = {
{BQ25980_CHRGR_CTRL_6, 0x0}, {BQ25980_CHRGR_CTRL_6, 0x0},
}; };
static struct reg_default bq25975_reg_defs[] = { static const struct reg_default bq25975_reg_defs[] = {
{BQ25980_BATOVP, 0x5A}, {BQ25980_BATOVP, 0x5A},
{BQ25980_BATOVP_ALM, 0x46}, {BQ25980_BATOVP_ALM, 0x46},
{BQ25980_BATOCP, 0x51}, {BQ25980_BATOCP, 0x51},
@ -214,7 +214,7 @@ static struct reg_default bq25975_reg_defs[] = {
{BQ25980_CHRGR_CTRL_6, 0x0}, {BQ25980_CHRGR_CTRL_6, 0x0},
}; };
static struct reg_default bq25960_reg_defs[] = { static const struct reg_default bq25960_reg_defs[] = {
{BQ25980_BATOVP, 0x5A}, {BQ25980_BATOVP, 0x5A},
{BQ25980_BATOVP_ALM, 0x46}, {BQ25980_BATOVP_ALM, 0x46},
{BQ25980_BATOCP, 0x51}, {BQ25980_BATOCP, 0x51},

View File

@ -689,9 +689,8 @@ static void cpcap_usb_detect(struct work_struct *work)
struct power_supply *battery; struct power_supply *battery;
battery = power_supply_get_by_name("battery"); battery = power_supply_get_by_name("battery");
if (IS_ERR_OR_NULL(battery)) { if (!battery) {
dev_err(ddata->dev, "battery power_supply not available %li\n", dev_err(ddata->dev, "battery power_supply not available\n");
PTR_ERR(battery));
return; return;
} }

View File

@ -501,7 +501,7 @@ static struct max14577_charger_platform_data *max14577_charger_dt_init(
static struct max14577_charger_platform_data *max14577_charger_dt_init( static struct max14577_charger_platform_data *max14577_charger_dt_init(
struct platform_device *pdev) struct platform_device *pdev)
{ {
return NULL; return ERR_PTR(-ENODATA);
} }
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
@ -572,7 +572,7 @@ static int max14577_charger_probe(struct platform_device *pdev)
chg->max14577 = max14577; chg->max14577 = max14577;
chg->pdata = max14577_charger_dt_init(pdev); chg->pdata = max14577_charger_dt_init(pdev);
if (IS_ERR_OR_NULL(chg->pdata)) if (IS_ERR(chg->pdata))
return PTR_ERR(chg->pdata); return PTR_ERR(chg->pdata);
ret = max14577_charger_reg_init(chg); ret = max14577_charger_reg_init(chg);

View File

@ -288,9 +288,10 @@ static int max172xx_voltage_to_ps(unsigned int reg)
return reg * 1250; /* in uV */ return reg * 1250; /* in uV */
} }
static int max172xx_capacity_to_ps(unsigned int reg) static int max172xx_capacity_to_ps(unsigned int reg,
struct max1720x_device_info *info)
{ {
return reg * 500; /* in uAh */ return reg * (500000 / info->rsense); /* in uAh */
} }
/* /*
@ -394,11 +395,11 @@ static int max1720x_battery_get_property(struct power_supply *psy,
break; break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
ret = regmap_read(info->regmap, MAX172XX_DESIGN_CAP, &reg_val); ret = regmap_read(info->regmap, MAX172XX_DESIGN_CAP, &reg_val);
val->intval = max172xx_capacity_to_ps(reg_val); val->intval = max172xx_capacity_to_ps(reg_val, info);
break; break;
case POWER_SUPPLY_PROP_CHARGE_AVG: case POWER_SUPPLY_PROP_CHARGE_AVG:
ret = regmap_read(info->regmap, MAX172XX_REPCAP, &reg_val); ret = regmap_read(info->regmap, MAX172XX_REPCAP, &reg_val);
val->intval = max172xx_capacity_to_ps(reg_val); val->intval = max172xx_capacity_to_ps(reg_val, info);
break; break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
ret = regmap_read(info->regmap, MAX172XX_TTE, &reg_val); ret = regmap_read(info->regmap, MAX172XX_TTE, &reg_val);
@ -422,10 +423,12 @@ static int max1720x_battery_get_property(struct power_supply *psy,
break; break;
case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_CHARGE_FULL:
ret = regmap_read(info->regmap, MAX172XX_FULL_CAP, &reg_val); ret = regmap_read(info->regmap, MAX172XX_FULL_CAP, &reg_val);
val->intval = max172xx_capacity_to_ps(reg_val); val->intval = max172xx_capacity_to_ps(reg_val, info);
break; break;
case POWER_SUPPLY_PROP_MODEL_NAME: case POWER_SUPPLY_PROP_MODEL_NAME:
ret = regmap_read(info->regmap, MAX172XX_DEV_NAME, &reg_val); ret = regmap_read(info->regmap, MAX172XX_DEV_NAME, &reg_val);
if (ret)
return ret;
reg_val = FIELD_GET(MAX172XX_DEV_NAME_TYPE_MASK, reg_val); reg_val = FIELD_GET(MAX172XX_DEV_NAME_TYPE_MASK, reg_val);
if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17201) if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17201)
val->strval = max17201_model; val->strval = max17201_model;

View File

@ -18,7 +18,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/thermal.h> #include <linux/thermal.h>
@ -196,24 +195,24 @@ static int __power_supply_populate_supplied_from(struct power_supply *epsy,
void *data) void *data)
{ {
struct power_supply *psy = data; struct power_supply *psy = data;
struct device_node *np; struct fwnode_handle *np;
int i = 0; int i = 0;
do { do {
np = of_parse_phandle(psy->dev.of_node, "power-supplies", i++); np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", i++);
if (!np) if (IS_ERR(np))
break; break;
if (np == epsy->dev.of_node) { if (np == epsy->dev.fwnode) {
dev_dbg(&psy->dev, "%s: Found supply : %s\n", dev_dbg(&psy->dev, "%s: Found supply : %s\n",
psy->desc->name, epsy->desc->name); psy->desc->name, epsy->desc->name);
psy->supplied_from[i-1] = (char *)epsy->desc->name; psy->supplied_from[i-1] = (char *)epsy->desc->name;
psy->num_supplies++; psy->num_supplies++;
of_node_put(np); fwnode_handle_put(np);
break; break;
} }
of_node_put(np); fwnode_handle_put(np);
} while (np); } while (true);
return 0; return 0;
} }
@ -232,16 +231,16 @@ static int power_supply_populate_supplied_from(struct power_supply *psy)
static int __power_supply_find_supply_from_node(struct power_supply *epsy, static int __power_supply_find_supply_from_node(struct power_supply *epsy,
void *data) void *data)
{ {
struct device_node *np = data; struct fwnode_handle *fwnode = data;
/* returning non-zero breaks out of power_supply_for_each_psy loop */ /* returning non-zero breaks out of power_supply_for_each_psy loop */
if (epsy->dev.of_node == np) if (epsy->dev.fwnode == fwnode)
return 1; return 1;
return 0; return 0;
} }
static int power_supply_find_supply_from_node(struct device_node *supply_node) static int power_supply_find_supply_from_fwnode(struct fwnode_handle *supply_node)
{ {
int error; int error;
@ -249,7 +248,7 @@ static int power_supply_find_supply_from_node(struct device_node *supply_node)
* power_supply_for_each_psy() either returns its own errors or values * power_supply_for_each_psy() either returns its own errors or values
* returned by __power_supply_find_supply_from_node(). * returned by __power_supply_find_supply_from_node().
* *
* __power_supply_find_supply_from_node() will return 0 (no match) * __power_supply_find_supply_from_fwnode() will return 0 (no match)
* or 1 (match). * or 1 (match).
* *
* We return 0 if power_supply_for_each_psy() returned 1, -EPROBE_DEFER if * We return 0 if power_supply_for_each_psy() returned 1, -EPROBE_DEFER if
@ -262,7 +261,7 @@ static int power_supply_find_supply_from_node(struct device_node *supply_node)
static int power_supply_check_supplies(struct power_supply *psy) static int power_supply_check_supplies(struct power_supply *psy)
{ {
struct device_node *np; struct fwnode_handle *np;
int cnt = 0; int cnt = 0;
/* If there is already a list honor it */ /* If there is already a list honor it */
@ -270,24 +269,24 @@ static int power_supply_check_supplies(struct power_supply *psy)
return 0; return 0;
/* No device node found, nothing to do */ /* No device node found, nothing to do */
if (!psy->dev.of_node) if (!psy->dev.fwnode)
return 0; return 0;
do { do {
int ret; int ret;
np = of_parse_phandle(psy->dev.of_node, "power-supplies", cnt++); np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", cnt++);
if (!np) if (IS_ERR(np))
break; break;
ret = power_supply_find_supply_from_node(np); ret = power_supply_find_supply_from_fwnode(np);
of_node_put(np); fwnode_handle_put(np);
if (ret) { if (ret) {
dev_dbg(&psy->dev, "Failed to find supply!\n"); dev_dbg(&psy->dev, "Failed to find supply!\n");
return ret; return ret;
} }
} while (np); } while (!IS_ERR(np));
/* Missing valid "power-supplies" entries */ /* Missing valid "power-supplies" entries */
if (cnt == 1) if (cnt == 1)
@ -497,15 +496,14 @@ void power_supply_put(struct power_supply *psy)
} }
EXPORT_SYMBOL_GPL(power_supply_put); EXPORT_SYMBOL_GPL(power_supply_put);
#ifdef CONFIG_OF static int power_supply_match_device_fwnode(struct device *dev, const void *data)
static int power_supply_match_device_node(struct device *dev, const void *data)
{ {
return dev->parent && dev->parent->of_node == data; return dev->parent && dev_fwnode(dev->parent) == data;
} }
/** /**
* power_supply_get_by_phandle() - Search for a power supply and returns its ref * power_supply_get_by_reference() - Search for a power supply and returns its ref
* @np: Pointer to device node holding phandle property * @fwnode: Pointer to fwnode holding phandle property
* @property: Name of property holding a power supply name * @property: Name of property holding a power supply name
* *
* If power supply was found, it increases reference count for the * If power supply was found, it increases reference count for the
@ -515,21 +513,21 @@ static int power_supply_match_device_node(struct device *dev, const void *data)
* Return: On success returns a reference to a power supply with * Return: On success returns a reference to a power supply with
* matching name equals to value under @property, NULL or ERR_PTR otherwise. * matching name equals to value under @property, NULL or ERR_PTR otherwise.
*/ */
struct power_supply *power_supply_get_by_phandle(struct device_node *np, struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode,
const char *property) const char *property)
{ {
struct device_node *power_supply_np; struct fwnode_handle *power_supply_fwnode;
struct power_supply *psy = NULL; struct power_supply *psy = NULL;
struct device *dev; struct device *dev;
power_supply_np = of_parse_phandle(np, property, 0); power_supply_fwnode = fwnode_find_reference(fwnode, property, 0);
if (!power_supply_np) if (IS_ERR(power_supply_fwnode))
return ERR_PTR(-ENODEV); return ERR_CAST(power_supply_fwnode);
dev = class_find_device(&power_supply_class, NULL, power_supply_np, dev = class_find_device(&power_supply_class, NULL, power_supply_fwnode,
power_supply_match_device_node); power_supply_match_device_fwnode);
of_node_put(power_supply_np); fwnode_handle_put(power_supply_fwnode);
if (dev) { if (dev) {
psy = dev_to_psy(dev); psy = dev_to_psy(dev);
@ -538,7 +536,7 @@ struct power_supply *power_supply_get_by_phandle(struct device_node *np,
return psy; return psy;
} }
EXPORT_SYMBOL_GPL(power_supply_get_by_phandle); EXPORT_SYMBOL_GPL(power_supply_get_by_reference);
static void devm_power_supply_put(struct device *dev, void *res) static void devm_power_supply_put(struct device *dev, void *res)
{ {
@ -548,27 +546,27 @@ static void devm_power_supply_put(struct device *dev, void *res)
} }
/** /**
* devm_power_supply_get_by_phandle() - Resource managed version of * devm_power_supply_get_by_reference() - Resource managed version of
* power_supply_get_by_phandle() * power_supply_get_by_reference()
* @dev: Pointer to device holding phandle property * @dev: Pointer to device holding phandle property
* @property: Name of property holding a power supply phandle * @property: Name of property holding a power supply phandle
* *
* Return: On success returns a reference to a power supply with * Return: On success returns a reference to a power supply with
* matching name equals to value under @property, NULL or ERR_PTR otherwise. * matching name equals to value under @property, NULL or ERR_PTR otherwise.
*/ */
struct power_supply *devm_power_supply_get_by_phandle(struct device *dev, struct power_supply *devm_power_supply_get_by_reference(struct device *dev,
const char *property) const char *property)
{ {
struct power_supply **ptr, *psy; struct power_supply **ptr, *psy;
if (!dev->of_node) if (!dev_fwnode(dev))
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL); ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL);
if (!ptr) if (!ptr)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
psy = power_supply_get_by_phandle(dev->of_node, property); psy = power_supply_get_by_reference(dev_fwnode(dev), property);
if (IS_ERR_OR_NULL(psy)) { if (IS_ERR_OR_NULL(psy)) {
devres_free(ptr); devres_free(ptr);
} else { } else {
@ -577,40 +575,26 @@ struct power_supply *devm_power_supply_get_by_phandle(struct device *dev,
} }
return psy; return psy;
} }
EXPORT_SYMBOL_GPL(devm_power_supply_get_by_phandle); EXPORT_SYMBOL_GPL(devm_power_supply_get_by_reference);
#endif /* CONFIG_OF */
int power_supply_get_battery_info(struct power_supply *psy, int power_supply_get_battery_info(struct power_supply *psy,
struct power_supply_battery_info **info_out) struct power_supply_battery_info **info_out)
{ {
struct power_supply_resistance_temp_table *resist_table; struct power_supply_resistance_temp_table *resist_table;
struct power_supply_battery_info *info; struct power_supply_battery_info *info;
struct device_node *battery_np = NULL; struct fwnode_handle *srcnode, *fwnode;
struct fwnode_reference_args args;
struct fwnode_handle *fwnode = NULL;
const char *value; const char *value;
int err, len, index; int err, len, index, proplen;
const __be32 *list; u32 *propdata __free(kfree) = NULL;
u32 min_max[2]; u32 min_max[2];
if (psy->dev.of_node) { srcnode = dev_fwnode(&psy->dev);
battery_np = of_parse_phandle(psy->dev.of_node, "monitored-battery", 0); if (!srcnode && psy->dev.parent)
if (!battery_np) srcnode = dev_fwnode(psy->dev.parent);
return -ENODEV;
fwnode = fwnode_handle_get(of_fwnode_handle(battery_np)); fwnode = fwnode_find_reference(srcnode, "monitored-battery", 0);
} else if (psy->dev.parent) { if (IS_ERR(fwnode))
err = fwnode_property_get_reference_args( return PTR_ERR(fwnode);
dev_fwnode(psy->dev.parent),
"monitored-battery", NULL, 0, 0, &args);
if (err)
return err;
fwnode = args.fwnode;
}
if (!fwnode)
return -ENOENT;
err = fwnode_property_read_string(fwnode, "compatible", &value); err = fwnode_property_read_string(fwnode, "compatible", &value);
if (err) if (err)
@ -740,15 +724,7 @@ int power_supply_get_battery_info(struct power_supply *psy,
info->temp_max = min_max[1]; info->temp_max = min_max[1];
} }
/* len = fwnode_property_count_u32(fwnode, "ocv-capacity-celsius");
* The below code uses raw of-data parsing to parse
* /schemas/types.yaml#/definitions/uint32-matrix
* data, so for now this is only support with of.
*/
if (!battery_np)
goto out_ret_pointer;
len = of_property_count_u32_elems(battery_np, "ocv-capacity-celsius");
if (len < 0 && len != -EINVAL) { if (len < 0 && len != -EINVAL) {
err = len; err = len;
goto out_put_node; goto out_put_node;
@ -757,13 +733,13 @@ int power_supply_get_battery_info(struct power_supply *psy,
err = -EINVAL; err = -EINVAL;
goto out_put_node; goto out_put_node;
} else if (len > 0) { } else if (len > 0) {
of_property_read_u32_array(battery_np, "ocv-capacity-celsius", fwnode_property_read_u32_array(fwnode, "ocv-capacity-celsius",
info->ocv_temp, len); info->ocv_temp, len);
} }
for (index = 0; index < len; index++) { for (index = 0; index < len; index++) {
struct power_supply_battery_ocv_table *table; struct power_supply_battery_ocv_table *table;
int i, tab_len, size; int i, tab_len;
char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d",
index); index);
@ -772,15 +748,28 @@ int power_supply_get_battery_info(struct power_supply *psy,
err = -ENOMEM; err = -ENOMEM;
goto out_put_node; goto out_put_node;
} }
list = of_get_property(battery_np, propname, &size); proplen = fwnode_property_count_u32(fwnode, propname);
if (!list || !size) { if (proplen < 0 || proplen % 2 != 0) {
dev_err(&psy->dev, "failed to get %s\n", propname); dev_err(&psy->dev, "failed to get %s\n", propname);
power_supply_put_battery_info(psy, info); power_supply_put_battery_info(psy, info);
err = -EINVAL; err = -EINVAL;
goto out_put_node; goto out_put_node;
} }
tab_len = size / (2 * sizeof(__be32)); u32 *propdata __free(kfree) = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL);
if (!propdata) {
power_supply_put_battery_info(psy, info);
err = -EINVAL;
goto out_put_node;
}
err = fwnode_property_read_u32_array(fwnode, propname, propdata, proplen);
if (err < 0) {
dev_err(&psy->dev, "failed to get %s\n", propname);
power_supply_put_battery_info(psy, info);
goto out_put_node;
}
tab_len = proplen / 2;
info->ocv_table_size[index] = tab_len; info->ocv_table_size[index] = tab_len;
info->ocv_table[index] = table = info->ocv_table[index] = table =
@ -792,18 +781,36 @@ int power_supply_get_battery_info(struct power_supply *psy,
} }
for (i = 0; i < tab_len; i++) { for (i = 0; i < tab_len; i++) {
table[i].ocv = be32_to_cpu(*list); table[i].ocv = propdata[i*2];
list++; table[i].capacity = propdata[i*2+1];
table[i].capacity = be32_to_cpu(*list);
list++;
} }
} }
list = of_get_property(battery_np, "resistance-temp-table", &len); proplen = fwnode_property_count_u32(fwnode, "resistance-temp-table");
if (!list || !len) if (proplen == 0 || proplen == -EINVAL) {
err = 0;
goto out_ret_pointer; goto out_ret_pointer;
} else if (proplen < 0 || proplen % 2 != 0) {
power_supply_put_battery_info(psy, info);
err = (proplen < 0) ? proplen : -EINVAL;
goto out_put_node;
}
info->resist_table_size = len / (2 * sizeof(__be32)); propdata = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL);
if (!propdata) {
power_supply_put_battery_info(psy, info);
err = -ENOMEM;
goto out_put_node;
}
err = fwnode_property_read_u32_array(fwnode, "resistance-temp-table",
propdata, proplen);
if (err < 0) {
power_supply_put_battery_info(psy, info);
goto out_put_node;
}
info->resist_table_size = proplen / 2;
info->resist_table = resist_table = devm_kcalloc(&psy->dev, info->resist_table = resist_table = devm_kcalloc(&psy->dev,
info->resist_table_size, info->resist_table_size,
sizeof(*resist_table), sizeof(*resist_table),
@ -815,8 +822,8 @@ int power_supply_get_battery_info(struct power_supply *psy,
} }
for (index = 0; index < info->resist_table_size; index++) { for (index = 0; index < info->resist_table_size; index++) {
resist_table[index].temp = be32_to_cpu(*list++); resist_table[index].temp = propdata[index*2];
resist_table[index].resistance = be32_to_cpu(*list++); resist_table[index].resistance = propdata[index*2+1];
} }
out_ret_pointer: out_ret_pointer:
@ -825,7 +832,6 @@ out_ret_pointer:
out_put_node: out_put_node:
fwnode_handle_put(fwnode); fwnode_handle_put(fwnode);
of_node_put(battery_np);
return err; return err;
} }
EXPORT_SYMBOL_GPL(power_supply_get_battery_info); EXPORT_SYMBOL_GPL(power_supply_get_battery_info);
@ -1587,10 +1593,9 @@ __power_supply_register(struct device *parent,
dev_set_drvdata(dev, psy); dev_set_drvdata(dev, psy);
psy->desc = desc; psy->desc = desc;
if (cfg) { if (cfg) {
device_set_node(dev, cfg->fwnode);
dev->groups = cfg->attr_grp; dev->groups = cfg->attr_grp;
psy->drv_data = cfg->drv_data; psy->drv_data = cfg->drv_data;
dev->of_node =
cfg->fwnode ? to_of_node(cfg->fwnode) : cfg->of_node;
psy->supplied_to = cfg->supplied_to; psy->supplied_to = cfg->supplied_to;
psy->num_supplicants = cfg->num_supplicants; psy->num_supplicants = cfg->num_supplicants;
} }

View File

@ -577,6 +577,8 @@ static int qcom_battmgr_bat_get_property(struct power_supply *psy,
val->intval = battmgr->status.capacity; val->intval = battmgr->status.capacity;
break; break;
case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_CAPACITY:
if (battmgr->status.percent == (unsigned int)-1)
return -ENODATA;
val->intval = battmgr->status.percent; val->intval = battmgr->status.percent;
break; break;
case POWER_SUPPLY_PROP_TEMP: case POWER_SUPPLY_PROP_TEMP:
@ -617,6 +619,7 @@ static const enum power_supply_property sc8280xp_bat_props[] = {
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_NOW,
@ -981,6 +984,8 @@ static unsigned int qcom_battmgr_sc8280xp_parse_technology(const char *chemistry
{ {
if (!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN)) if (!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN))
return POWER_SUPPLY_TECHNOLOGY_LION; return POWER_SUPPLY_TECHNOLOGY_LION;
if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN))
return POWER_SUPPLY_TECHNOLOGY_LIPO;
pr_err("Unknown battery technology '%s'\n", chemistry); pr_err("Unknown battery technology '%s'\n", chemistry);
return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
@ -1063,6 +1068,26 @@ static void qcom_battmgr_sc8280xp_callback(struct qcom_battmgr *battmgr,
battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC; battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC;
battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB; battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB;
battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS; battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS;
if (battmgr->info.last_full_capacity != 0) {
/*
* 100 * battmgr->status.capacity can overflow a 32bit
* unsigned integer. FW readings are in m{W/A}h, which
* are multiplied by 1000 converting them to u{W/A}h,
* the format the power_supply API expects.
* To avoid overflow use the original value for dividend
* and convert the divider back to m{W/A}h, which can be
* done without any loss of precision.
*/
battmgr->status.percent =
(100 * le32_to_cpu(resp->status.capacity)) /
(battmgr->info.last_full_capacity / 1000);
} else {
/*
* Let the sysfs handler know no data is available at
* this time.
*/
battmgr->status.percent = (unsigned int)-1;
}
break; break;
case BATTMGR_BAT_DISCHARGE_TIME: case BATTMGR_BAT_DISCHARGE_TIME:
battmgr->status.discharge_time = le32_to_cpu(resp->time); battmgr->status.discharge_time = le32_to_cpu(resp->time);

View File

@ -362,17 +362,17 @@ enum charger_status {
DISABLE_CHARGE, DISABLE_CHARGE,
}; };
struct smb2_register { struct smb_init_register {
u16 addr; u16 addr;
u8 mask; u8 mask;
u8 val; u8 val;
}; };
/** /**
* struct smb2_chip - smb2 chip structure * struct smb_chip - smb chip structure
* @dev: Device reference for power_supply * @dev: Device reference for power_supply
* @name: The platform device name * @name: The platform device name
* @base: Base address for smb2 registers * @base: Base address for smb registers
* @regmap: Register map * @regmap: Register map
* @batt_info: Battery data from DT * @batt_info: Battery data from DT
* @status_change_work: Worker to handle plug/unplug events * @status_change_work: Worker to handle plug/unplug events
@ -382,7 +382,7 @@ struct smb2_register {
* @usb_in_v_chan: USB_IN voltage measurement channel * @usb_in_v_chan: USB_IN voltage measurement channel
* @chg_psy: Charger power supply instance * @chg_psy: Charger power supply instance
*/ */
struct smb2_chip { struct smb_chip {
struct device *dev; struct device *dev;
const char *name; const char *name;
unsigned int base; unsigned int base;
@ -399,7 +399,7 @@ struct smb2_chip {
struct power_supply *chg_psy; struct power_supply *chg_psy;
}; };
static enum power_supply_property smb2_properties[] = { static enum power_supply_property smb_properties[] = {
POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_MAX,
@ -411,7 +411,7 @@ static enum power_supply_property smb2_properties[] = {
POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_USB_TYPE,
}; };
static int smb2_get_prop_usb_online(struct smb2_chip *chip, int *val) static int smb_get_prop_usb_online(struct smb_chip *chip, int *val)
{ {
unsigned int stat; unsigned int stat;
int rc; int rc;
@ -431,13 +431,13 @@ static int smb2_get_prop_usb_online(struct smb2_chip *chip, int *val)
* Qualcomm "automatic power source detection" aka APSD * Qualcomm "automatic power source detection" aka APSD
* tells us what type of charger we're connected to. * tells us what type of charger we're connected to.
*/ */
static int smb2_apsd_get_charger_type(struct smb2_chip *chip, int *val) static int smb_apsd_get_charger_type(struct smb_chip *chip, int *val)
{ {
unsigned int apsd_stat, stat; unsigned int apsd_stat, stat;
int usb_online = 0; int usb_online = 0;
int rc; int rc;
rc = smb2_get_prop_usb_online(chip, &usb_online); rc = smb_get_prop_usb_online(chip, &usb_online);
if (!usb_online) { if (!usb_online) {
*val = POWER_SUPPLY_USB_TYPE_UNKNOWN; *val = POWER_SUPPLY_USB_TYPE_UNKNOWN;
return rc; return rc;
@ -471,13 +471,13 @@ static int smb2_apsd_get_charger_type(struct smb2_chip *chip, int *val)
return 0; return 0;
} }
static int smb2_get_prop_status(struct smb2_chip *chip, int *val) static int smb_get_prop_status(struct smb_chip *chip, int *val)
{ {
unsigned char stat[2]; unsigned char stat[2];
int usb_online = 0; int usb_online = 0;
int rc; int rc;
rc = smb2_get_prop_usb_online(chip, &usb_online); rc = smb_get_prop_usb_online(chip, &usb_online);
if (!usb_online) { if (!usb_online) {
*val = POWER_SUPPLY_STATUS_DISCHARGING; *val = POWER_SUPPLY_STATUS_DISCHARGING;
return rc; return rc;
@ -519,7 +519,7 @@ static int smb2_get_prop_status(struct smb2_chip *chip, int *val)
} }
} }
static inline int smb2_get_current_limit(struct smb2_chip *chip, static inline int smb_get_current_limit(struct smb_chip *chip,
unsigned int *val) unsigned int *val)
{ {
int rc = regmap_read(chip->regmap, chip->base + ICL_STATUS, val); int rc = regmap_read(chip->regmap, chip->base + ICL_STATUS, val);
@ -529,7 +529,7 @@ static inline int smb2_get_current_limit(struct smb2_chip *chip,
return rc; return rc;
} }
static int smb2_set_current_limit(struct smb2_chip *chip, unsigned int val) static int smb_set_current_limit(struct smb_chip *chip, unsigned int val)
{ {
unsigned char val_raw; unsigned char val_raw;
@ -544,22 +544,22 @@ static int smb2_set_current_limit(struct smb2_chip *chip, unsigned int val)
val_raw); val_raw);
} }
static void smb2_status_change_work(struct work_struct *work) static void smb_status_change_work(struct work_struct *work)
{ {
unsigned int charger_type, current_ua; unsigned int charger_type, current_ua;
int usb_online = 0; int usb_online = 0;
int count, rc; int count, rc;
struct smb2_chip *chip; struct smb_chip *chip;
chip = container_of(work, struct smb2_chip, status_change_work.work); chip = container_of(work, struct smb_chip, status_change_work.work);
smb2_get_prop_usb_online(chip, &usb_online); smb_get_prop_usb_online(chip, &usb_online);
if (!usb_online) if (!usb_online)
return; return;
for (count = 0; count < 3; count++) { for (count = 0; count < 3; count++) {
dev_dbg(chip->dev, "get charger type retry %d\n", count); dev_dbg(chip->dev, "get charger type retry %d\n", count);
rc = smb2_apsd_get_charger_type(chip, &charger_type); rc = smb_apsd_get_charger_type(chip, &charger_type);
if (rc != -EAGAIN) if (rc != -EAGAIN)
break; break;
msleep(100); msleep(100);
@ -592,11 +592,11 @@ static void smb2_status_change_work(struct work_struct *work)
break; break;
} }
smb2_set_current_limit(chip, current_ua); smb_set_current_limit(chip, current_ua);
power_supply_changed(chip->chg_psy); power_supply_changed(chip->chg_psy);
} }
static int smb2_get_iio_chan(struct smb2_chip *chip, struct iio_channel *chan, static int smb_get_iio_chan(struct smb_chip *chip, struct iio_channel *chan,
int *val) int *val)
{ {
int rc; int rc;
@ -617,7 +617,7 @@ static int smb2_get_iio_chan(struct smb2_chip *chip, struct iio_channel *chan,
return iio_read_channel_processed(chan, val); return iio_read_channel_processed(chan, val);
} }
static int smb2_get_prop_health(struct smb2_chip *chip, int *val) static int smb_get_prop_health(struct smb_chip *chip, int *val)
{ {
int rc; int rc;
unsigned int stat; unsigned int stat;
@ -651,11 +651,11 @@ static int smb2_get_prop_health(struct smb2_chip *chip, int *val)
} }
} }
static int smb2_get_property(struct power_supply *psy, static int smb_get_property(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
union power_supply_propval *val) union power_supply_propval *val)
{ {
struct smb2_chip *chip = power_supply_get_drvdata(psy); struct smb_chip *chip = power_supply_get_drvdata(psy);
switch (psp) { switch (psp) {
case POWER_SUPPLY_PROP_MANUFACTURER: case POWER_SUPPLY_PROP_MANUFACTURER:
@ -665,43 +665,43 @@ static int smb2_get_property(struct power_supply *psy,
val->strval = chip->name; val->strval = chip->name;
return 0; return 0;
case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_MAX:
return smb2_get_current_limit(chip, &val->intval); return smb_get_current_limit(chip, &val->intval);
case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_CURRENT_NOW:
return smb2_get_iio_chan(chip, chip->usb_in_i_chan, return smb_get_iio_chan(chip, chip->usb_in_i_chan,
&val->intval); &val->intval);
case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_VOLTAGE_NOW:
return smb2_get_iio_chan(chip, chip->usb_in_v_chan, return smb_get_iio_chan(chip, chip->usb_in_v_chan,
&val->intval); &val->intval);
case POWER_SUPPLY_PROP_ONLINE: case POWER_SUPPLY_PROP_ONLINE:
return smb2_get_prop_usb_online(chip, &val->intval); return smb_get_prop_usb_online(chip, &val->intval);
case POWER_SUPPLY_PROP_STATUS: case POWER_SUPPLY_PROP_STATUS:
return smb2_get_prop_status(chip, &val->intval); return smb_get_prop_status(chip, &val->intval);
case POWER_SUPPLY_PROP_HEALTH: case POWER_SUPPLY_PROP_HEALTH:
return smb2_get_prop_health(chip, &val->intval); return smb_get_prop_health(chip, &val->intval);
case POWER_SUPPLY_PROP_USB_TYPE: case POWER_SUPPLY_PROP_USB_TYPE:
return smb2_apsd_get_charger_type(chip, &val->intval); return smb_apsd_get_charger_type(chip, &val->intval);
default: default:
dev_err(chip->dev, "invalid property: %d\n", psp); dev_err(chip->dev, "invalid property: %d\n", psp);
return -EINVAL; return -EINVAL;
} }
} }
static int smb2_set_property(struct power_supply *psy, static int smb_set_property(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
const union power_supply_propval *val) const union power_supply_propval *val)
{ {
struct smb2_chip *chip = power_supply_get_drvdata(psy); struct smb_chip *chip = power_supply_get_drvdata(psy);
switch (psp) { switch (psp) {
case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_MAX:
return smb2_set_current_limit(chip, val->intval); return smb_set_current_limit(chip, val->intval);
default: default:
dev_err(chip->dev, "No setter for property: %d\n", psp); dev_err(chip->dev, "No setter for property: %d\n", psp);
return -EINVAL; return -EINVAL;
} }
} }
static int smb2_property_is_writable(struct power_supply *psy, static int smb_property_is_writable(struct power_supply *psy,
enum power_supply_property psp) enum power_supply_property psp)
{ {
switch (psp) { switch (psp) {
@ -712,9 +712,9 @@ static int smb2_property_is_writable(struct power_supply *psy,
} }
} }
static irqreturn_t smb2_handle_batt_overvoltage(int irq, void *data) static irqreturn_t smb_handle_batt_overvoltage(int irq, void *data)
{ {
struct smb2_chip *chip = data; struct smb_chip *chip = data;
unsigned int status; unsigned int status;
regmap_read(chip->regmap, chip->base + BATTERY_CHARGER_STATUS_2, regmap_read(chip->regmap, chip->base + BATTERY_CHARGER_STATUS_2,
@ -729,9 +729,9 @@ static irqreturn_t smb2_handle_batt_overvoltage(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t smb2_handle_usb_plugin(int irq, void *data) static irqreturn_t smb_handle_usb_plugin(int irq, void *data)
{ {
struct smb2_chip *chip = data; struct smb_chip *chip = data;
power_supply_changed(chip->chg_psy); power_supply_changed(chip->chg_psy);
@ -741,18 +741,18 @@ static irqreturn_t smb2_handle_usb_plugin(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t smb2_handle_usb_icl_change(int irq, void *data) static irqreturn_t smb_handle_usb_icl_change(int irq, void *data)
{ {
struct smb2_chip *chip = data; struct smb_chip *chip = data;
power_supply_changed(chip->chg_psy); power_supply_changed(chip->chg_psy);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t smb2_handle_wdog_bark(int irq, void *data) static irqreturn_t smb_handle_wdog_bark(int irq, void *data)
{ {
struct smb2_chip *chip = data; struct smb_chip *chip = data;
int rc; int rc;
power_supply_changed(chip->chg_psy); power_supply_changed(chip->chg_psy);
@ -765,22 +765,22 @@ static irqreturn_t smb2_handle_wdog_bark(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static const struct power_supply_desc smb2_psy_desc = { static const struct power_supply_desc smb_psy_desc = {
.name = "pmi8998_charger", .name = "pmi8998_charger",
.type = POWER_SUPPLY_TYPE_USB, .type = POWER_SUPPLY_TYPE_USB,
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
BIT(POWER_SUPPLY_USB_TYPE_CDP) | BIT(POWER_SUPPLY_USB_TYPE_CDP) |
BIT(POWER_SUPPLY_USB_TYPE_DCP) | BIT(POWER_SUPPLY_USB_TYPE_DCP) |
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
.properties = smb2_properties, .properties = smb_properties,
.num_properties = ARRAY_SIZE(smb2_properties), .num_properties = ARRAY_SIZE(smb_properties),
.get_property = smb2_get_property, .get_property = smb_get_property,
.set_property = smb2_set_property, .set_property = smb_set_property,
.property_is_writeable = smb2_property_is_writable, .property_is_writeable = smb_property_is_writable,
}; };
/* Init sequence derived from vendor downstream driver */ /* Init sequence derived from vendor downstream driver */
static const struct smb2_register smb2_init_seq[] = { static const struct smb_init_register smb_init_seq[] = {
{ .addr = AICL_RERUN_TIME_CFG, .mask = AICL_RERUN_TIME_MASK, .val = 0 }, { .addr = AICL_RERUN_TIME_CFG, .mask = AICL_RERUN_TIME_MASK, .val = 0 },
/* /*
* By default configure us as an upstream facing port * By default configure us as an upstream facing port
@ -882,17 +882,17 @@ static const struct smb2_register smb2_init_seq[] = {
.val = 1000000 / CURRENT_SCALE_FACTOR }, .val = 1000000 / CURRENT_SCALE_FACTOR },
}; };
static int smb2_init_hw(struct smb2_chip *chip) static int smb_init_hw(struct smb_chip *chip)
{ {
int rc, i; int rc, i;
for (i = 0; i < ARRAY_SIZE(smb2_init_seq); i++) { for (i = 0; i < ARRAY_SIZE(smb_init_seq); i++) {
dev_dbg(chip->dev, "%d: Writing 0x%02x to 0x%02x\n", i, dev_dbg(chip->dev, "%d: Writing 0x%02x to 0x%02x\n", i,
smb2_init_seq[i].val, smb2_init_seq[i].addr); smb_init_seq[i].val, smb_init_seq[i].addr);
rc = regmap_update_bits(chip->regmap, rc = regmap_update_bits(chip->regmap,
chip->base + smb2_init_seq[i].addr, chip->base + smb_init_seq[i].addr,
smb2_init_seq[i].mask, smb_init_seq[i].mask,
smb2_init_seq[i].val); smb_init_seq[i].val);
if (rc < 0) if (rc < 0)
return dev_err_probe(chip->dev, rc, return dev_err_probe(chip->dev, rc,
"%s: init command %d failed\n", "%s: init command %d failed\n",
@ -902,7 +902,7 @@ static int smb2_init_hw(struct smb2_chip *chip)
return 0; return 0;
} }
static int smb2_init_irq(struct smb2_chip *chip, int *irq, const char *name, static int smb_init_irq(struct smb_chip *chip, int *irq, const char *name,
irqreturn_t (*handler)(int irq, void *data)) irqreturn_t (*handler)(int irq, void *data))
{ {
int irqnum; int irqnum;
@ -924,11 +924,11 @@ static int smb2_init_irq(struct smb2_chip *chip, int *irq, const char *name,
return 0; return 0;
} }
static int smb2_probe(struct platform_device *pdev) static int smb_probe(struct platform_device *pdev)
{ {
struct power_supply_config supply_config = {}; struct power_supply_config supply_config = {};
struct power_supply_desc *desc; struct power_supply_desc *desc;
struct smb2_chip *chip; struct smb_chip *chip;
int rc, irq; int rc, irq;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
@ -959,17 +959,17 @@ static int smb2_probe(struct platform_device *pdev)
"Couldn't get usbin_i IIO channel\n"); "Couldn't get usbin_i IIO channel\n");
} }
rc = smb2_init_hw(chip); rc = smb_init_hw(chip);
if (rc < 0) if (rc < 0)
return rc; return rc;
supply_config.drv_data = chip; supply_config.drv_data = chip;
supply_config.fwnode = dev_fwnode(&pdev->dev); supply_config.fwnode = dev_fwnode(&pdev->dev);
desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL); desc = devm_kzalloc(chip->dev, sizeof(smb_psy_desc), GFP_KERNEL);
if (!desc) if (!desc)
return -ENOMEM; return -ENOMEM;
memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc)); memcpy(desc, &smb_psy_desc, sizeof(smb_psy_desc));
desc->name = desc->name =
devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger", devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger",
(const char *)device_get_match_data(chip->dev)); (const char *)device_get_match_data(chip->dev));
@ -988,7 +988,7 @@ static int smb2_probe(struct platform_device *pdev)
"Failed to get battery info\n"); "Failed to get battery info\n");
rc = devm_delayed_work_autocancel(chip->dev, &chip->status_change_work, rc = devm_delayed_work_autocancel(chip->dev, &chip->status_change_work,
smb2_status_change_work); smb_status_change_work);
if (rc) if (rc)
return dev_err_probe(chip->dev, rc, return dev_err_probe(chip->dev, rc,
"Failed to init status change work\n"); "Failed to init status change work\n");
@ -999,24 +999,26 @@ static int smb2_probe(struct platform_device *pdev)
if (rc < 0) if (rc < 0)
return dev_err_probe(chip->dev, rc, "Couldn't set vbat max\n"); return dev_err_probe(chip->dev, rc, "Couldn't set vbat max\n");
rc = smb2_init_irq(chip, &irq, "bat-ov", smb2_handle_batt_overvoltage); rc = smb_init_irq(chip, &irq, "bat-ov", smb_handle_batt_overvoltage);
if (rc < 0) if (rc < 0)
return rc; return rc;
rc = smb2_init_irq(chip, &chip->cable_irq, "usb-plugin", rc = smb_init_irq(chip, &chip->cable_irq, "usb-plugin",
smb2_handle_usb_plugin); smb_handle_usb_plugin);
if (rc < 0) if (rc < 0)
return rc; return rc;
rc = smb2_init_irq(chip, &irq, "usbin-icl-change", rc = smb_init_irq(chip, &irq, "usbin-icl-change",
smb2_handle_usb_icl_change); smb_handle_usb_icl_change);
if (rc < 0) if (rc < 0)
return rc; return rc;
rc = smb2_init_irq(chip, &irq, "wdog-bark", smb2_handle_wdog_bark); rc = smb_init_irq(chip, &irq, "wdog-bark", smb_handle_wdog_bark);
if (rc < 0) if (rc < 0)
return rc; return rc;
rc = dev_pm_set_wake_irq(chip->dev, chip->cable_irq); devm_device_init_wakeup(chip->dev);
rc = devm_pm_set_wake_irq(chip->dev, chip->cable_irq);
if (rc < 0) if (rc < 0)
return dev_err_probe(chip->dev, rc, "Couldn't set wake irq\n"); return dev_err_probe(chip->dev, rc, "Couldn't set wake irq\n");
@ -1028,22 +1030,22 @@ static int smb2_probe(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id smb2_match_id_table[] = { static const struct of_device_id smb_match_id_table[] = {
{ .compatible = "qcom,pmi8998-charger", .data = "pmi8998" }, { .compatible = "qcom,pmi8998-charger", .data = "pmi8998" },
{ .compatible = "qcom,pm660-charger", .data = "pm660" }, { .compatible = "qcom,pm660-charger", .data = "pm660" },
{ /* sentinal */ } { /* sentinal */ }
}; };
MODULE_DEVICE_TABLE(of, smb2_match_id_table); MODULE_DEVICE_TABLE(of, smb_match_id_table);
static struct platform_driver qcom_spmi_smb2 = { static struct platform_driver qcom_spmi_smb = {
.probe = smb2_probe, .probe = smb_probe,
.driver = { .driver = {
.name = "qcom-pmi8998/pm660-charger", .name = "qcom-smbx-charger",
.of_match_table = smb2_match_id_table, .of_match_table = smb_match_id_table,
}, },
}; };
module_platform_driver(qcom_spmi_smb2); module_platform_driver(qcom_spmi_smb);
MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>"); MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>");
MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver"); MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver");

View File

@ -512,7 +512,6 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
ret |= twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a, ret |= twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
TWL4030_BCIMDKEY); TWL4030_BCIMDKEY);
if (bci->usb_enabled) { if (bci->usb_enabled) {
pm_runtime_mark_last_busy(bci->transceiver->dev);
pm_runtime_put_autosuspend(bci->transceiver->dev); pm_runtime_put_autosuspend(bci->transceiver->dev);
bci->usb_enabled = 0; bci->usb_enabled = 0;
} }

View File

@ -66,10 +66,11 @@
#define UG3105_LOW_BAT_UV 3700000 #define UG3105_LOW_BAT_UV 3700000
#define UG3105_FULL_BAT_HYST_UV 38000 #define UG3105_FULL_BAT_HYST_UV 38000
#define AMBIENT_TEMP_CELCIUS 25
struct ug3105_chip { struct ug3105_chip {
struct i2c_client *client; struct i2c_client *client;
struct power_supply *psy; struct power_supply *psy;
struct power_supply_battery_info *info;
struct delayed_work work; struct delayed_work work;
struct mutex lock; struct mutex lock;
int ocv[UG3105_MOV_AVG_WINDOW]; /* micro-volt */ int ocv[UG3105_MOV_AVG_WINDOW]; /* micro-volt */
@ -103,7 +104,8 @@ static int ug3105_read_word(struct i2c_client *client, u8 reg)
static int ug3105_get_status(struct ug3105_chip *chip) static int ug3105_get_status(struct ug3105_chip *chip)
{ {
int full = chip->info->constant_charge_voltage_max_uv - UG3105_FULL_BAT_HYST_UV; int full = chip->psy->battery_info->constant_charge_voltage_max_uv -
UG3105_FULL_BAT_HYST_UV;
if (chip->curr > UG3105_CURR_HYST_UA) if (chip->curr > UG3105_CURR_HYST_UA)
return POWER_SUPPLY_STATUS_CHARGING; return POWER_SUPPLY_STATUS_CHARGING;
@ -117,62 +119,6 @@ static int ug3105_get_status(struct ug3105_chip *chip)
return POWER_SUPPLY_STATUS_NOT_CHARGING; return POWER_SUPPLY_STATUS_NOT_CHARGING;
} }
static int ug3105_get_capacity(struct ug3105_chip *chip)
{
/*
* OCV voltages in uV for 0-110% in 5% increments, the 100-110% is
* for LiPo HV (High-Voltage) bateries which can go up to 4.35V
* instead of the usual 4.2V.
*/
static const int ocv_capacity_tbl[23] = {
3350000,
3610000,
3690000,
3710000,
3730000,
3750000,
3770000,
3786667,
3803333,
3820000,
3836667,
3853333,
3870000,
3907500,
3945000,
3982500,
4020000,
4075000,
4110000,
4150000,
4200000,
4250000,
4300000,
};
int i, ocv_diff, ocv_step;
if (chip->ocv_avg < ocv_capacity_tbl[0])
return 0;
if (chip->status == POWER_SUPPLY_STATUS_FULL)
return 100;
for (i = 1; i < ARRAY_SIZE(ocv_capacity_tbl); i++) {
if (chip->ocv_avg > ocv_capacity_tbl[i])
continue;
ocv_diff = ocv_capacity_tbl[i] - chip->ocv_avg;
ocv_step = ocv_capacity_tbl[i] - ocv_capacity_tbl[i - 1];
/* scale 0-110% down to 0-100% for LiPo HV */
if (chip->info->constant_charge_voltage_max_uv >= 4300000)
return (i * 500 - ocv_diff * 500 / ocv_step) / 110;
else
return i * 5 - ocv_diff * 5 / ocv_step;
}
return 100;
}
static void ug3105_work(struct work_struct *work) static void ug3105_work(struct work_struct *work)
{ {
struct ug3105_chip *chip = container_of(work, struct ug3105_chip, struct ug3105_chip *chip = container_of(work, struct ug3105_chip,
@ -231,7 +177,12 @@ static void ug3105_work(struct work_struct *work)
chip->supplied = power_supply_am_i_supplied(psy); chip->supplied = power_supply_am_i_supplied(psy);
chip->status = ug3105_get_status(chip); chip->status = ug3105_get_status(chip);
chip->capacity = ug3105_get_capacity(chip); if (chip->status == POWER_SUPPLY_STATUS_FULL)
chip->capacity = 100;
else
chip->capacity = power_supply_batinfo_ocv2cap(chip->psy->battery_info,
chip->ocv_avg,
AMBIENT_TEMP_CELCIUS);
/* /*
* Skip internal resistance calc on charger [un]plug and * Skip internal resistance calc on charger [un]plug and
@ -401,12 +352,10 @@ static int ug3105_probe(struct i2c_client *client)
if (IS_ERR(psy)) if (IS_ERR(psy))
return PTR_ERR(psy); return PTR_ERR(psy);
ret = power_supply_get_battery_info(psy, &chip->info); if (!psy->battery_info ||
if (ret) psy->battery_info->factory_internal_resistance_uohm == -EINVAL ||
return ret; psy->battery_info->constant_charge_voltage_max_uv == -EINVAL ||
!psy->battery_info->ocv_table[0]) {
if (chip->info->factory_internal_resistance_uohm == -EINVAL ||
chip->info->constant_charge_voltage_max_uv == -EINVAL) {
dev_err(dev, "error required properties are missing\n"); dev_err(dev, "error required properties are missing\n");
return -ENODEV; return -ENODEV;
} }
@ -422,7 +371,7 @@ static int ug3105_probe(struct i2c_client *client)
chip->ua_per_unit = 8100000 / curr_sense_res_uohm; chip->ua_per_unit = 8100000 / curr_sense_res_uohm;
/* Use provided internal resistance as start point (in milli-ohm) */ /* Use provided internal resistance as start point (in milli-ohm) */
chip->intern_res_avg = chip->info->factory_internal_resistance_uohm / 1000; chip->intern_res_avg = psy->battery_info->factory_internal_resistance_uohm / 1000;
/* Also add it to the internal resistance moving average window */ /* Also add it to the internal resistance moving average window */
chip->intern_res[0] = chip->intern_res_avg; chip->intern_res[0] = chip->intern_res_avg;
chip->intern_res_avg_index = 1; chip->intern_res_avg_index = 1;

View File

@ -643,7 +643,7 @@ static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
struct power_supply *charger; struct power_supply *charger;
struct power_supply_config cfg = { struct power_supply_config cfg = {
.drv_data = regmap, .drv_data = regmap,
.of_node = dev->of_node, .fwnode = dev_fwnode(dev),
}; };
charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg); charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);

View File

@ -232,7 +232,6 @@ struct power_supply;
/* Run-time specific power supply configuration */ /* Run-time specific power supply configuration */
struct power_supply_config { struct power_supply_config {
struct device_node *of_node;
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
/* Driver private data */ /* Driver private data */
@ -808,19 +807,10 @@ static inline void power_supply_put(struct power_supply *psy) {}
static inline struct power_supply *power_supply_get_by_name(const char *name) static inline struct power_supply *power_supply_get_by_name(const char *name)
{ return NULL; } { return NULL; }
#endif #endif
#ifdef CONFIG_OF extern struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode,
extern struct power_supply *power_supply_get_by_phandle(struct device_node *np,
const char *property); const char *property);
extern struct power_supply *devm_power_supply_get_by_phandle( extern struct power_supply *devm_power_supply_get_by_reference(
struct device *dev, const char *property); struct device *dev, const char *property);
#else /* !CONFIG_OF */
static inline struct power_supply *
power_supply_get_by_phandle(struct device_node *np, const char *property)
{ return NULL; }
static inline struct power_supply *
devm_power_supply_get_by_phandle(struct device *dev, const char *property)
{ return NULL; }
#endif /* CONFIG_OF */
extern const enum power_supply_property power_supply_battery_info_properties[]; extern const enum power_supply_property power_supply_battery_info_properties[];
extern const size_t power_supply_battery_info_properties_size; extern const size_t power_supply_battery_info_properties_size;