From 3370f271bac47c366689c2372d201bc48cb99b15 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 29 Feb 2020 01:04:17 -0600 Subject: power: supply: axp20x_battery: Send uevents for status changes Signed-off-by: Samuel Holland --- 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 74a5d53d7cf2..1c4d5f2eac62 100644 --- a/drivers/power/supply/axp20x_battery.c +++ b/drivers/power/supply/axp20x_battery.c @@ -90,8 +90,15 @@ #define AXP717_BAT_CC_MIN_UA 0 #define AXP717_BAT_CC_MAX_UA 3008000 +#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; @@ -106,6 +113,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 { @@ -1030,6 +1038,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, @@ -1040,6 +1067,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 = { @@ -1053,6 +1081,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 = { @@ -1065,6 +1094,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 = { @@ -1078,6 +1108,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[] = { @@ -1099,11 +1130,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; @@ -1141,6 +1174,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. @@ -1206,7 +1258,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