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

Commit 1b2e28e2 authored by Guru Das Srinagesh's avatar Guru Das Srinagesh
Browse files

power: qti_battery_charger: Block PMIC GLINK Tx for debug battery



The remote subsystem does not transmit PMIC GLINK notifications
triggered by charging parameter changes when a debug battery (one whose
battery ID is set to 7.5 Kohms) is detected. This allows it to enter low
power mode provided no queries for individual power supply (PSY)
properties are made of it.

Power consumption monitoring tests require it to enter low power mode
and stay there, which can happen only if it is not disturbed by having
to respond to queries made by HLOS for PSY properties. This change
enables the user to block all PMIC GLINK Tx messages from this driver to
remote subsystem by setting the boolean debugfs property "block_tx".

Once this is done, all subsequent reads of PSY properties will return
not the instantaneous values of those quantities, but the last (stale)
values obtained during the last read that was made prior to Tx being
blocked. To return to normal behaviour and obtain instantaneous values
from the remote subsystem, the debugfs property must be cleared.

Change-Id: Ie9b6ec78dcb8ec00102e9d7d23e238445045206f
Signed-off-by: default avatarGuru Das Srinagesh <gurus@codeaurora.org>
parent b5d21191
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#define pr_fmt(fmt)	"BATTERY_CHG: %s: " fmt, __func__

#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -145,12 +146,15 @@ struct battery_chg_dev {
	struct mutex			rw_lock;
	struct completion		ack;
	struct psy_state		psy_list[PSY_TYPE_MAX];
	struct dentry			*debugfs_dir;
	u32				*thermal_levels;
	int				curr_thermal_level;
	int				num_thermal_levels;
	atomic_t			state;
	struct work_struct		subsys_up_work;
	int				fake_soc;
	bool				block_tx;
	bool				debug_battery_detected;
};

static const int battery_prop_map[BATT_PROP_MAX] = {
@@ -211,6 +215,9 @@ static int battery_chg_write(struct battery_chg_dev *bcdev, void *data,
		return 0;
	}

	if (bcdev->debug_battery_detected && bcdev->block_tx)
		return 0;

	mutex_lock(&bcdev->rw_lock);
	reinit_completion(&bcdev->ack);
	rc = pmic_glink_write(bcdev->client, data, len);
@@ -383,6 +390,7 @@ static bool validate_message(struct battery_charger_resp_msg *resp_msg,
	return true;
}

#define MODEL_DEBUG_BOARD	"Debug_Board"
static void handle_message(struct battery_chg_dev *bcdev, void *data,
				size_t len)
{
@@ -399,6 +407,8 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data,
		if (pst->model && len == sizeof(*model_resp_msg)) {
			memcpy(pst->model, model_resp_msg->model, MAX_STR_LEN);
			ack_set = true;
			bcdev->debug_battery_detected = !strcmp(pst->model,
					MODEL_DEBUG_BOARD);
			break;
		}

@@ -1008,6 +1018,38 @@ static struct attribute *battery_class_attrs[] = {
};
ATTRIBUTE_GROUPS(battery_class);

#ifdef CONFIG_DEBUG_FS
static void battery_chg_add_debugfs(struct battery_chg_dev *bcdev)
{
	int rc;
	struct dentry *dir, *file;

	dir = debugfs_create_dir("battery_charger", NULL);
	if (IS_ERR(dir)) {
		rc = PTR_ERR(dir);
		pr_err("Failed to create charger debugfs directory, rc=%d\n",
			rc);
		return;
	}

	file = debugfs_create_bool("block_tx", 0600, dir, &bcdev->block_tx);
	if (IS_ERR(file)) {
		rc = PTR_ERR(file);
		pr_err("Failed to create block_tx debugfs file, rc=%d\n",
			rc);
		goto error;
	}

	bcdev->debugfs_dir = dir;

	return;
error:
	debugfs_remove_recursive(dir);
}
#else
static void battery_chg_add_debugfs(struct battery_chg_dev *bcdev) { }
#endif

static int battery_chg_parse_dt(struct battery_chg_dev *bcdev)
{
	struct device_node *node = bcdev->dev->of_node;
@@ -1144,6 +1186,7 @@ static int battery_chg_probe(struct platform_device *pdev)
		goto error;
	}

	battery_chg_add_debugfs(bcdev);
	battery_chg_notify_enable(bcdev);

	return 0;
@@ -1157,6 +1200,7 @@ static int battery_chg_remove(struct platform_device *pdev)
	struct battery_chg_dev *bcdev = platform_get_drvdata(pdev);
	int rc;

	debugfs_remove_recursive(bcdev->debugfs_dir);
	class_unregister(&bcdev->battery_class);
	rc = pmic_glink_unregister_client(bcdev->client);
	if (rc < 0) {