power supply and reset changes for the 7.0 series

* power-supply core
   - sysfs: Constify pointer passed to dev_attr_psp
   - extend DT binding documentation for battery cells to allow
     describing voltage drop behaviour
  * power-supply drivers
   - multiple: Remove unused gpio include header
   - multiple: Fix potential IRQ use-after-free on driver unload
   - bd71828: Add support for ROHM BD72720
   - misc. small fixes
  * reset drivers
   - tdx-ec-poweroff: fix restart
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmmOWCwACgkQ2O7X88g7
 +ppKvRAAkOUnzB2XBNuFUo7lF5menrccueob0oDKFXqrOM4TEtByMQBcxYCU0Li7
 eYIWt1XlcjNJ2rvQfgbVAKWBp5aKAWlizH8f4Q1Z/1GTxKNrCAZdGF0ARsW+0l4Q
 mVOXZa/2FAD/zfV+xrHKZV0x0NWnMjaZPgsRFq1Gvc7Q+Fs11S8UvK266wjIzF5w
 3T9tAJapEcXgd9OpQSTJr898GI09tJLLbJLFNGeHY5+l+nzmCvL8gZWGDPxdDPEj
 c4EhTMfhQr4uJsFxwdPGdaLxWaYlGWMR+Ji/AA+56QuK1F3DekpTZWpPIh2loPgo
 A8cVNaOrusCA/8ZmaTTsSvTzgkj/sttXwV2CvSa0TyY7EaET3TZAwZVgvYEunmj6
 TJHIizRc/jPf+yoHMF9d9iEfgtaxUmbtzJ3KWF/Tt89vxZ0CxCvxeUYTELRiJkJz
 iXBmDlhfmoMBJlh76ULZr36tEytDc2UG6cLr812qjtMhkza9QZkWn8HF7lny9rZy
 df/uUzcfA4lLVu/XPEUo7KDYyx2Pd2T61nC0lsCgmExe46bjP9HLdLVUKHX8GCVA
 5/sqeLViUMqsKk32L3+zOeMGPPHd/qUlq0ItFDuqsaHEHxwFruFEU0Q2a3wAXvcI
 J2tQ4lhnxM5N5DNTL2QeAl2DxDzVUehxAxJQiXNJu9lDjh08wxw=
 =HkTZ
 -----END PGP SIGNATURE-----

Merge tag 'for-v7.0' 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:
   - sysfs: constify pointer passed to dev_attr_psp
   - extend DT binding documentation for battery cells to allow
     describing voltage drop behaviour

  power-supply drivers:
   - multiple: Remove unused gpio include header
   - multiple: Fix potential IRQ use-after-free on driver unload
   - bd71828: Add support for ROHM BD72720
   - misc small fixes

  reset drivers:
   - tdx-ec-poweroff: fix restart"

* tag 'for-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (30 commits)
  power: supply: bd71828: Use dev_err_probe()
  dt-bindings: power: supply: google,goldfish-battery: Convert to DT schema
  power: supply: qcom_battmgr: Recognize "LiP" as lithium-polymer
  power: supply: wm97xx: Use devm_power_supply_register()
  power: supply: wm97xx: Use devm_kcalloc()
  power: supply: pm8916_lbc: Fix use-after-free for extcon in IRQ handler
  power: reset: tdx-ec-poweroff: fix restart
  docs: power: update documentation about removed function
  power: supply: wm97xx: Fix NULL pointer dereference in power_supply_changed()
  MAINTAINERS: adjust file entry in ROHM BD71828 CHARGER
  power: supply: ab8500_chargalg: improve kernel-doc
  power: supply: sysfs: Constify pointer passed to dev_attr_psp()
  power: supply: bq27xxx: fix wrong errno when bus ops are unsupported
  power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write
  power: supply: sbs-battery: Fix use-after-free in power_supply_changed()
  power: supply: rt9455: Fix use-after-free in power_supply_changed()
  power: supply: pm8916_lbc: Fix use-after-free in power_supply_changed()
  power: supply: pm8916_bms_vm: Fix use-after-free in power_supply_changed()
  power: supply: pf1550: Fix use-after-free in power_supply_changed()
  power: supply: goldfish: Fix use-after-free in power_supply_changed()
  ...
This commit is contained in:
Linus Torvalds 2026-02-12 18:24:37 -08:00
commit 7563f7e0e9
26 changed files with 221 additions and 190 deletions

View file

@ -1,17 +0,0 @@
Android Goldfish Battery
Android goldfish battery device generated by android emulator.
Required properties:
- compatible : should contain "google,goldfish-battery" to match emulator
- reg : <registers mapping>
- interrupts : <interrupt mapping>
Example:
goldfish_battery@9020000 {
compatible = "google,goldfish-battery";
reg = <0x9020000 0x1000>;
interrupts = <0x3>;
};

View file

@ -0,0 +1,41 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/power/supply/google,goldfish-battery.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Android Goldfish Battery
maintainers:
- Kuan-Wei Chiu <visitorckw@gmail.com>
allOf:
- $ref: power-supply.yaml#
description:
Android goldfish battery device generated by Android emulator.
properties:
compatible:
const: google,goldfish-battery
reg:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
examples:
- |
battery@9020000 {
compatible = "google,goldfish-battery";
reg = <0x9020000 0x1000>;
interrupts = <3>;
};

View file

@ -183,17 +183,7 @@ struct charger_desc elements:
the value of measure_battery_temp.
5. Notify Charger-Manager of charger events: cm_notify_event()
==============================================================
If there is an charger event is required to notify
Charger Manager, a charger device driver that triggers the event can call
cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager.
In the function, psy is the charger driver's power_supply pointer, which is
associated with Charger-Manager. The parameter "type"
is the same as irq's type (enum cm_event_types). The event message "msg" is
optional and is effective only if the event type is "UNDESCRIBED" or "OTHERS".
6. Other Considerations
5. Other Considerations
=======================
At the charger/battery-related events such as battery-pulled-out,

View file

@ -22899,7 +22899,7 @@ ROHM BD71828 CHARGER
M: Andreas Kemnade <andreas@kemnade.info>
M: Matti Vaittinen <mazziesaccount@gmail.com>
S: Maintained
F: drivers/power/supply/bd71828-charger.c
F: drivers/power/supply/bd71828-power.c
ROHM BD79703 DAC
M: Matti Vaittinen <mazziesaccount@gmail.com>

View file

@ -10,6 +10,7 @@
#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include <linux/reboot-mode.h>
#include <linux/slab.h>
struct nvmem_reboot_mode {
struct reboot_mode_driver reboot;
@ -19,12 +20,22 @@ struct nvmem_reboot_mode {
static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
unsigned int magic)
{
int ret;
struct nvmem_reboot_mode *nvmem_rbm;
size_t buf_len;
void *buf;
int ret;
nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic));
buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len);
if (IS_ERR(buf))
return PTR_ERR(buf);
kfree(buf);
if (buf_len > sizeof(magic))
return -EINVAL;
ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len);
if (ret < 0)
dev_err(reboot->dev, "update reboot mode bits failed\n");

View file

@ -8,7 +8,10 @@
*/
#include <linux/array_size.h>
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dev_printk.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
@ -31,6 +34,8 @@
#define EC_REG_MAX 0xD0
#define EC_CMD_TIMEOUT_MS 1000
static const struct regmap_range volatile_ranges[] = {
regmap_reg_range(EC_CMD_REG, EC_CMD_REG),
};
@ -75,6 +80,13 @@ static int tdx_ec_power_off(struct sys_off_data *data)
err = tdx_ec_cmd(regmap, EC_CMD_POWEROFF);
if (err) {
dev_err(data->dev, "Failed to send power off command\n");
} else {
mdelay(EC_CMD_TIMEOUT_MS);
WARN_ONCE(1, "Unable to power off system\n");
}
return err ? NOTIFY_BAD : NOTIFY_DONE;
}
@ -85,6 +97,13 @@ static int tdx_ec_restart(struct sys_off_data *data)
err = tdx_ec_cmd(regmap, EC_CMD_RESET);
if (err) {
dev_err(data->dev, "Failed to send restart command\n");
} else {
mdelay(EC_CMD_TIMEOUT_MS);
WARN_ONCE(1, "Unable to restart system\n");
}
return err ? NOTIFY_BAD : NOTIFY_DONE;
}

View file

@ -170,13 +170,13 @@ struct ab8500_chargalg_events {
* @original_iset_ua: the non optimized/maximised charger current
* @current_iset_ua: the charging current used at this moment
* @condition_cnt: number of iterations needed before a new charger current
is set
* is set
* @max_current_ua: maximum charger current
* @wait_cnt: to avoid too fast current step down in case of charger
* voltage collapse, we insert this delay between step
* down
* @level: tells in how many steps the charging current has been
increased
* increased
*/
struct ab8500_charge_curr_maximization {
int original_iset_ua;
@ -199,18 +199,20 @@ enum maxim_ret {
* @charge_status: battery operating status
* @eoc_cnt: counter used to determine end-of_charge
* @maintenance_chg: indicate if maintenance charge is active
* @t_hyst_norm temperature hysteresis when the temperature has been
* @t_hyst_norm: temperature hysteresis when the temperature has been
* over or under normal limits
* @t_hyst_lowhigh temperature hysteresis when the temperature has been
* @t_hyst_lowhigh: temperature hysteresis when the temperature has been
* over or under the high or low limits
* @charge_state: current state of the charging algorithm
* @ccm charging current maximization parameters
* @ccm: charging current maximization parameters
* @chg_info: information about connected charger types
* @batt_data: data of the battery
* @bm: Platform specific battery management information
* @parent: pointer to the struct ab8500
* @chargalg_psy: structure that holds the battery properties exposed by
* the charging algorithm
* @ac_chg: AC charger power supply
* @usb_chg: USB charger power supply
* @events: structure for information about events triggered
* @chargalg_wq: work queue for running the charging algorithm
* @chargalg_periodic_work: work to run the charging algorithm periodically
@ -300,6 +302,7 @@ ab8500_chargalg_maintenance_timer_expired(struct hrtimer *timer)
/**
* ab8500_chargalg_state_to() - Change charge state
* @di: pointer to the ab8500_chargalg structure
* @state: new charge algorithm state
*
* This function gets called when a charge state change should occur
*/
@ -763,7 +766,7 @@ static void init_maxim_chg_curr(struct ab8500_chargalg *di)
/**
* ab8500_chargalg_chg_curr_maxim - increases the charger current to
* compensate for the system load
* @di pointer to the ab8500_chargalg structure
* @di: pointer to the ab8500_chargalg structure
*
* This maximization function is used to raise the charger current to get the
* battery current as close to the optimal value as possible. The battery

View file

@ -3466,26 +3466,6 @@ static int ab8500_charger_probe(struct platform_device *pdev)
return ret;
}
/* Request interrupts */
for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) {
irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name);
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev,
irq, NULL, ab8500_charger_irq[i].isr,
IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
ab8500_charger_irq[i].name, di);
if (ret != 0) {
dev_err(dev, "failed to request %s IRQ %d: %d\n"
, ab8500_charger_irq[i].name, irq, ret);
return ret;
}
dev_dbg(dev, "Requested %s IRQ %d: %d\n",
ab8500_charger_irq[i].name, irq, ret);
}
/* initialize lock */
spin_lock_init(&di->usb_state.usb_lock);
mutex_init(&di->usb_ipt_crnt_lock);
@ -3614,6 +3594,26 @@ static int ab8500_charger_probe(struct platform_device *pdev)
return PTR_ERR(di->usb_chg.psy);
}
/* Request interrupts */
for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) {
irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name);
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev,
irq, NULL, ab8500_charger_irq[i].isr,
IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
ab8500_charger_irq[i].name, di);
if (ret != 0) {
dev_err(dev, "failed to request %s IRQ %d: %d\n"
, ab8500_charger_irq[i].name, irq, ret);
return ret;
}
dev_dbg(dev, "Requested %s IRQ %d: %d\n",
ab8500_charger_irq[i].name, irq, ret);
}
/*
* Check what battery we have, since we always have the USB
* psy, use that as a handle.

View file

@ -597,14 +597,6 @@ static int act8945a_charger_probe(struct platform_device *pdev)
return irq ?: -ENXIO;
}
ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
IRQF_TRIGGER_FALLING, "act8945a_interrupt",
charger);
if (ret) {
dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
return ret;
}
charger->desc.name = "act8945a-charger";
charger->desc.get_property = act8945a_charger_get_property;
charger->desc.properties = act8945a_charger_props;
@ -625,6 +617,14 @@ static int act8945a_charger_probe(struct platform_device *pdev)
return PTR_ERR(charger->psy);
}
ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
IRQF_TRIGGER_FALLING, "act8945a_interrupt",
charger);
if (ret) {
dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
return ret;
}
platform_set_drvdata(pdev, charger);
INIT_WORK(&charger->work, act8945a_work);

View file

@ -1058,10 +1058,8 @@ static int bd71828_power_probe(struct platform_device *pdev)
pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);
else
pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map");
if (!pwr->regmap) {
dev_err(&pdev->dev, "No parent regmap\n");
return -EINVAL;
}
if (!pwr->regmap)
return dev_err_probe(&pdev->dev, -EINVAL, "No parent regmap\n");
pwr->dev = &pdev->dev;
@ -1083,8 +1081,7 @@ static int bd71828_power_probe(struct platform_device *pdev)
dev_dbg(pwr->dev, "Found ROHM BD72720\n");
break;
default:
dev_err(pwr->dev, "Unknown PMIC\n");
return -EINVAL;
return dev_err_probe(pwr->dev, -EINVAL, "Unknown PMIC\n");
}
ret = bd7182x_get_rsens(pwr);

View file

@ -56,7 +56,6 @@
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/kernel.h>

View file

@ -8,7 +8,6 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/types.h>
@ -1741,6 +1740,12 @@ static int bq256xx_probe(struct i2c_client *client)
usb_register_notifier(bq->usb3_phy, &bq->usb_nb);
}
ret = bq256xx_power_supply_init(bq, &psy_cfg, dev);
if (ret) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
if (client->irq) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
bq256xx_irq_handler_thread,
@ -1753,12 +1758,6 @@ static int bq256xx_probe(struct i2c_client *client)
}
}
ret = bq256xx_power_supply_init(bq, &psy_cfg, dev);
if (ret) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
ret = bq256xx_hw_init(bq);
if (ret) {
dev_err(dev, "Cannot initialize the chip.\n");

View file

@ -8,7 +8,6 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/types.h>
@ -1241,6 +1240,12 @@ static int bq25980_probe(struct i2c_client *client)
return ret;
}
ret = bq25980_power_supply_init(bq, dev);
if (ret) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
if (client->irq) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
bq25980_irq_handler_thread,
@ -1251,12 +1256,6 @@ static int bq25980_probe(struct i2c_client *client)
return ret;
}
ret = bq25980_power_supply_init(bq, dev);
if (ret) {
dev_err(dev, "Failed to register power supply\n");
return ret;
}
ret = bq25980_hw_init(bq);
if (ret) {
dev_err(dev, "Cannot initialize the chip.\n");

View file

@ -1172,7 +1172,7 @@ static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index,
return -EINVAL;
if (!di->bus.write)
return -EPERM;
return -EOPNOTSUPP;
ret = di->bus.write(di, di->regs[reg_index], value, single);
if (ret < 0)
@ -1191,7 +1191,7 @@ static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_ind
return -EINVAL;
if (!di->bus.read_bulk)
return -EPERM;
return -EOPNOTSUPP;
ret = di->bus.read_bulk(di, di->regs[reg_index], data, len);
if (ret < 0)
@ -1210,7 +1210,7 @@ static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_in
return -EINVAL;
if (!di->bus.write_bulk)
return -EPERM;
return -EOPNOTSUPP;
ret = di->bus.write_bulk(di, di->regs[reg_index], data, len);
if (ret < 0)

View file

@ -1122,10 +1122,6 @@ static int cpcap_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
error = cpcap_battery_init_interrupts(pdev, ddata);
if (error)
return error;
error = cpcap_battery_init_iio(ddata);
if (error)
return error;
@ -1142,6 +1138,10 @@ static int cpcap_battery_probe(struct platform_device *pdev)
return error;
}
error = cpcap_battery_init_interrupts(pdev, ddata);
if (error)
return error;
atomic_set(&ddata->active, 1);
error = cpcap_battery_calibrate(ddata);

View file

@ -13,7 +13,6 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/power_supply.h>

View file

@ -224,12 +224,6 @@ static int goldfish_battery_probe(struct platform_device *pdev)
if (data->irq < 0)
return -ENODEV;
ret = devm_request_irq(&pdev->dev, data->irq,
goldfish_battery_interrupt,
IRQF_SHARED, pdev->name, data);
if (ret)
return ret;
psy_cfg.drv_data = data;
data->ac = devm_power_supply_register(&pdev->dev,
@ -244,6 +238,12 @@ static int goldfish_battery_probe(struct platform_device *pdev)
if (IS_ERR(data->battery))
return PTR_ERR(data->battery);
ret = devm_request_irq(&pdev->dev, data->irq,
goldfish_battery_interrupt,
IRQF_SHARED, pdev->name, data);
if (ret)
return ret;
GOLDFISH_BATTERY_WRITE(data, BATTERY_INT_ENABLE, BATTERY_INT_MASK);
return 0;
}

View file

@ -584,22 +584,6 @@ static int pf1550_charger_probe(struct platform_device *pdev)
return dev_err_probe(chg->dev, ret,
"failed to add battery sense work\n");
for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
irq = platform_get_irq(pdev, i);
if (irq < 0)
return irq;
chg->virqs[i] = irq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
pf1550_charger_irq_handler,
IRQF_NO_SUSPEND,
"pf1550-charger", chg);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"failed irq request\n");
}
psy_cfg.drv_data = chg;
chg->charger = devm_power_supply_register(&pdev->dev,
@ -616,6 +600,22 @@ static int pf1550_charger_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(chg->battery),
"failed: power supply register\n");
for (i = 0; i < PF1550_CHARGER_IRQ_NR; i++) {
irq = platform_get_irq(pdev, i);
if (irq < 0)
return irq;
chg->virqs[i] = irq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
pf1550_charger_irq_handler,
IRQF_NO_SUSPEND,
"pf1550-charger", chg);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"failed irq request\n");
}
pf1550_dt_parse_dev_info(chg);
return pf1550_reg_init(chg);

View file

@ -167,15 +167,6 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
if (ret < 0)
return -EINVAL;
irq = platform_get_irq_byname(pdev, "fifo");
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
IRQF_ONESHOT, "pm8916_vm_bms", bat);
if (ret)
return ret;
ret = regmap_bulk_read(bat->regmap, bat->reg + PM8916_PERPH_TYPE, &tmp, 2);
if (ret)
goto comm_error;
@ -220,6 +211,15 @@ static int pm8916_bms_vm_battery_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Unable to get battery info\n");
irq = platform_get_irq_byname(pdev, "fifo");
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_bms_vm_fifo_update_done_irq,
IRQF_ONESHOT, "pm8916_vm_bms", bat);
if (ret)
return ret;
platform_set_drvdata(pdev, bat);
return 0;

View file

@ -274,15 +274,6 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev)
return dev_err_probe(dev, -EINVAL,
"Wrong amount of reg values: %d (4 expected)\n", len);
irq = platform_get_irq_byname(pdev, "usb_vbus");
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq,
IRQF_ONESHOT, "pm8916_lbc", chg);
if (ret)
return ret;
ret = device_property_read_u32_array(dev, "reg", chg->reg, len);
if (ret)
return ret;
@ -332,6 +323,10 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Unable to get battery info\n");
irq = platform_get_irq_byname(pdev, "usb_vbus");
if (irq < 0)
return irq;
chg->edev = devm_extcon_dev_allocate(dev, pm8916_lbc_charger_cable);
if (IS_ERR(chg->edev))
return PTR_ERR(chg->edev);
@ -340,6 +335,11 @@ static int pm8916_lbc_charger_probe(struct platform_device *pdev)
if (ret < 0)
return dev_err_probe(dev, ret, "failed to register extcon device\n");
ret = devm_request_threaded_irq(dev, irq, NULL, pm8916_lbc_charger_state_changed_irq,
IRQF_ONESHOT, "pm8916_lbc", chg);
if (ret)
return ret;
ret = regmap_read(chg->regmap, chg->reg[LBC_USB] + PM8916_INT_RT_STS, &tmp);
if (ret)
goto comm_error;

View file

@ -235,12 +235,12 @@ static struct power_supply_attr power_supply_attrs[] __ro_after_init = {
static struct attribute *
__power_supply_attrs[POWER_SUPPLY_ATTR_CNT + 1] __ro_after_init;
static const struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
static const struct power_supply_attr *to_ps_attr(const struct device_attribute *attr)
{
return container_of(attr, struct power_supply_attr, dev_attr);
return container_of_const(attr, struct power_supply_attr, dev_attr);
}
static enum power_supply_property dev_attr_psp(struct device_attribute *attr)
static enum power_supply_property dev_attr_psp(const struct device_attribute *attr)
{
return to_ps_attr(attr) - power_supply_attrs;
}

View file

@ -1240,7 +1240,8 @@ static unsigned int qcom_battmgr_sc8280xp_parse_technology(const char *chemistry
if ((!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN)) ||
(!strncmp(chemistry, "OOI", BATTMGR_CHEMISTRY_LEN)))
return POWER_SUPPLY_TECHNOLOGY_LION;
if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN))
if (!strncmp(chemistry, "LIP", BATTMGR_CHEMISTRY_LEN) ||
!strncmp(chemistry, "LiP", BATTMGR_CHEMISTRY_LEN))
return POWER_SUPPLY_TECHNOLOGY_LIPO;
pr_err("Unknown battery technology '%s'\n", chemistry);

View file

@ -1663,6 +1663,15 @@ static int rt9455_probe(struct i2c_client *client)
rt9455_charger_config.supplied_to = rt9455_charger_supplied_to;
rt9455_charger_config.num_supplicants =
ARRAY_SIZE(rt9455_charger_supplied_to);
info->charger = devm_power_supply_register(dev, &rt9455_charger_desc,
&rt9455_charger_config);
if (IS_ERR(info->charger)) {
dev_err(dev, "Failed to register charger\n");
ret = PTR_ERR(info->charger);
goto put_usb_notifier;
}
ret = devm_request_threaded_irq(dev, client->irq, NULL,
rt9455_irq_handler_thread,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
@ -1678,14 +1687,6 @@ static int rt9455_probe(struct i2c_client *client)
goto put_usb_notifier;
}
info->charger = devm_power_supply_register(dev, &rt9455_charger_desc,
&rt9455_charger_config);
if (IS_ERR(info->charger)) {
dev_err(dev, "Failed to register charger\n");
ret = PTR_ERR(info->charger);
goto put_usb_notifier;
}
return 0;
put_usb_notifier:

View file

@ -1174,24 +1174,6 @@ static int sbs_probe(struct i2c_client *client)
i2c_set_clientdata(client, chip);
if (!chip->gpio_detect)
goto skip_gpio;
irq = gpiod_to_irq(chip->gpio_detect);
if (irq <= 0) {
dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
goto skip_gpio;
}
rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev_name(&client->dev), chip);
if (rc) {
dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
goto skip_gpio;
}
skip_gpio:
/*
* Before we register, we might need to make sure we can actually talk
* to the battery.
@ -1217,6 +1199,24 @@ skip_gpio:
return dev_err_probe(&client->dev, PTR_ERR(chip->power_supply),
"Failed to register power supply\n");
if (!chip->gpio_detect)
goto out;
irq = gpiod_to_irq(chip->gpio_detect);
if (irq <= 0) {
dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
goto out;
}
rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev_name(&client->dev), chip);
if (rc) {
dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
goto out;
}
out:
dev_info(&client->dev,
"%s: battery gas gauge device registered\n", client->name);

View file

@ -6,7 +6,6 @@
*/
#include <linux/bits.h>
#include <linux/freezer.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>

View file

@ -178,12 +178,6 @@ static int wm97xx_bat_probe(struct platform_device *dev)
"failed to get charge GPIO\n");
if (charge_gpiod) {
gpiod_set_consumer_name(charge_gpiod, "BATT CHRG");
ret = request_irq(gpiod_to_irq(charge_gpiod),
wm97xx_chrg_irq, 0,
"AC Detect", dev);
if (ret)
return dev_err_probe(&dev->dev, ret,
"failed to request GPIO irq\n");
props++; /* POWER_SUPPLY_PROP_STATUS */
}
@ -198,11 +192,9 @@ static int wm97xx_bat_probe(struct platform_device *dev)
if (pdata->min_voltage >= 0)
props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */
prop = kcalloc(props, sizeof(*prop), GFP_KERNEL);
if (!prop) {
ret = -ENOMEM;
goto err3;
}
prop = devm_kcalloc(&dev->dev, props, sizeof(*prop), GFP_KERNEL);
if (!prop)
return -ENOMEM;
prop[i++] = POWER_SUPPLY_PROP_PRESENT;
if (charge_gpiod)
@ -231,21 +223,21 @@ static int wm97xx_bat_probe(struct platform_device *dev)
bat_psy_desc.properties = prop;
bat_psy_desc.num_properties = props;
bat_psy = power_supply_register(&dev->dev, &bat_psy_desc, &cfg);
if (!IS_ERR(bat_psy)) {
schedule_work(&bat_work);
} else {
ret = PTR_ERR(bat_psy);
goto err4;
bat_psy = devm_power_supply_register(&dev->dev, &bat_psy_desc, &cfg);
if (IS_ERR(bat_psy))
return PTR_ERR(bat_psy);
schedule_work(&bat_work);
if (charge_gpiod) {
ret = request_irq(gpiod_to_irq(charge_gpiod), wm97xx_chrg_irq,
0, "AC Detect", dev);
if (ret)
return dev_err_probe(&dev->dev, ret,
"failed to request GPIO irq\n");
}
return 0;
err4:
kfree(prop);
err3:
if (charge_gpiod)
free_irq(gpiod_to_irq(charge_gpiod), dev);
return ret;
}
static void wm97xx_bat_remove(struct platform_device *dev)
@ -253,8 +245,6 @@ static void wm97xx_bat_remove(struct platform_device *dev)
if (charge_gpiod)
free_irq(gpiod_to_irq(charge_gpiod), dev);
cancel_work_sync(&bat_work);
power_supply_unregister(bat_psy);
kfree(prop);
}
static struct platform_driver wm97xx_bat_driver = {