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

power: supply: axp20x_usb_power: fix race condition with usb bc

When input_current_limit is set while USB BC is in progress, the BC
module will overwrite the value that was set when it finishes detection.

Signed-off-by: Aren Moynihan <aren@peacevolution.org>
Link: https://lore.kernel.org/r/20240130203714.3020464-4-aren@peacevolution.org
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Aren Moynihan and committed by
Sebastian Reichel
06a807e6 b02fbd83

+23
+23
drivers/power/supply/axp20x_usb_power.c
··· 117 117 if (val != power->old_status) 118 118 power_supply_changed(power->supply); 119 119 120 + if (power->usb_bc_en_bit && (val & AXP20X_PWR_STATUS_VBUS_PRESENT) != 121 + (power->old_status & AXP20X_PWR_STATUS_VBUS_PRESENT)) { 122 + dev_dbg(power->dev, "Cable status changed, re-enabling USB BC"); 123 + ret = regmap_field_write(power->usb_bc_en_bit, 1); 124 + if (ret) 125 + dev_err(power->dev, "failed to enable USB BC: errno %d", 126 + ret); 127 + } 128 + 120 129 power->old_status = val; 121 130 power->online = val & AXP20X_PWR_STATUS_VBUS_USED; 122 131 ··· 274 265 static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power, 275 266 int intval) 276 267 { 268 + int ret; 277 269 unsigned int reg; 278 270 const unsigned int max = power->axp_data->curr_lim_table_size; 279 271 280 272 if (intval == -1) 281 273 return -EINVAL; 274 + 275 + /* 276 + * BC1.2 detection can cause a race condition if we try to set a current 277 + * limit while it's in progress. When it finishes it will overwrite the 278 + * current limit we just set. 279 + */ 280 + if (power->usb_bc_en_bit) { 281 + dev_dbg(power->dev, 282 + "disabling BC1.2 detection because current limit was set"); 283 + ret = regmap_field_write(power->usb_bc_en_bit, 0); 284 + if (ret) 285 + return ret; 286 + } 282 287 283 288 for (reg = max - 1; reg > 0; reg--) 284 289 if (power->axp_data->curr_lim_table[reg] <= intval)