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

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

Merge "qcom: battery: Fix using stale votable pointers"

parents a7e6a824 3ecadbc4
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -930,11 +930,17 @@ static int pl_determine_initial_status(struct pl_data *chip)
}

#define DEFAULT_RESTRICTED_CURRENT_UA	1000000
static int pl_init(void)
int qcom_batt_init(void)
{
	struct pl_data *chip;
	int rc = 0;

	/* initialize just once */
	if (the_chip) {
		pr_err("was initialized earlier Failing now\n");
		return -EINVAL;
	}

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;
@@ -1014,7 +1020,9 @@ static int pl_init(void)
		goto unreg_notifier;
	}

	return rc;
	the_chip = chip;

	return 0;

unreg_notifier:
	power_supply_unreg_notifier(&chip->nb);
@@ -1031,21 +1039,23 @@ cleanup:
	return rc;
}

static void pl_deinit(void)
void qcom_batt_deinit(void)
{
	struct pl_data *chip = the_chip;

	if (chip == NULL)
		return;

	cancel_work_sync(&chip->status_change_work);
	cancel_delayed_work_sync(&chip->pl_taper_work);
	cancel_work_sync(&chip->pl_disable_forever_work);

	power_supply_unreg_notifier(&chip->nb);
	destroy_votable(chip->pl_awake_votable);
	destroy_votable(chip->pl_disable_votable);
	destroy_votable(chip->fv_votable);
	destroy_votable(chip->fcc_votable);
	wakeup_source_unregister(chip->pl_ws);
	the_chip = NULL;
	kfree(chip);
}

module_init(pl_init);
module_exit(pl_deinit)

MODULE_DESCRIPTION("");
MODULE_LICENSE("GPL v2");
+17 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __BATTERY_H
#define __BATTERY_H
int qcom_batt_init(void);
void qcom_batt_deinit(void);
#endif /* __BATTERY_H */
+1 −1
Original line number Diff line number Diff line
@@ -677,7 +677,7 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
		rc = smblib_get_prop_fcc_delta(chg, val);
		break;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		val->intval = get_effective_result(chg->usb_icl_votable);
		rc = smblib_get_icl_current(chg, &val->intval);
		break;
	default:
		pr_debug("get prop %d is not supported in usb-main\n", psp);
+118 −12
Original line number Diff line number Diff line
@@ -19,10 +19,11 @@
#include <linux/qpnp/qpnp-revid.h>
#include <linux/input/qpnp-power-on.h>
#include <linux/irq.h>
#include <linux/pmic-voter.h>
#include "smb-lib.h"
#include "smb-reg.h"
#include "battery.h"
#include "storm-watch.h"
#include <linux/pmic-voter.h>

#define smblib_err(chg, fmt, ...)		\
	pr_err("%s: %s: " fmt, chg->name,	\
@@ -813,6 +814,28 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua)
	return rc;
}

static int get_sdp_current(struct smb_charger *chg, int *icl_ua)
{
	int rc;
	u8 icl_options;
	bool usb3 = false;

	rc = smblib_read(chg, USBIN_ICL_OPTIONS_REG, &icl_options);
	if (rc < 0) {
		smblib_err(chg, "Couldn't get ICL options rc=%d\n", rc);
		return rc;
	}

	usb3 = (icl_options & CFG_USB3P0_SEL_BIT);

	if (icl_options & USB51_MODE_BIT)
		*icl_ua = usb3 ? USBIN_900MA : USBIN_500MA;
	else
		*icl_ua = usb3 ? USBIN_150MA : USBIN_100MA;

	return rc;
}

int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
{
	int rc = 0;
@@ -890,6 +913,48 @@ enable_icl_changed_interrupt:
	return rc;
}

int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua)
{
	int rc = 0;
	u8 load_cfg;
	bool override;
	union power_supply_propval pval;

	rc = smblib_get_prop_typec_mode(chg, &pval);
	if (rc < 0) {
		smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc);
		return rc;
	}

	if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
		|| chg->micro_usb_mode)
		&& (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) {
		rc = get_sdp_current(chg, icl_ua);
		if (rc < 0) {
			smblib_err(chg, "Couldn't get SDP ICL rc=%d\n", rc);
			return rc;
		}
	} else {
		rc = smblib_read(chg, USBIN_LOAD_CFG_REG, &load_cfg);
		if (rc < 0) {
			smblib_err(chg, "Couldn't get load cfg rc=%d\n", rc);
			return rc;
		}
		override = load_cfg & ICL_OVERRIDE_AFTER_APSD_BIT;
		if (!override)
			return INT_MAX;

		/* override is set */
		rc = smblib_get_charge_param(chg, &chg->param.usb_icl, icl_ua);
		if (rc < 0) {
			smblib_err(chg, "Couldn't get HC ICL rc=%d\n", rc);
			return rc;
		}
	}

	return 0;
}

/*********************
 * VOTABLE CALLBACKS *
 *********************/
@@ -3088,12 +3153,28 @@ static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising)
	}
}

static void smblib_typec_usb_plugin(struct smb_charger *chg, bool vbus_rising)
void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg)
{
	int rc;
	u8 stat;
	bool vbus_rising;

	rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read USB_INT_RT_STS rc=%d\n", rc);
		return;
	}

	vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT);

	if (vbus_rising)
		smblib_cc2_sink_removal_exit(chg);
	else
		smblib_cc2_sink_removal_enter(chg);

	power_supply_changed(chg->usb_psy);
	smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n",
					vbus_rising ? "attached" : "detached");
}

#define PL_DELAY_MS			30000
@@ -3152,8 +3233,6 @@ void smblib_usb_plugin_locked(struct smb_charger *chg)

	if (chg->micro_usb_mode)
		smblib_micro_usb_plugin(chg, vbus_rising);
	else
		smblib_typec_usb_plugin(chg, vbus_rising);

	power_supply_changed(chg->usb_psy);
	smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n",
@@ -3166,6 +3245,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
	struct smb_charger *chg = irq_data->parent_data;

	mutex_lock(&chg->lock);
	if (chg->pd_hard_reset)
		smblib_usb_plugin_hard_reset_locked(chg);
	else
		smblib_usb_plugin_locked(chg);
	mutex_unlock(&chg->lock);
	return IRQ_HANDLED;
@@ -4187,26 +4269,30 @@ static int smblib_create_votables(struct smb_charger *chg)
	int rc = 0;

	chg->fcc_votable = find_votable("FCC");
	if (!chg->fcc_votable) {
		rc = -EPROBE_DEFER;
	if (chg->fcc_votable == NULL) {
		rc = -EINVAL;
		smblib_err(chg, "Couldn't find FCC votable rc=%d\n", rc);
		return rc;
	}

	chg->fv_votable = find_votable("FV");
	if (!chg->fv_votable) {
		rc = -EPROBE_DEFER;
	if (chg->fv_votable == NULL) {
		rc = -EINVAL;
		smblib_err(chg, "Couldn't find FV votable rc=%d\n", rc);
		return rc;
	}

	chg->usb_icl_votable = find_votable("USB_ICL");
	if (!chg->usb_icl_votable) {
		rc = -EPROBE_DEFER;
		rc = -EINVAL;
		smblib_err(chg, "Couldn't find USB_ICL votable rc=%d\n", rc);
		return rc;
	}

	chg->pl_disable_votable = find_votable("PL_DISABLE");
	if (!chg->pl_disable_votable) {
		rc = -EPROBE_DEFER;
	if (chg->pl_disable_votable == NULL) {
		rc = -EINVAL;
		smblib_err(chg, "Couldn't find votable PL_DISABLE rc=%d\n", rc);
		return rc;
	}
	vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0);
@@ -4390,6 +4476,14 @@ int smblib_init(struct smb_charger *chg)
	case PARALLEL_MASTER:
		chg->qnovo_fcc_ua = -EINVAL;
		chg->qnovo_fv_uv = -EINVAL;

		rc = qcom_batt_init();
		if (rc < 0) {
			smblib_err(chg, "Couldn't init qcom_batt_init rc=%d\n",
				rc);
			return rc;
		}

		rc = smblib_create_votables(chg);
		if (rc < 0) {
			smblib_err(chg, "Couldn't create votables rc=%d\n",
@@ -4421,8 +4515,20 @@ int smblib_deinit(struct smb_charger *chg)
{
	switch (chg->mode) {
	case PARALLEL_MASTER:
		cancel_work_sync(&chg->bms_update_work);
		cancel_work_sync(&chg->rdstd_cc2_detach_work);
		cancel_delayed_work_sync(&chg->hvdcp_detect_work);
		cancel_delayed_work_sync(&chg->step_soc_req_work);
		cancel_delayed_work_sync(&chg->clear_hdc_work);
		cancel_work_sync(&chg->otg_oc_work);
		cancel_work_sync(&chg->vconn_oc_work);
		cancel_delayed_work_sync(&chg->otg_ss_done_work);
		cancel_delayed_work_sync(&chg->icl_change_work);
		cancel_delayed_work_sync(&chg->pl_enable_work);
		cancel_work_sync(&chg->legacy_detection_work);
		power_supply_unreg_notifier(&chg->nb);
		smblib_destroy_votables(chg);
		qcom_batt_deinit();
		break;
	case PARALLEL_SLAVE:
		break;
+1 −0
Original line number Diff line number Diff line
@@ -493,6 +493,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override);
int smblib_dp_dm(struct smb_charger *chg, int val);
int smblib_rerun_aicl(struct smb_charger *chg);
int smblib_set_icl_current(struct smb_charger *chg, int icl_ua);
int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua);
int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua);

int smblib_init(struct smb_charger *chg);
Loading