power: supply: qti_battery_charger: Disable notifications while in sleep
Currently during fast charging, charger FW on ADSP sends battery power supply notifications to HLOS even while in sleep. These notifications cause HLOS to come out of sleep to process the request. This is not needed as display is OFF and any change in battery status will not be updated on screen. Add panel event notifiers to receive notifications from display FW so that power supply notifications from the charger FW can be disabled when the panel is turned off and re-enabled when the panel is on. Change-Id: Ibf9e688f1571fd40ca18a1155fce95efd039690b Signed-off-by: Anjelique Melendez <quic_amelende@quicinc.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "BATTERY_CHG: %s: " fmt, __func__
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/soc/qcom/pmic_glink.h>
|
||||
#include <linux/soc/qcom/battery_charger.h>
|
||||
#include <linux/soc/qcom/panel_event_notifier.h>
|
||||
|
||||
#define MSG_OWNER_BC 32778
|
||||
#define MSG_TYPE_REQ_RESP 1
|
||||
@@ -28,6 +29,7 @@
|
||||
|
||||
/* opcode for battery charger */
|
||||
#define BC_SET_NOTIFY_REQ 0x04
|
||||
#define BC_DISABLE_NOTIFY_REQ 0x05
|
||||
#define BC_NOTIFY_IND 0x07
|
||||
#define BC_BATTERY_STATUS_GET 0x30
|
||||
#define BC_BATTERY_STATUS_SET 0x31
|
||||
@@ -223,6 +225,7 @@ struct battery_chg_dev {
|
||||
struct completion fw_update_ack;
|
||||
struct psy_state psy_list[PSY_TYPE_MAX];
|
||||
struct dentry *debugfs_dir;
|
||||
void *notifier_cookie;
|
||||
u32 *thermal_levels;
|
||||
const char *wls_fw_name;
|
||||
int curr_thermal_level;
|
||||
@@ -249,6 +252,7 @@ struct battery_chg_dev {
|
||||
bool restrict_chg_en;
|
||||
/* To track the driver initialization status */
|
||||
bool initialized;
|
||||
bool notify_en;
|
||||
};
|
||||
|
||||
static const int battery_prop_map[BATT_PROP_MAX] = {
|
||||
@@ -420,19 +424,42 @@ static int get_property_id(struct psy_state *pst,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void battery_chg_notify_disable(struct battery_chg_dev *bcdev)
|
||||
{
|
||||
struct battery_charger_set_notify_msg req_msg = { { 0 } };
|
||||
int rc;
|
||||
|
||||
if (bcdev->notify_en) {
|
||||
/* Send request to disable notification */
|
||||
req_msg.hdr.owner = MSG_OWNER_BC;
|
||||
req_msg.hdr.type = MSG_TYPE_NOTIFY;
|
||||
req_msg.hdr.opcode = BC_DISABLE_NOTIFY_REQ;
|
||||
|
||||
rc = battery_chg_write(bcdev, &req_msg, sizeof(req_msg));
|
||||
if (rc < 0)
|
||||
pr_err("Failed to disable notification rc=%d\n", rc);
|
||||
else
|
||||
bcdev->notify_en = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void battery_chg_notify_enable(struct battery_chg_dev *bcdev)
|
||||
{
|
||||
struct battery_charger_set_notify_msg req_msg = { { 0 } };
|
||||
int rc;
|
||||
|
||||
/* Send request to enable notification */
|
||||
req_msg.hdr.owner = MSG_OWNER_BC;
|
||||
req_msg.hdr.type = MSG_TYPE_NOTIFY;
|
||||
req_msg.hdr.opcode = BC_SET_NOTIFY_REQ;
|
||||
if (!bcdev->notify_en) {
|
||||
/* Send request to enable notification */
|
||||
req_msg.hdr.owner = MSG_OWNER_BC;
|
||||
req_msg.hdr.type = MSG_TYPE_NOTIFY;
|
||||
req_msg.hdr.opcode = BC_SET_NOTIFY_REQ;
|
||||
|
||||
rc = battery_chg_write(bcdev, &req_msg, sizeof(req_msg));
|
||||
if (rc < 0)
|
||||
pr_err("Failed to enable notification rc=%d\n", rc);
|
||||
rc = battery_chg_write(bcdev, &req_msg, sizeof(req_msg));
|
||||
if (rc < 0)
|
||||
pr_err("Failed to enable notification rc=%d\n", rc);
|
||||
else
|
||||
bcdev->notify_en = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void battery_chg_state_cb(void *priv, enum pmic_glink_state state)
|
||||
@@ -444,6 +471,8 @@ static void battery_chg_state_cb(void *priv, enum pmic_glink_state state)
|
||||
atomic_set(&bcdev->state, state);
|
||||
if (state == PMIC_GLINK_STATE_UP)
|
||||
schedule_work(&bcdev->subsys_up_work);
|
||||
else if (state == PMIC_GLINK_STATE_DOWN)
|
||||
bcdev->notify_en = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -574,6 +603,7 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data,
|
||||
|
||||
break;
|
||||
case BC_SET_NOTIFY_REQ:
|
||||
case BC_DISABLE_NOTIFY_REQ:
|
||||
case BC_SHUTDOWN_NOTIFY:
|
||||
case BC_SHIP_MODE_REQ_SET:
|
||||
/* Always ACK response for notify or ship_mode request */
|
||||
@@ -1971,6 +2001,79 @@ static int battery_chg_ship_mode(struct notifier_block *nb, unsigned long code,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static void panel_event_notifier_callback(enum panel_event_notifier_tag tag,
|
||||
struct panel_event_notification *notification, void *data)
|
||||
{
|
||||
struct battery_chg_dev *bcdev = data;
|
||||
|
||||
if (!notification) {
|
||||
pr_debug("Invalid panel notification\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("panel event received, type: %d\n", notification->notif_type);
|
||||
switch (notification->notif_type) {
|
||||
case DRM_PANEL_EVENT_BLANK:
|
||||
battery_chg_notify_disable(bcdev);
|
||||
break;
|
||||
case DRM_PANEL_EVENT_UNBLANK:
|
||||
battery_chg_notify_enable(bcdev);
|
||||
break;
|
||||
default:
|
||||
pr_debug("Ignore panel event: %d\n", notification->notif_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int battery_chg_register_panel_notifier(struct battery_chg_dev *bcdev)
|
||||
{
|
||||
struct device_node *np = bcdev->dev->of_node;
|
||||
struct device_node *pnode;
|
||||
struct drm_panel *panel, *active_panel = NULL;
|
||||
void *cookie = NULL;
|
||||
int i, count, rc;
|
||||
|
||||
count = of_count_phandle_with_args(np, "qcom,display-panels", NULL);
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pnode = of_parse_phandle(np, "qcom,display-panels", i);
|
||||
if (!pnode)
|
||||
return -ENODEV;
|
||||
|
||||
panel = of_drm_find_panel(pnode);
|
||||
of_node_put(pnode);
|
||||
if (!IS_ERR(panel)) {
|
||||
active_panel = panel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!active_panel) {
|
||||
rc = PTR_ERR(panel);
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dev_err(bcdev->dev, "Failed to find active panel, rc=%d\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
cookie = panel_event_notifier_register(
|
||||
PANEL_EVENT_NOTIFICATION_PRIMARY,
|
||||
PANEL_EVENT_NOTIFIER_CLIENT_BATTERY_CHARGER,
|
||||
active_panel,
|
||||
panel_event_notifier_callback,
|
||||
(void *)bcdev);
|
||||
if (IS_ERR(cookie)) {
|
||||
rc = PTR_ERR(cookie);
|
||||
dev_err(bcdev->dev, "Failed to register panel event notifier, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
pr_debug("register panel notifier successful\n");
|
||||
bcdev->notifier_cookie = cookie;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int battery_chg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct battery_chg_dev *bcdev;
|
||||
@@ -2044,6 +2147,10 @@ static int battery_chg_probe(struct platform_device *pdev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = battery_chg_register_panel_notifier(bcdev);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA;
|
||||
platform_set_drvdata(pdev, bcdev);
|
||||
bcdev->fake_soc = -EINVAL;
|
||||
@@ -2061,6 +2168,7 @@ static int battery_chg_probe(struct platform_device *pdev)
|
||||
|
||||
bcdev->wls_fw_update_time_ms = WLS_FW_UPDATE_TIME_MS;
|
||||
battery_chg_add_debugfs(bcdev);
|
||||
bcdev->notify_en = false;
|
||||
battery_chg_notify_enable(bcdev);
|
||||
device_init_wakeup(bcdev->dev, true);
|
||||
schedule_work(&bcdev->usb_type_work);
|
||||
@@ -2079,6 +2187,9 @@ static int battery_chg_remove(struct platform_device *pdev)
|
||||
struct battery_chg_dev *bcdev = platform_get_drvdata(pdev);
|
||||
int rc;
|
||||
|
||||
if (bcdev->notifier_cookie)
|
||||
panel_event_notifier_unregister(bcdev->notifier_cookie);
|
||||
|
||||
device_init_wakeup(bcdev->dev, false);
|
||||
debugfs_remove_recursive(bcdev->debugfs_dir);
|
||||
class_unregister(&bcdev->battery_class);
|
||||
|
||||
Reference in New Issue
Block a user