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.
monitored-battery:
$ref: /schemas/types.yaml#/definitions/phandle
description: |
phandle to a "simple-battery" compatible node.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -20815,6 +20815,13 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
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
M: Maximilian Luz <luzmaximilian@gmail.com>
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")) {
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");
if (IS_ERR(data->vbus_power_supply)) {
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
tristate "Toradex Embedded Controller power-off and reset driver"
depends on ARCH_MXC || COMPILE_TEST
depends on I2C
select REGMAP_I2C
help

View file

@ -129,7 +129,7 @@ static void at91_wakeup_status(struct platform_device *pdev)
else if (SHDW_RTTWK(reg, &rcfg->shdwc))
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)

View file

@ -19,7 +19,7 @@
#define NO_REASON_SHIFT 0
struct pm8916_pon {
struct qcom_pon {
struct device *dev;
struct regmap *regmap;
u32 baseaddr;
@ -27,11 +27,11 @@ struct pm8916_pon {
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)
{
struct pm8916_pon *pon = container_of
(reboot, struct pm8916_pon, reboot_mode);
struct qcom_pon *pon = container_of
(reboot, struct qcom_pon, reboot_mode);
int ret;
ret = regmap_update_bits(pon->regmap,
@ -44,9 +44,9 @@ static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot,
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;
int error;
@ -72,7 +72,7 @@ static int pm8916_pon_probe(struct platform_device *pdev)
if (reason_shift != NO_REASON_SHIFT) {
pon->reboot_mode.dev = &pdev->dev;
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);
if (error) {
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);
}
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,pm8941-pon", .data = (void *)NO_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 },
{ }
};
MODULE_DEVICE_TABLE(of, pm8916_pon_id_table);
MODULE_DEVICE_TABLE(of, qcom_pon_id_table);
static struct platform_driver pm8916_pon_driver = {
.probe = pm8916_pon_probe,
static struct platform_driver qcom_pon_driver = {
.probe = qcom_pon_probe,
.driver = {
.name = "pm8916-pon",
.of_match_table = pm8916_pon_id_table,
.name = "qcom-pon",
.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");

View file

@ -120,5 +120,5 @@ obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o
obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.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

View file

@ -1674,7 +1674,7 @@ static int bq2415x_probe(struct i2c_client *client)
/* Query for initial reported_mode and set it */
if (bq->nb.notifier_call) {
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");
if (IS_ERR(notify_psy))
notify_psy = NULL;

View file

@ -504,7 +504,6 @@ static ssize_t bq24190_sysfs_show(struct device *dev,
else
count = sysfs_emit(buf, "%hhx\n", v);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return count;
@ -535,7 +534,6 @@ static ssize_t bq24190_sysfs_store(struct device *dev,
if (ret)
count = ret;
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return count;
@ -562,7 +560,6 @@ static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
else
ret = bq24190_charger_set_charge_type(bdi, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return ret;
@ -605,7 +602,6 @@ static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
}
out:
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
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_SHIFT, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
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_SHIFT, &val);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
if (ret)
@ -1376,7 +1370,6 @@ static int bq24190_charger_get_property(struct power_supply *psy,
ret = -ENODATA;
}
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return ret;
@ -1419,7 +1412,6 @@ static int bq24190_charger_set_property(struct power_supply *psy,
ret = -EINVAL;
}
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return ret;
@ -1682,7 +1674,6 @@ static int bq24190_battery_get_property(struct power_supply *psy,
ret = -ENODATA;
}
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return ret;
@ -1713,7 +1704,6 @@ static int bq24190_battery_set_property(struct power_supply *psy,
ret = -EINVAL;
}
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
return ret;
@ -1861,7 +1851,6 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
return IRQ_NONE;
}
bq24190_check_status(bdi);
pm_runtime_mark_last_busy(bdi->dev);
pm_runtime_put_autosuspend(bdi->dev);
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;
if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max)
bdi->vreg = bdi->vreg_max = v;
power_supply_put_battery_info(bdi->charger, info);
}
return 0;
@ -2186,7 +2177,6 @@ static int bq24190_probe(struct i2c_client *client)
enable_irq_wake(client->irq);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return 0;
@ -2273,7 +2263,6 @@ static __maybe_unused int bq24190_pm_suspend(struct device *dev)
bq24190_register_reset(bdi);
if (error >= 0) {
pm_runtime_mark_last_busy(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);
if (error >= 0) {
pm_runtime_mark_last_busy(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_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0xa2},
@ -398,7 +398,7 @@ static struct reg_default bq2560x_reg_defs[] = {
{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_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},
@ -411,7 +411,7 @@ static struct reg_default bq25611d_reg_defs[] = {
{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_CHARGER_CONTROL_0, 0x1a},
{BQ256XX_CHARGE_CURRENT_LIMIT, 0x91},

View file

@ -104,7 +104,7 @@ struct bq25980_device {
int watchdog_timer;
};
static struct reg_default bq25980_reg_defs[] = {
static const struct reg_default bq25980_reg_defs[] = {
{BQ25980_BATOVP, 0x5A},
{BQ25980_BATOVP_ALM, 0x46},
{BQ25980_BATOCP, 0x51},
@ -159,7 +159,7 @@ static struct reg_default bq25980_reg_defs[] = {
{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_ALM, 0x46},
{BQ25980_BATOCP, 0x51},
@ -214,7 +214,7 @@ static struct reg_default bq25975_reg_defs[] = {
{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_ALM, 0x46},
{BQ25980_BATOCP, 0x51},

View file

@ -689,9 +689,8 @@ static void cpcap_usb_detect(struct work_struct *work)
struct power_supply *battery;
battery = power_supply_get_by_name("battery");
if (IS_ERR_OR_NULL(battery)) {
dev_err(ddata->dev, "battery power_supply not available %li\n",
PTR_ERR(battery));
if (!battery) {
dev_err(ddata->dev, "battery power_supply not available\n");
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(
struct platform_device *pdev)
{
return NULL;
return ERR_PTR(-ENODATA);
}
#endif /* CONFIG_OF */
@ -572,7 +572,7 @@ static int max14577_charger_probe(struct platform_device *pdev)
chg->max14577 = max14577;
chg->pdata = max14577_charger_dt_init(pdev);
if (IS_ERR_OR_NULL(chg->pdata))
if (IS_ERR(chg->pdata))
return PTR_ERR(chg->pdata);
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 */
}
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;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
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;
case POWER_SUPPLY_PROP_CHARGE_AVG:
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;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
ret = regmap_read(info->regmap, MAX172XX_TTE, &reg_val);
@ -422,10 +423,12 @@ static int max1720x_battery_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
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;
case POWER_SUPPLY_PROP_MODEL_NAME:
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);
if (reg_val == MAX172XX_DEV_NAME_TYPE_MAX17201)
val->strval = max17201_model;

View file

@ -18,7 +18,6 @@
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/power_supply.h>
#include <linux/property.h>
#include <linux/thermal.h>
@ -196,24 +195,24 @@ static int __power_supply_populate_supplied_from(struct power_supply *epsy,
void *data)
{
struct power_supply *psy = data;
struct device_node *np;
struct fwnode_handle *np;
int i = 0;
do {
np = of_parse_phandle(psy->dev.of_node, "power-supplies", i++);
if (!np)
np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", i++);
if (IS_ERR(np))
break;
if (np == epsy->dev.of_node) {
if (np == epsy->dev.fwnode) {
dev_dbg(&psy->dev, "%s: Found supply : %s\n",
psy->desc->name, epsy->desc->name);
psy->supplied_from[i-1] = (char *)epsy->desc->name;
psy->num_supplies++;
of_node_put(np);
fwnode_handle_put(np);
break;
}
of_node_put(np);
} while (np);
fwnode_handle_put(np);
} while (true);
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,
void *data)
{
struct device_node *np = data;
struct fwnode_handle *fwnode = data;
/* 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 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;
@ -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
* 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).
*
* 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)
{
struct device_node *np;
struct fwnode_handle *np;
int cnt = 0;
/* If there is already a list honor it */
@ -270,24 +269,24 @@ static int power_supply_check_supplies(struct power_supply *psy)
return 0;
/* No device node found, nothing to do */
if (!psy->dev.of_node)
if (!psy->dev.fwnode)
return 0;
do {
int ret;
np = of_parse_phandle(psy->dev.of_node, "power-supplies", cnt++);
if (!np)
np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", cnt++);
if (IS_ERR(np))
break;
ret = power_supply_find_supply_from_node(np);
of_node_put(np);
ret = power_supply_find_supply_from_fwnode(np);
fwnode_handle_put(np);
if (ret) {
dev_dbg(&psy->dev, "Failed to find supply!\n");
return ret;
}
} while (np);
} while (!IS_ERR(np));
/* Missing valid "power-supplies" entries */
if (cnt == 1)
@ -497,15 +496,14 @@ void power_supply_put(struct power_supply *psy)
}
EXPORT_SYMBOL_GPL(power_supply_put);
#ifdef CONFIG_OF
static int power_supply_match_device_node(struct device *dev, const void *data)
static int power_supply_match_device_fwnode(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
* @np: Pointer to device node holding phandle property
* power_supply_get_by_reference() - Search for a power supply and returns its ref
* @fwnode: Pointer to fwnode holding phandle property
* @property: Name of property holding a power supply name
*
* 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
* matching name equals to value under @property, NULL or ERR_PTR otherwise.
*/
struct power_supply *power_supply_get_by_phandle(struct device_node *np,
const char *property)
struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode,
const char *property)
{
struct device_node *power_supply_np;
struct fwnode_handle *power_supply_fwnode;
struct power_supply *psy = NULL;
struct device *dev;
power_supply_np = of_parse_phandle(np, property, 0);
if (!power_supply_np)
return ERR_PTR(-ENODEV);
power_supply_fwnode = fwnode_find_reference(fwnode, property, 0);
if (IS_ERR(power_supply_fwnode))
return ERR_CAST(power_supply_fwnode);
dev = class_find_device(&power_supply_class, NULL, power_supply_np,
power_supply_match_device_node);
dev = class_find_device(&power_supply_class, NULL, power_supply_fwnode,
power_supply_match_device_fwnode);
of_node_put(power_supply_np);
fwnode_handle_put(power_supply_fwnode);
if (dev) {
psy = dev_to_psy(dev);
@ -538,7 +536,7 @@ struct power_supply *power_supply_get_by_phandle(struct device_node *np,
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)
{
@ -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
* power_supply_get_by_phandle()
* devm_power_supply_get_by_reference() - Resource managed version of
* power_supply_get_by_reference()
* @dev: Pointer to device holding phandle property
* @property: Name of property holding a power supply phandle
*
* Return: On success returns a reference to a power supply with
* matching name equals to value under @property, NULL or ERR_PTR otherwise.
*/
struct power_supply *devm_power_supply_get_by_phandle(struct device *dev,
const char *property)
struct power_supply *devm_power_supply_get_by_reference(struct device *dev,
const char *property)
{
struct power_supply **ptr, *psy;
if (!dev->of_node)
if (!dev_fwnode(dev))
return ERR_PTR(-ENODEV);
ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
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)) {
devres_free(ptr);
} else {
@ -577,40 +575,26 @@ struct power_supply *devm_power_supply_get_by_phandle(struct device *dev,
}
return psy;
}
EXPORT_SYMBOL_GPL(devm_power_supply_get_by_phandle);
#endif /* CONFIG_OF */
EXPORT_SYMBOL_GPL(devm_power_supply_get_by_reference);
int power_supply_get_battery_info(struct power_supply *psy,
struct power_supply_battery_info **info_out)
{
struct power_supply_resistance_temp_table *resist_table;
struct power_supply_battery_info *info;
struct device_node *battery_np = NULL;
struct fwnode_reference_args args;
struct fwnode_handle *fwnode = NULL;
struct fwnode_handle *srcnode, *fwnode;
const char *value;
int err, len, index;
const __be32 *list;
int err, len, index, proplen;
u32 *propdata __free(kfree) = NULL;
u32 min_max[2];
if (psy->dev.of_node) {
battery_np = of_parse_phandle(psy->dev.of_node, "monitored-battery", 0);
if (!battery_np)
return -ENODEV;
srcnode = dev_fwnode(&psy->dev);
if (!srcnode && psy->dev.parent)
srcnode = dev_fwnode(psy->dev.parent);
fwnode = fwnode_handle_get(of_fwnode_handle(battery_np));
} else if (psy->dev.parent) {
err = fwnode_property_get_reference_args(
dev_fwnode(psy->dev.parent),
"monitored-battery", NULL, 0, 0, &args);
if (err)
return err;
fwnode = args.fwnode;
}
if (!fwnode)
return -ENOENT;
fwnode = fwnode_find_reference(srcnode, "monitored-battery", 0);
if (IS_ERR(fwnode))
return PTR_ERR(fwnode);
err = fwnode_property_read_string(fwnode, "compatible", &value);
if (err)
@ -740,15 +724,7 @@ int power_supply_get_battery_info(struct power_supply *psy,
info->temp_max = min_max[1];
}
/*
* 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");
len = fwnode_property_count_u32(fwnode, "ocv-capacity-celsius");
if (len < 0 && len != -EINVAL) {
err = len;
goto out_put_node;
@ -757,13 +733,13 @@ int power_supply_get_battery_info(struct power_supply *psy,
err = -EINVAL;
goto out_put_node;
} 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);
}
for (index = 0; index < len; index++) {
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",
index);
@ -772,15 +748,28 @@ int power_supply_get_battery_info(struct power_supply *psy,
err = -ENOMEM;
goto out_put_node;
}
list = of_get_property(battery_np, propname, &size);
if (!list || !size) {
proplen = fwnode_property_count_u32(fwnode, propname);
if (proplen < 0 || proplen % 2 != 0) {
dev_err(&psy->dev, "failed to get %s\n", propname);
power_supply_put_battery_info(psy, info);
err = -EINVAL;
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[index] = table =
@ -792,18 +781,36 @@ int power_supply_get_battery_info(struct power_supply *psy,
}
for (i = 0; i < tab_len; i++) {
table[i].ocv = be32_to_cpu(*list);
list++;
table[i].capacity = be32_to_cpu(*list);
list++;
table[i].ocv = propdata[i*2];
table[i].capacity = propdata[i*2+1];
}
}
list = of_get_property(battery_np, "resistance-temp-table", &len);
if (!list || !len)
proplen = fwnode_property_count_u32(fwnode, "resistance-temp-table");
if (proplen == 0 || proplen == -EINVAL) {
err = 0;
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_size,
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++) {
resist_table[index].temp = be32_to_cpu(*list++);
resist_table[index].resistance = be32_to_cpu(*list++);
resist_table[index].temp = propdata[index*2];
resist_table[index].resistance = propdata[index*2+1];
}
out_ret_pointer:
@ -825,7 +832,6 @@ out_ret_pointer:
out_put_node:
fwnode_handle_put(fwnode);
of_node_put(battery_np);
return err;
}
EXPORT_SYMBOL_GPL(power_supply_get_battery_info);
@ -1587,10 +1593,9 @@ __power_supply_register(struct device *parent,
dev_set_drvdata(dev, psy);
psy->desc = desc;
if (cfg) {
device_set_node(dev, cfg->fwnode);
dev->groups = cfg->attr_grp;
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->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;
break;
case POWER_SUPPLY_PROP_CAPACITY:
if (battmgr->status.percent == (unsigned int)-1)
return -ENODATA;
val->intval = battmgr->status.percent;
break;
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_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
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))
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);
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->usb.online = source == BATTMGR_CHARGING_SOURCE_USB;
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;
case BATTMGR_BAT_DISCHARGE_TIME:
battmgr->status.discharge_time = le32_to_cpu(resp->time);

View file

@ -362,17 +362,17 @@ enum charger_status {
DISABLE_CHARGE,
};
struct smb2_register {
struct smb_init_register {
u16 addr;
u8 mask;
u8 val;
};
/**
* struct smb2_chip - smb2 chip structure
* struct smb_chip - smb chip structure
* @dev: Device reference for power_supply
* @name: The platform device name
* @base: Base address for smb2 registers
* @base: Base address for smb registers
* @regmap: Register map
* @batt_info: Battery data from DT
* @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
* @chg_psy: Charger power supply instance
*/
struct smb2_chip {
struct smb_chip {
struct device *dev;
const char *name;
unsigned int base;
@ -399,7 +399,7 @@ struct smb2_chip {
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_MODEL_NAME,
POWER_SUPPLY_PROP_CURRENT_MAX,
@ -411,7 +411,7 @@ static enum power_supply_property smb2_properties[] = {
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;
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
* 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;
int usb_online = 0;
int rc;
rc = smb2_get_prop_usb_online(chip, &usb_online);
rc = smb_get_prop_usb_online(chip, &usb_online);
if (!usb_online) {
*val = POWER_SUPPLY_USB_TYPE_UNKNOWN;
return rc;
@ -471,13 +471,13 @@ static int smb2_apsd_get_charger_type(struct smb2_chip *chip, int *val)
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];
int usb_online = 0;
int rc;
rc = smb2_get_prop_usb_online(chip, &usb_online);
rc = smb_get_prop_usb_online(chip, &usb_online);
if (!usb_online) {
*val = POWER_SUPPLY_STATUS_DISCHARGING;
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)
{
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;
}
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;
@ -544,22 +544,22 @@ static int smb2_set_current_limit(struct smb2_chip *chip, unsigned int val)
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;
int usb_online = 0;
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)
return;
for (count = 0; count < 3; 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)
break;
msleep(100);
@ -592,11 +592,11 @@ static void smb2_status_change_work(struct work_struct *work)
break;
}
smb2_set_current_limit(chip, current_ua);
smb_set_current_limit(chip, current_ua);
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 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);
}
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;
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,
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) {
case POWER_SUPPLY_PROP_MANUFACTURER:
@ -665,43 +665,43 @@ static int smb2_get_property(struct power_supply *psy,
val->strval = chip->name;
return 0;
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:
return smb2_get_iio_chan(chip, chip->usb_in_i_chan,
return smb_get_iio_chan(chip, chip->usb_in_i_chan,
&val->intval);
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);
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:
return smb2_get_prop_status(chip, &val->intval);
return smb_get_prop_status(chip, &val->intval);
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:
return smb2_apsd_get_charger_type(chip, &val->intval);
return smb_apsd_get_charger_type(chip, &val->intval);
default:
dev_err(chip->dev, "invalid property: %d\n", psp);
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,
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) {
case POWER_SUPPLY_PROP_CURRENT_MAX:
return smb2_set_current_limit(chip, val->intval);
return smb_set_current_limit(chip, val->intval);
default:
dev_err(chip->dev, "No setter for property: %d\n", psp);
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)
{
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;
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;
}
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);
@ -741,18 +741,18 @@ static irqreturn_t smb2_handle_usb_plugin(int irq, void *data)
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);
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;
power_supply_changed(chip->chg_psy);
@ -765,22 +765,22 @@ static irqreturn_t smb2_handle_wdog_bark(int irq, void *data)
return IRQ_HANDLED;
}
static const struct power_supply_desc smb2_psy_desc = {
static const struct power_supply_desc smb_psy_desc = {
.name = "pmi8998_charger",
.type = POWER_SUPPLY_TYPE_USB,
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
.properties = smb2_properties,
.num_properties = ARRAY_SIZE(smb2_properties),
.get_property = smb2_get_property,
.set_property = smb2_set_property,
.property_is_writeable = smb2_property_is_writable,
.properties = smb_properties,
.num_properties = ARRAY_SIZE(smb_properties),
.get_property = smb_get_property,
.set_property = smb_set_property,
.property_is_writeable = smb_property_is_writable,
};
/* 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 },
/*
* 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 },
};
static int smb2_init_hw(struct smb2_chip *chip)
static int smb_init_hw(struct smb_chip *chip)
{
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,
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,
chip->base + smb2_init_seq[i].addr,
smb2_init_seq[i].mask,
smb2_init_seq[i].val);
chip->base + smb_init_seq[i].addr,
smb_init_seq[i].mask,
smb_init_seq[i].val);
if (rc < 0)
return dev_err_probe(chip->dev, rc,
"%s: init command %d failed\n",
@ -902,7 +902,7 @@ static int smb2_init_hw(struct smb2_chip *chip)
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))
{
int irqnum;
@ -924,11 +924,11 @@ static int smb2_init_irq(struct smb2_chip *chip, int *irq, const char *name,
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_desc *desc;
struct smb2_chip *chip;
struct smb_chip *chip;
int rc, irq;
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");
}
rc = smb2_init_hw(chip);
rc = smb_init_hw(chip);
if (rc < 0)
return rc;
supply_config.drv_data = chip;
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)
return -ENOMEM;
memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc));
memcpy(desc, &smb_psy_desc, sizeof(smb_psy_desc));
desc->name =
devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger",
(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");
rc = devm_delayed_work_autocancel(chip->dev, &chip->status_change_work,
smb2_status_change_work);
smb_status_change_work);
if (rc)
return dev_err_probe(chip->dev, rc,
"Failed to init status change work\n");
@ -999,24 +999,26 @@ static int smb2_probe(struct platform_device *pdev)
if (rc < 0)
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)
return rc;
rc = smb2_init_irq(chip, &chip->cable_irq, "usb-plugin",
smb2_handle_usb_plugin);
rc = smb_init_irq(chip, &chip->cable_irq, "usb-plugin",
smb_handle_usb_plugin);
if (rc < 0)
return rc;
rc = smb2_init_irq(chip, &irq, "usbin-icl-change",
smb2_handle_usb_icl_change);
rc = smb_init_irq(chip, &irq, "usbin-icl-change",
smb_handle_usb_icl_change);
if (rc < 0)
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)
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)
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;
}
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,pm660-charger", .data = "pm660" },
{ /* sentinal */ }
};
MODULE_DEVICE_TABLE(of, smb2_match_id_table);
MODULE_DEVICE_TABLE(of, smb_match_id_table);
static struct platform_driver qcom_spmi_smb2 = {
.probe = smb2_probe,
static struct platform_driver qcom_spmi_smb = {
.probe = smb_probe,
.driver = {
.name = "qcom-pmi8998/pm660-charger",
.of_match_table = smb2_match_id_table,
.name = "qcom-smbx-charger",
.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_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,
TWL4030_BCIMDKEY);
if (bci->usb_enabled) {
pm_runtime_mark_last_busy(bci->transceiver->dev);
pm_runtime_put_autosuspend(bci->transceiver->dev);
bci->usb_enabled = 0;
}

View file

@ -66,10 +66,11 @@
#define UG3105_LOW_BAT_UV 3700000
#define UG3105_FULL_BAT_HYST_UV 38000
#define AMBIENT_TEMP_CELCIUS 25
struct ug3105_chip {
struct i2c_client *client;
struct power_supply *psy;
struct power_supply_battery_info *info;
struct delayed_work work;
struct mutex lock;
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)
{
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)
return POWER_SUPPLY_STATUS_CHARGING;
@ -117,62 +119,6 @@ static int ug3105_get_status(struct ug3105_chip *chip)
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)
{
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->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
@ -401,12 +352,10 @@ static int ug3105_probe(struct i2c_client *client)
if (IS_ERR(psy))
return PTR_ERR(psy);
ret = power_supply_get_battery_info(psy, &chip->info);
if (ret)
return ret;
if (chip->info->factory_internal_resistance_uohm == -EINVAL ||
chip->info->constant_charge_voltage_max_uv == -EINVAL) {
if (!psy->battery_info ||
psy->battery_info->factory_internal_resistance_uohm == -EINVAL ||
psy->battery_info->constant_charge_voltage_max_uv == -EINVAL ||
!psy->battery_info->ocv_table[0]) {
dev_err(dev, "error required properties are missing\n");
return -ENODEV;
}
@ -422,7 +371,7 @@ static int ug3105_probe(struct i2c_client *client)
chip->ua_per_unit = 8100000 / curr_sense_res_uohm;
/* 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 */
chip->intern_res[0] = chip->intern_res_avg;
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_config cfg = {
.drv_data = regmap,
.of_node = dev->of_node,
.fwnode = dev_fwnode(dev),
};
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 */
struct power_supply_config {
struct device_node *of_node;
struct fwnode_handle *fwnode;
/* 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)
{ return NULL; }
#endif
#ifdef CONFIG_OF
extern struct power_supply *power_supply_get_by_phandle(struct device_node *np,
const char *property);
extern struct power_supply *devm_power_supply_get_by_phandle(
extern struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode,
const char *property);
extern struct power_supply *devm_power_supply_get_by_reference(
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 size_t power_supply_battery_info_properties_size;