SBC_builder/patch/kernel/sunxi-6.16/patches.megous/power-supply-axp20x_battery-Send-uevents-for-status-changes.patch
2025-08-27 10:16:25 +02:00

150 lines
4.6 KiB
Diff

From 8c7dd5717bd52b20181f230987e1799953e4becc Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Sat, 5 Apr 2025 18:14:35 +0200
Subject: power: supply: axp20x_battery: Send uevents for status changes
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/power/supply/axp20x_battery.c | 56 ++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
index 3d64d7c8c47b..ee94d9527153 100644
--- a/drivers/power/supply/axp20x_battery.c
+++ b/drivers/power/supply/axp20x_battery.c
@@ -92,8 +92,15 @@
#define AXP717_TS_PIN_DISABLE BIT(4)
+#define DRVNAME "axp20x-battery-power-supply"
+
struct axp20x_batt_ps;
+struct axp_irq_data {
+ const char *name;
+ irq_handler_t handler;
+};
+
struct axp_data {
int ccc_scale;
int ccc_offset;
@@ -108,6 +115,7 @@ struct axp_data {
void (*set_bat_info)(struct platform_device *pdev,
struct axp20x_batt_ps *axp_batt,
struct power_supply_battery_info *info);
+ const struct axp_irq_data *irqs;
};
struct axp20x_batt_ps {
@@ -1051,6 +1059,25 @@ static void axp717_set_battery_info(struct platform_device *pdev,
}
}
+static irqreturn_t axp20x_battery_changed_irq(int irq, void *devid)
+{
+ struct axp20x_batt_ps *axp20x_batt = devid;
+
+ power_supply_changed(axp20x_batt->batt);
+
+ return IRQ_HANDLED;
+}
+
+static const struct axp_irq_data axp20x_irqs[] = {
+ { "BATT_PLUGIN", axp20x_battery_changed_irq },
+ { "BATT_REMOVAL", axp20x_battery_changed_irq },
+ { "BATT_HEALTH_DEAD", axp20x_battery_changed_irq },
+ { "BATT_HEALTH_GOOD", axp20x_battery_changed_irq },
+ { "BATT_CHARGING", axp20x_battery_changed_irq },
+ { "BATT_CHARGING_DONE", axp20x_battery_changed_irq },
+ {}
+};
+
static const struct axp_data axp209_data = {
.ccc_scale = 100000,
.ccc_offset = 300000,
@@ -1061,6 +1088,7 @@ static const struct axp_data axp209_data = {
.set_max_voltage = axp20x_battery_set_max_voltage,
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
.set_bat_info = axp209_set_battery_info,
+ .irqs = axp20x_irqs,
};
static const struct axp_data axp221_data = {
@@ -1074,6 +1102,7 @@ static const struct axp_data axp221_data = {
.set_max_voltage = axp22x_battery_set_max_voltage,
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
.set_bat_info = axp209_set_battery_info,
+ .irqs = axp20x_irqs,
};
static const struct axp_data axp717_data = {
@@ -1086,6 +1115,7 @@ static const struct axp_data axp717_data = {
.set_max_voltage = axp717_battery_set_max_voltage,
.cfg_iio_chan = axp717_bat_cfg_iio_channels,
.set_bat_info = axp717_set_battery_info,
+ .irqs = axp20x_irqs,
};
static const struct axp_data axp813_data = {
@@ -1099,6 +1129,7 @@ static const struct axp_data axp813_data = {
.set_max_voltage = axp20x_battery_set_max_voltage,
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
.set_bat_info = axp209_set_battery_info,
+ .irqs = axp20x_irqs,
};
static const struct of_device_id axp20x_battery_ps_id[] = {
@@ -1120,11 +1151,13 @@ MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
static int axp20x_power_probe(struct platform_device *pdev)
{
+ struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
struct axp20x_batt_ps *axp20x_batt;
struct power_supply_config psy_cfg = {};
struct power_supply_battery_info *info;
struct device *dev = &pdev->dev;
- int ret;
+ const struct axp_irq_data *irq_data;
+ int irq, ret;
if (!of_device_is_available(pdev->dev.of_node))
return -ENODEV;
@@ -1162,6 +1195,25 @@ static int axp20x_power_probe(struct platform_device *pdev)
power_supply_put_battery_info(axp20x_batt->batt, info);
}
+ /* Request irqs after registering, as irqs may trigger immediately */
+ for (irq_data = axp20x_batt->data->irqs; irq_data->name; irq_data++) {
+ irq = platform_get_irq_byname(pdev, irq_data->name);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "No IRQ for %s: %d\n",
+ irq_data->name, irq);
+ return irq;
+ }
+ irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
+ ret = devm_request_any_context_irq(&pdev->dev, irq,
+ irq_data->handler, 0,
+ DRVNAME, axp20x_batt);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Error requesting %s IRQ: %d\n",
+ irq_data->name, ret);
+ return ret;
+ }
+ }
+
/*
* Update max CCC to a valid value if battery info is present or set it
* to current register value by default.
@@ -1227,7 +1279,7 @@ static int axp20x_power_probe(struct platform_device *pdev)
static struct platform_driver axp20x_batt_driver = {
.probe = axp20x_power_probe,
.driver = {
- .name = "axp20x-battery-power-supply",
+ .name = DRVNAME,
.of_match_table = axp20x_battery_ps_id,
},
};
--
2.35.3