diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index 15c931bbbf65..de13d3367648 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -731,7 +731,8 @@ static int qpnp_flash_led_get_voltage_headroom(struct qpnp_flash_led *led) #define FLASH_VDIP_MARGIN 50000 #define BOB_EFFICIENCY 900LL #define VIN_FLASH_MIN_UV 3300000LL -static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) +static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led, + int *max_current) { int ocv_uv = 0, rbatt_uohm = 0, ibat_now = 0, voltage_hdrm_mv = 0; int rc = 0; @@ -747,8 +748,10 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) } /* If no battery is connected, return max possible flash current */ - if (!rbatt_uohm) - return FLASH_LED_MAX_TOTAL_CURRENT_MA; + if (!rbatt_uohm) { + *max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA; + return 0; + } rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv); if (rc < 0) { @@ -785,7 +788,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) /* Wait for LMH mitigation to take effect */ udelay(100); - return qpnp_flash_led_calc_max_current(led); + return qpnp_flash_led_calc_max_current(led, max_current); } /* @@ -825,13 +828,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV); pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n", avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh); - return min(FLASH_LED_MAX_TOTAL_CURRENT_MA, + *max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA, (int)(div64_s64(avail_flash_ua, MCONV))); + return 0; } -static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) +static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led, + int *thermal_current_lim) { - int thermal_current_lim = 0; int rc; u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status; @@ -888,7 +892,7 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) /* Look up current limit based on THERMAL_OTST status */ if (otst_status) - thermal_current_lim = + *thermal_current_lim = led->pdata->thermal_derate_current[otst_status >> 1]; /* Restore THERMAL_THRESHx registers to original values */ @@ -913,23 +917,36 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) if (rc < 0) return rc; - return thermal_current_lim; + return 0; } -static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led) +static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led, + int *max_avail_current) { - int max_avail_current, thermal_current_lim = 0; + int thermal_current_lim = 0, rc; led->trigger_lmh = false; - max_avail_current = qpnp_flash_led_calc_max_current(led); - if (led->pdata->thermal_derate_en) - thermal_current_lim = - qpnp_flash_led_calc_thermal_current_lim(led); + rc = qpnp_flash_led_calc_max_current(led, max_avail_current); + if (rc < 0) { + pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc); + return rc; + } + + if (led->pdata->thermal_derate_en) { + rc = qpnp_flash_led_calc_thermal_current_lim(led, + &thermal_current_lim); + if (rc < 0) { + pr_err("Couldn't calculate thermal_current_lim, rc=%d\n", + rc); + return rc; + } + } if (thermal_current_lim) - max_avail_current = min(max_avail_current, thermal_current_lim); + *max_avail_current = min(*max_avail_current, + thermal_current_lim); - return max_avail_current; + return 0; } static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode) @@ -1237,12 +1254,11 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, } if (options & QUERY_MAX_CURRENT) { - rc = qpnp_flash_led_get_max_avail_current(led); + rc = qpnp_flash_led_get_max_avail_current(led, max_current); if (rc < 0) { pr_err("query max current failed, rc=%d\n", rc); return rc; } - *max_current = rc; } return 0; @@ -1291,7 +1307,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, static ssize_t qpnp_flash_led_max_current_show(struct device *dev, struct device_attribute *attr, char *buf) { - int rc; + int rc, max_current = 0; struct flash_switch_data *snode; struct qpnp_flash_led *led; struct led_classdev *led_cdev = dev_get_drvdata(dev); @@ -1299,11 +1315,11 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev, snode = container_of(led_cdev, struct flash_switch_data, cdev); led = dev_get_drvdata(&snode->pdev->dev); - rc = qpnp_flash_led_get_max_avail_current(led); + rc = qpnp_flash_led_get_max_avail_current(led, &max_current); if (rc < 0) pr_err("query max current failed, rc=%d\n", rc); - return snprintf(buf, PAGE_SIZE, "%d\n", rc); + return snprintf(buf, PAGE_SIZE, "%d\n", max_current); } /* sysfs attributes exported by flash_led */