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

Commit 0ce2ea25 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: battery: Remove wakelock for parallel"

parents 6bec818d 3c800464
Loading
Loading
Loading
Loading
+0 −19
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ struct pl_data {
	struct delayed_work	status_change_work;
	struct work_struct	pl_disable_forever_work;
	struct work_struct	pl_taper_work;
	struct delayed_work	pl_awake_work;
	struct delayed_work	fcc_stepper_work;
	bool			taper_work_running;
	struct power_supply	*main_psy;
@@ -1108,14 +1107,6 @@ static void pl_disable_forever_work(struct work_struct *work)
		vote(chip->hvdcp_hw_inov_dis_votable, PL_VOTER, false, 0);
}

static void pl_awake_work(struct work_struct *work)
{
	struct pl_data *chip = container_of(work,
			struct pl_data, pl_awake_work.work);

	vote(chip->pl_awake_votable, PL_VOTER, false, 0);
}

static bool is_batt_available(struct pl_data *chip)
{
	if (!chip->batt_psy)
@@ -1176,10 +1167,6 @@ static int pl_disable_vote_callback(struct votable *votable,
	total_fcc_ua = get_effective_result_locked(chip->fcc_votable);

	if (chip->pl_mode != POWER_SUPPLY_PL_NONE && !pl_disable) {
		/* keep system awake to talk to slave charger through i2c */
		cancel_delayed_work_sync(&chip->pl_awake_work);
		vote(chip->pl_awake_votable, PL_VOTER, true, 0);

		rc = validate_parallel_icl(chip, &disable);
		if (rc < 0)
			return rc;
@@ -1337,10 +1324,6 @@ static int pl_disable_vote_callback(struct votable *votable,
		}

		rerun_election(chip->fv_votable);

		cancel_delayed_work_sync(&chip->pl_awake_work);
		schedule_delayed_work(&chip->pl_awake_work,
						msecs_to_jiffies(5000));
	}

	/* notify parallel state change */
@@ -1836,7 +1819,6 @@ int qcom_batt_init(int smb_version)
	INIT_DELAYED_WORK(&chip->status_change_work, status_change_work);
	INIT_WORK(&chip->pl_taper_work, pl_taper_work);
	INIT_WORK(&chip->pl_disable_forever_work, pl_disable_forever_work);
	INIT_DELAYED_WORK(&chip->pl_awake_work, pl_awake_work);
	INIT_DELAYED_WORK(&chip->fcc_stepper_work, fcc_stepper_work);

	rc = pl_register_notifier(chip);
@@ -1894,7 +1876,6 @@ void qcom_batt_deinit(void)
	cancel_delayed_work_sync(&chip->status_change_work);
	cancel_work_sync(&chip->pl_taper_work);
	cancel_work_sync(&chip->pl_disable_forever_work);
	cancel_delayed_work_sync(&chip->pl_awake_work);
	cancel_delayed_work_sync(&chip->fcc_stepper_work);

	power_supply_unreg_notifier(&chip->nb);
+221 −18
Original line number Diff line number Diff line
@@ -236,19 +236,28 @@ struct smb1355 {
	struct smb_params	param;

	struct mutex		write_lock;
	struct mutex		suspend_lock;

	struct power_supply	*parallel_psy;
	struct pmic_revid_data	*pmic_rev_id;

	int			d_health;
	int			c_health;
	int			c_charger_temp_max;
	int			die_temp_deciDegC;
	int			suspended_usb_icl;
	int			charge_type;
	int			vbatt_uv;
	int			fcc_ua;
	bool			exit_die_temp;
	struct delayed_work	die_temp_work;
	bool			disabled;
	bool			suspended;
	bool			charging_enabled;
	bool			pin_status;

	struct votable		*irq_disable_votable;
	struct votable		*fcc_votable;
	struct votable		*fv_votable;
};

enum {
@@ -265,6 +274,27 @@ static bool is_secure(struct smb1355 *chip, int addr)
	return (addr & 0xFF) >= 0xA0;
}

static bool is_voter_available(struct smb1355 *chip)
{
	if (!chip->fcc_votable) {
		chip->fcc_votable = find_votable("FCC");
		if (!chip->fcc_votable) {
			pr_debug("Couldn't find FCC votable\n");
			return false;
		}
	}

	if (!chip->fv_votable) {
		chip->fv_votable = find_votable("FV");
		if (!chip->fv_votable) {
			pr_debug("Couldn't find FV votable\n");
			return false;
		}
	}

	return true;
}

static int smb1355_read(struct smb1355 *chip, u16 addr, u8 *val)
{
	unsigned int temp;
@@ -589,6 +619,138 @@ static int smb1355_get_prop_health(struct smb1355 *chip, int type)
	return POWER_SUPPLY_HEALTH_COOL;
}

static int smb1355_get_prop_voltage_max(struct smb1355 *chip,
					union power_supply_propval *val)
{
	int rc = 0;

	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = chip->vbatt_uv;
		goto done;
	}
	rc = smb1355_get_charge_param(chip, &chip->param.ov, &val->intval);
	if (rc < 0)
		pr_err("failed to read vbatt rc=%d\n", rc);
	else
		chip->vbatt_uv = val->intval;
done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

static int smb1355_get_prop_constant_charge_current_max(struct smb1355 *chip,
					union power_supply_propval *val)
{
	int rc = 0;

	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = chip->fcc_ua;
		goto done;
	}
	rc = smb1355_get_charge_param(chip, &chip->param.fcc, &val->intval);
	if (rc < 0)
		pr_err("failed to read fcc rc=%d\n", rc);
	else
		chip->fcc_ua = val->intval;
done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

static int smb1355_get_prop_health_value(struct smb1355 *chip,
				union power_supply_propval *val, int type)
{
	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = (type == DIE_TEMP) ? chip->d_health :
						chip->c_health;
	} else {
		val->intval = smb1355_get_prop_health(chip, (type == DIE_TEMP) ?
						DIE_TEMP : CONNECTOR_TEMP);
		if (type == DIE_TEMP)
			chip->d_health = val->intval;
		else
			chip->c_health = val->intval;
	}

	mutex_unlock(&chip->suspend_lock);

	return 0;
}

static int smb1355_get_prop_online(struct smb1355 *chip,
					union power_supply_propval *val)
{
	int rc = 0;
	u8 stat;

	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = chip->charging_enabled;
		goto done;
	}
	rc = smb1355_read(chip, BATTERY_STATUS_3_REG, &stat);
	if (rc < 0) {
		pr_err("failed to read BATTERY_STATUS_3_REG %d\n", rc);
	} else {
		val->intval = (bool)(stat & ENABLE_CHARGING_BIT);
		chip->charging_enabled = val->intval;
	}
done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

static int smb1355_get_prop_pin_enabled(struct smb1355 *chip,
					union power_supply_propval *val)
{
	int rc = 0;
	u8 stat;

	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = chip->pin_status;
		goto done;
	}
	rc = smb1355_read(chip, BATTERY_STATUS_2_REG, &stat);
	if (rc < 0) {
		pr_err("failed to read BATTERY_STATUS_2_REG %d\n", rc);
	} else {
		val->intval = !(stat & DISABLE_CHARGING_BIT);
		chip->pin_status = val->intval;
	}
done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

static int smb1355_get_prop_charge_type(struct smb1355 *chip,
					union power_supply_propval *val)
{
	int rc = 0;

	/*
	 * In case of system suspend we should not allow
	 * register reads and writes to the device as it
	 * leads to i2c transaction failures.
	 */
	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		val->intval = chip->charge_type;
		goto done;
	}
	rc = smb1355_get_prop_batt_charge_type(chip, val);
	if (rc < 0)
		pr_err("failed to read batt_charge_type %d\n", rc);
	else
		chip->charge_type = val->intval;
done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

#define MIN_PARALLEL_ICL_UA		250000
#define SUSPEND_CURRENT_UA		2000
static int smb1355_parallel_get_prop(struct power_supply *psy,
@@ -596,23 +758,18 @@ static int smb1355_parallel_get_prop(struct power_supply *psy,
				     union power_supply_propval *val)
{
	struct smb1355 *chip = power_supply_get_drvdata(psy);
	u8 stat;
	int rc = 0;

	switch (prop) {
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		rc = smb1355_get_prop_batt_charge_type(chip, val);
		rc = smb1355_get_prop_charge_type(chip, val);
		break;
	case POWER_SUPPLY_PROP_CHARGING_ENABLED:
	case POWER_SUPPLY_PROP_ONLINE:
		rc = smb1355_read(chip, BATTERY_STATUS_3_REG, &stat);
		if (rc >= 0)
			val->intval = (bool)(stat & ENABLE_CHARGING_BIT);
		rc = smb1355_get_prop_online(chip, val);
		break;
	case POWER_SUPPLY_PROP_PIN_ENABLED:
		rc = smb1355_read(chip, BATTERY_STATUS_2_REG, &stat);
		if (rc >= 0)
			val->intval = !(stat & DISABLE_CHARGING_BIT);
		rc = smb1355_get_prop_pin_enabled(chip, val);
		break;
	case POWER_SUPPLY_PROP_CHARGER_TEMP:
		val->intval = chip->die_temp_deciDegC;
@@ -634,12 +791,10 @@ static int smb1355_parallel_get_prop(struct power_supply *psy,
		val->intval = chip->disabled;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		rc = smb1355_get_charge_param(chip, &chip->param.ov,
						&val->intval);
		rc = smb1355_get_prop_voltage_max(chip, val);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		rc = smb1355_get_charge_param(chip, &chip->param.fcc,
						&val->intval);
		rc = smb1355_get_prop_constant_charge_current_max(chip, val);
		break;
	case POWER_SUPPLY_PROP_MODEL_NAME:
		val->strval = chip->name;
@@ -649,13 +804,13 @@ static int smb1355_parallel_get_prop(struct power_supply *psy,
		break;
	case POWER_SUPPLY_PROP_CONNECTOR_HEALTH:
		if (chip->c_health == -EINVAL)
			val->intval = smb1355_get_prop_health(chip,
			rc = smb1355_get_prop_health_value(chip, val,
							CONNECTOR_TEMP);
		else
			val->intval = chip->c_health;
		break;
	case POWER_SUPPLY_PROP_DIE_HEALTH:
		val->intval = smb1355_get_prop_health(chip, DIE_TEMP);
		rc = smb1355_get_prop_health_value(chip, val, DIE_TEMP);
		break;
	case POWER_SUPPLY_PROP_PARALLEL_BATFET_MODE:
		val->intval = chip->dt.pl_batfet_mode;
@@ -816,6 +971,11 @@ static int smb1355_parallel_set_prop(struct power_supply *psy,
	struct smb1355 *chip = power_supply_get_drvdata(psy);
	int rc = 0;

	mutex_lock(&chip->suspend_lock);
	if (chip->suspended) {
		pr_debug("parallel power supply set prop %d\n", prop);
		goto done;
	}
	switch (prop) {
	case POWER_SUPPLY_PROP_INPUT_SUSPEND:
		rc = smb1355_set_parallel_charging(chip, (bool)val->intval);
@@ -845,9 +1005,10 @@ static int smb1355_parallel_set_prop(struct power_supply *psy,
	default:
		pr_debug("parallel power supply set prop %d not supported\n",
			prop);
		return -EINVAL;
		rc = -EINVAL;
	}

done:
	mutex_unlock(&chip->suspend_lock);
	return rc;
}

@@ -1387,8 +1548,10 @@ static int smb1355_probe(struct platform_device *pdev)
	chip->dev = &pdev->dev;
	chip->param = v1_params;
	chip->c_health = -EINVAL;
	chip->d_health = -EINVAL;
	chip->c_charger_temp_max = -EINVAL;
	mutex_init(&chip->write_lock);
	mutex_init(&chip->suspend_lock);
	INIT_DELAYED_WORK(&chip->die_temp_work, die_temp_work);
	chip->disabled = false;
	chip->die_temp_deciDegC = -EINVAL;
@@ -1484,9 +1647,49 @@ static void smb1355_shutdown(struct platform_device *pdev)
	smb1355_clk_request(chip, false);
}

#ifdef CONFIG_PM_SLEEP
static int smb1355_suspend(struct device *dev)
{
	struct smb1355 *chip = dev_get_drvdata(dev);

	cancel_delayed_work_sync(&chip->die_temp_work);

	mutex_lock(&chip->suspend_lock);
	chip->suspended = true;
	mutex_unlock(&chip->suspend_lock);

	return 0;
}

static int smb1355_resume(struct device *dev)
{
	struct smb1355 *chip = dev_get_drvdata(dev);

	mutex_lock(&chip->suspend_lock);
	chip->suspended = false;
	mutex_unlock(&chip->suspend_lock);

	/*
	 * During suspend i2c failures are fixed by reporting cached
	 * chip state, to report correct values we need to invoke
	 * callbacks for the fcc and fv votables. To avoid excessive
	 * invokes to callbacks invoke only when smb1355 is enabled.
	 */
	if (is_voter_available(chip) && chip->charging_enabled) {
		rerun_election(chip->fcc_votable);
		rerun_election(chip->fv_votable);
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(smb1355_pm_ops, smb1355_suspend, smb1355_resume);

static struct platform_driver smb1355_driver = {
	.driver	= {
		.name		= "qcom,smb1355-charger",
		.pm		= &smb1355_pm_ops,
		.of_match_table	= match_table,
	},
	.probe		= smb1355_probe,