From b349afa64551b8de4bb0de5343ebac2aa15395cc Mon Sep 17 00:00:00 2001 From: Kamal Wadhwa Date: Thu, 12 Oct 2023 20:24:18 +0530 Subject: [PATCH] power: supply: qti_battery_charger: fix charge control logic during reboot In current design, when 'charge_control_en' sysfs is written, the structure variable value is updated with this new value. Read to this sysfs node will only return this structure variable value. However, this can cause issue, if the device rebooted after 'charge_control_en' is set '1', because the structure variable is '0' after reboot, and so reading to 'charge_control_en' also returns '0', even though value set in the HW is still '1'. Fix this by reading actual HW value via charger firmware on reboot and sysfs read. Change-Id: I41225765c22dfe20ef3d55b3353d47b2dd9a772e Signed-off-by: Kamal Wadhwa --- drivers/power/supply/qti_battery_charger.c | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qti_battery_charger.c b/drivers/power/supply/qti_battery_charger.c index eed9b7122032..3cca0f0df6d9 100644 --- a/drivers/power/supply/qti_battery_charger.c +++ b/drivers/power/supply/qti_battery_charger.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "BATTERY_CHG: %s: " fmt, __func__ @@ -1213,6 +1213,21 @@ static int battery_psy_set_charge_start_threshold(struct battery_chg_dev *bcdev, return rc; } +static int get_charge_control_en(struct battery_chg_dev *bcdev) +{ + int rc; + + rc = read_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], + BATT_CHG_CTRL_EN); + if (rc < 0) + pr_err("Failed to read the CHG_CTRL_EN, rc = %d\n", rc); + else + bcdev->chg_ctrl_en = + bcdev->psy_list[PSY_TYPE_BATTERY].prop[BATT_CHG_CTRL_EN]; + + return rc; +} + static int __battery_psy_set_charge_current(struct battery_chg_dev *bcdev, u32 fcc_ua) { @@ -1789,6 +1804,11 @@ static ssize_t charge_control_en_show(struct class *c, { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); + int rc; + + rc = get_charge_control_en(bcdev); + if (rc < 0) + return rc; return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->chg_ctrl_en); } @@ -2409,6 +2429,10 @@ static int battery_chg_probe(struct platform_device *pdev) device_init_wakeup(bcdev->dev, true); schedule_work(&bcdev->usb_type_work); + rc = get_charge_control_en(bcdev); + if (rc < 0) + pr_debug("Failed to read charge_control_en, rc = %d\n", rc); + return 0; error: cancel_work_sync(&bcdev->subsys_up_work);