Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b33615e4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-fg: fix peripheral restart code"

parents c2e89326 6ed51a55
Loading
Loading
Loading
Loading
+96 −50
Original line number Diff line number Diff line
@@ -400,6 +400,7 @@ struct fg_chip {
	struct completion	sram_access_granted;
	struct completion	sram_access_revoked;
	struct completion	batt_id_avail;
	struct completion	first_soc_done;
	struct power_supply	bms_psy;
	struct mutex		rw_lock;
	struct mutex		sysfs_restart_lock;
@@ -427,6 +428,7 @@ struct fg_chip {
	bool			first_profile_loaded;
	struct fg_wakeup_source	update_temp_wakeup_source;
	struct fg_wakeup_source	update_sram_wakeup_source;
	bool			fg_restarting;
	bool			profile_loaded;
	bool			use_otp_profile;
	bool			battery_missing;
@@ -1926,6 +1928,9 @@ static void update_sram_data(struct fg_chip *chip, int *resched_ms)
	int battid_valid = fg_is_batt_id_valid(chip);

	fg_stay_awake(&chip->update_sram_wakeup_source);
	if (chip->fg_restarting)
		goto resched;

	fg_mem_lock(chip);
	for (i = 1; i < FG_DATA_MAX; i++) {
		if (chip->profile_loaded && i >= FG_DATA_BATT_ID)
@@ -1994,6 +1999,7 @@ static void update_sram_data(struct fg_chip *chip, int *resched_ms)
	if (!rc)
		get_current_time(&chip->last_sram_update_time);

resched:
	if (battid_valid) {
		complete_all(&chip->batt_id_avail);
		*resched_ms = fg_sram_update_period_ms;
@@ -2055,6 +2061,9 @@ static void update_temp_data(struct work_struct *work)
				struct fg_chip,
				update_temp_work.work);

	if (chip->fg_restarting)
		goto resched;

	fg_stay_awake(&chip->update_temp_wakeup_source);
	if (chip->sw_rbias_ctrl) {
		rc = fg_mem_masked_write(chip, EXTERNAL_SENSE_SELECT,
@@ -2110,10 +2119,12 @@ out:
		if (rc)
			pr_err("failed to write BATT_TEMP_OFF rc=%d\n", rc);
	}
	fg_relax(&chip->update_temp_wakeup_source);

resched:
	schedule_delayed_work(
		&chip->update_temp_work,
		msecs_to_jiffies(TEMP_PERIOD_UPDATE_MS));
	fg_relax(&chip->update_temp_wakeup_source);
}

static void update_jeita_setting(struct work_struct *work)
@@ -2555,6 +2566,11 @@ static int fg_power_get_property(struct power_supply *psy,

	switch (psp) {
	case POWER_SUPPLY_PROP_BATTERY_TYPE:
		if (chip->battery_missing)
			val->strval = missing_batt_type;
		else if (chip->fg_restarting)
			val->strval = loading_batt_type;
		else
			val->strval = chip->batt_type;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
@@ -3662,7 +3678,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *_chip)
	if (batt_missing) {
		chip->battery_missing = true;
		chip->profile_loaded = false;
		chip->batt_type = missing_batt_type;
		chip->batt_type = default_batt_type;
		mutex_lock(&chip->cyc_ctr.lock);
		if (fg_debug_mask & FG_IRQS)
			pr_info("battery missing, clearing cycle counters\n");
@@ -3687,6 +3703,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *_chip)

	if (chip->power_supply_registered)
		power_supply_changed(&chip->bms_psy);
	complete_all(&chip->first_soc_done);
	return IRQ_HANDLED;
}

@@ -4142,14 +4159,32 @@ static void update_cc_cv_setpoint(struct fg_chip *chip)
#define FIRST_EST_DONE_BIT		BIT(5)
#define MAX_TRIES_FIRST_EST		3
#define FIRST_EST_WAIT_MS		2000
#define PROFILE_LOAD_TIMEOUT_MS		5000
static int fg_do_restart(struct fg_chip *chip, bool write_profile)
{
	int rc;
	int tries = 0;
	u8 reg = 0;
	u8 buf[2];

	if (fg_debug_mask & FG_STATUS)
		pr_info("restarting fuel gauge...\n");

	chip->fg_restarting = true;
	/*
	 * save the temperature if the sw rbias control is active so that there
	 * is no gap of time when there is no valid temperature read after the
	 * restart
	 */
	if (chip->sw_rbias_ctrl) {
		rc = fg_mem_read(chip, buf,
				fg_data[FG_DATA_BATT_TEMP].address,
				fg_data[FG_DATA_BATT_TEMP].len,
				fg_data[FG_DATA_BATT_TEMP].offset, 0);
		if (rc) {
			pr_err("failed to read batt temp rc=%d\n", rc);
			goto sub_and_fail;
		}
	}
	/*
	 * release the sram access and configure the correct settings
	 * before re-requesting access.
@@ -4246,18 +4281,18 @@ static int fg_do_restart(struct fg_chip *chip, bool write_profile)
	}

	/* wait for the first estimate to complete */
	for (tries = 0; tries < MAX_TRIES_FIRST_EST; tries++) {
		msleep(FIRST_EST_WAIT_MS);

	rc = wait_for_completion_interruptible_timeout(&chip->first_soc_done,
			msecs_to_jiffies(PROFILE_LOAD_TIMEOUT_MS));
	if (rc <= 0) {
		pr_err("transaction timed out rc=%d\n", rc);
		rc = -ETIMEDOUT;
		goto fail;
	}
	rc = fg_read(chip, &reg, INT_RT_STS(chip->soc_base), 1);
	if (rc) {
		pr_err("spmi read failed: addr=%03X, rc=%d\n",
				INT_RT_STS(chip->soc_base), rc);
		}
		if (reg & FIRST_EST_DONE_BIT)
			break;
		if (fg_debug_mask & FG_STATUS)
			pr_info("waiting for est, tries = %d\n", tries);
		goto fail;
	}
	if ((reg & FIRST_EST_DONE_BIT) == 0)
		pr_err("Battery profile reloading failed, no first estimate\n");
@@ -4277,6 +4312,22 @@ static int fg_do_restart(struct fg_chip *chip, bool write_profile)
		goto fail;
	}

	/* restore the battery temperature reading here */
	if (chip->sw_rbias_ctrl) {
		if (fg_debug_mask & FG_STATUS)
			pr_info("reloaded 0x%02x%02x into batt temp",
					buf[0], buf[1]);
		rc = fg_mem_write(chip, buf,
				fg_data[FG_DATA_BATT_TEMP].address,
				fg_data[FG_DATA_BATT_TEMP].len,
				fg_data[FG_DATA_BATT_TEMP].offset, 0);
		if (rc) {
			pr_err("failed to write batt temp rc=%d\n", rc);
			goto fail;
		}
	}
	chip->fg_restarting = false;

	if (fg_debug_mask & FG_STATUS)
		pr_info("done!\n");
	return 0;
@@ -4288,10 +4339,10 @@ sub_and_fail:
	fg_release_access_if_necessary(chip);
	goto fail;
fail:
	chip->fg_restarting = false;
	return -EINVAL;
}

#define PROFILE_LOAD_TIMEOUT_MS		5000
#define FG_PROFILE_LEN			128
#define PROFILE_COMPARE_LEN		32
#define THERMAL_COEFF_ADDR		0x444
@@ -4302,7 +4353,7 @@ static int fg_batt_profile_init(struct fg_chip *chip)
	int len;
	struct device_node *node = chip->spmi->dev.of_node;
	struct device_node *batt_node, *profile_node;
	const char *data, *batt_type_str, *old_batt_type;
	const char *data, *batt_type_str;
	bool tried_again = false, vbat_in_range, profiles_same;
	u8 reg = 0;

@@ -4335,9 +4386,8 @@ wait:
							fg_batt_type);
	if (!profile_node) {
		pr_err("couldn't find profile handle\n");
		old_batt_type = default_batt_type;
		rc = -ENODATA;
		goto fail;
		goto no_profile;
	}

	/* read rslow compensation values if they're available */
@@ -4387,29 +4437,6 @@ wait:
				&chip->cc_cv_threshold_mv);
	}

	/*
	 * Only configure from profile if thermal-coefficients is not
	 * defined in the FG device node.
	 */
	if (!of_find_property(chip->spmi->dev.of_node,
				"qcom,thermal-coefficients", NULL)) {
		data = of_get_property(profile_node,
				"qcom,thermal-coefficients", &len);
		if (data && len == THERMAL_COEFF_N_BYTES) {
			memcpy(chip->thermal_coefficients, data, len);
			rc = fg_mem_write(chip, chip->thermal_coefficients,
				THERMAL_COEFF_ADDR, THERMAL_COEFF_N_BYTES,
				THERMAL_COEFF_OFFSET, 0);
			if (rc) {
				pr_err("spmi write failed addr:%03x, ret:%d\n",
						THERMAL_COEFF_ADDR, rc);
				goto fail;
			} else {
				pr_debug("Battery thermal coefficients changed\n");
			}
		}
	}

	data = of_get_property(profile_node, "qcom,fg-profile-data", &len);
	if (!data) {
		pr_err("no battery profile loaded\n");
@@ -4420,7 +4447,7 @@ wait:
	if (len != FG_PROFILE_LEN) {
		pr_err("battery profile incorrect size: %d\n", len);
		rc = -EINVAL;
		goto fail;
		goto no_profile;
	}

	rc = of_property_read_string(profile_node, "qcom,battery-type",
@@ -4487,8 +4514,6 @@ wait:
				DUMP_PREFIX_NONE, 16, 1,
				chip->batt_profile, len, false);
	}
	old_batt_type = chip->batt_type;
	chip->batt_type = loading_batt_type;
	if (chip->power_supply_registered)
		power_supply_changed(&chip->bms_psy);

@@ -4504,7 +4529,28 @@ wait:
	rc = fg_do_restart(chip, true);
	if (rc) {
		pr_err("restart failed: %d\n", rc);
		goto fail;
		goto no_profile;
	}

	/*
	 * Only configure from profile if thermal-coefficients is not
	 * defined in the FG device node.
	 */
	if (!of_find_property(chip->spmi->dev.of_node,
				"qcom,thermal-coefficients", NULL)) {
		data = of_get_property(profile_node,
				"qcom,thermal-coefficients", &len);
		if (data && len == THERMAL_COEFF_N_BYTES) {
			memcpy(chip->thermal_coefficients, data, len);
			rc = fg_mem_write(chip, chip->thermal_coefficients,
				THERMAL_COEFF_ADDR, THERMAL_COEFF_N_BYTES,
				THERMAL_COEFF_OFFSET, 0);
			if (rc)
				pr_err("spmi write failed addr:%03x, ret:%d\n",
						THERMAL_COEFF_ADDR, rc);
			else if (fg_debug_mask & FG_STATUS)
				pr_info("Battery thermal coefficients changed\n");
		}
	}

done:
@@ -4529,11 +4575,9 @@ done:
	fg_relax(&chip->profile_wakeup_source);
	pr_info("Battery SOC: %d\n", get_prop_capacity(chip));
	return rc;
fail:
	chip->batt_type = old_batt_type;
no_profile:
	if (chip->power_supply_registered)
		power_supply_changed(&chip->bms_psy);
no_profile:
	fg_relax(&chip->profile_wakeup_source);
	return rc;
}
@@ -6022,6 +6066,8 @@ static int fg_probe(struct spmi_device *spmi)
	init_completion(&chip->sram_access_revoked);
	complete_all(&chip->sram_access_revoked);
	init_completion(&chip->batt_id_avail);
	init_completion(&chip->first_soc_done);
	complete_all(&chip->first_soc_done);
	dev_set_drvdata(&spmi->dev, chip);

	spmi_for_each_container_dev(spmi_resource, spmi) {