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: Guru Das Srinagesh <gurus@codeaurora.org>
This commit is contained in:
Guru Das Srinagesh 2020-04-03 18:50:55 -07:00 committed by Anjelique Melendez
parent 6dcf0f0f24
commit 70b2ee4bf0

View File

@ -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) {