Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: supply: bq25890: Support boards with more then one charger IC

Some devices, such as the Lenovo Yoga Tab 3 Pro (YT3-X90F) have
multiple batteries with a separate bq25890 charger for each battery.

This requires the bq25890_charger code to use a unique name per
registered power_supply class device, rather then hardcoding
"bq25890-charger" as power_supply class device name.

Add a "-%d" prefix to the name, allocated through idr in the same way
as several other power_supply drivers are already doing this.

Note this also updates: drivers/platform/x86/x86-android-tablets.c
which refers to the charger by power_supply-class-device-name for
the purpose of setting the "supplied-from" property on the fuel-gauge
to this name.

Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Hans de Goede and committed by
Sebastian Reichel
4e9498b8 dee0df84

+26 -5
+1 -1
drivers/platform/x86/x86-android-tablets.c
··· 187 187 /* Generic / shared charger / battery settings */ 188 188 static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; 189 189 static const char * const bq24190_psy[] = { "bq24190-charger" }; 190 - static const char * const bq25890_psy[] = { "bq25890-charger" }; 190 + static const char * const bq25890_psy[] = { "bq25890-charger-0" }; 191 191 192 192 static const struct property_entry fg_bq24190_supply_props[] = { 193 193 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
+25 -4
drivers/power/supply/bq25890_charger.c
··· 108 108 struct i2c_client *client; 109 109 struct device *dev; 110 110 struct power_supply *charger; 111 + struct power_supply_desc desc; 112 + char name[28]; /* "bq25890-charger-%d" */ 113 + int id; 111 114 112 115 struct usb_phy *usb_phy; 113 116 struct notifier_block usb_nb; ··· 131 128 132 129 struct mutex lock; /* protect state data */ 133 130 }; 131 + 132 + static DEFINE_IDR(bq25890_id); 133 + static DEFINE_MUTEX(bq25890_id_mutex); 134 134 135 135 static const struct regmap_range bq25890_readonly_reg_ranges[] = { 136 136 regmap_reg_range(0x0b, 0x0c), ··· 995 989 }; 996 990 997 991 static const struct power_supply_desc bq25890_power_supply_desc = { 998 - .name = "bq25890-charger", 999 992 .type = POWER_SUPPLY_TYPE_USB, 1000 993 .properties = bq25890_power_supply_props, 1001 994 .num_properties = ARRAY_SIZE(bq25890_power_supply_props), ··· 1008 1003 { 1009 1004 struct power_supply_config psy_cfg = { .drv_data = bq, }; 1010 1005 1006 + /* Get ID for the device */ 1007 + mutex_lock(&bq25890_id_mutex); 1008 + bq->id = idr_alloc(&bq25890_id, bq, 0, 0, GFP_KERNEL); 1009 + mutex_unlock(&bq25890_id_mutex); 1010 + if (bq->id < 0) 1011 + return bq->id; 1012 + 1013 + snprintf(bq->name, sizeof(bq->name), "bq25890-charger-%d", bq->id); 1014 + bq->desc = bq25890_power_supply_desc; 1015 + bq->desc.name = bq->name; 1016 + 1011 1017 psy_cfg.supplied_to = bq25890_charger_supplied_to; 1012 1018 psy_cfg.num_supplicants = ARRAY_SIZE(bq25890_charger_supplied_to); 1013 1019 1014 - bq->charger = devm_power_supply_register(bq->dev, 1015 - &bq25890_power_supply_desc, 1016 - &psy_cfg); 1020 + bq->charger = devm_power_supply_register(bq->dev, &bq->desc, &psy_cfg); 1017 1021 1018 1022 return PTR_ERR_OR_ZERO(bq->charger); 1019 1023 } ··· 1368 1354 struct bq25890_device *bq = data; 1369 1355 1370 1356 cancel_delayed_work_sync(&bq->pump_express_work); 1357 + 1358 + if (bq->id >= 0) { 1359 + mutex_lock(&bq25890_id_mutex); 1360 + idr_remove(&bq25890_id, bq->id); 1361 + mutex_unlock(&bq25890_id_mutex); 1362 + } 1371 1363 } 1372 1364 1373 1365 static int bq25890_probe(struct i2c_client *client) ··· 1388 1368 1389 1369 bq->client = client; 1390 1370 bq->dev = dev; 1371 + bq->id = -1; 1391 1372 1392 1373 mutex_init(&bq->lock); 1393 1374 INIT_DELAYED_WORK(&bq->pump_express_work, bq25890_pump_express_work);