From d290ee1e63164e6a3ce9bb606be5a50f5212750d Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Wed, 22 Mar 2017 18:07:31 -0600 Subject: [PATCH 1/3] power_supply: Use of-thermal cdev registration API With thermal frameworks of-thermal interface, thermal zone parameters can be defined in devicetree. This includes cooling device mitigation levels for a thermal zone. To take advantage of this, cooling device should use the thermal_of_cooling_device_register API to register a cooling device. Use thermal_of_cooling_device_register API to register the power supply cooling device. This enables power supply cooling device be included in the thermal zone parameter in devicetree. Change-Id: I27d6043cf1d3121d97f8300bb89635204ae32955 Signed-off-by: Ram Chandrasekar --- drivers/power/supply/power_supply_core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 5c36c430ce8b..dc660df5d736 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -947,7 +947,7 @@ static const struct thermal_cooling_device_ops psy_tcd_ops = { .set_cur_state = ps_set_cur_charge_cntl_limit, }; -static int psy_register_cooler(struct power_supply *psy) +static int psy_register_cooler(struct device *dev, struct power_supply *psy) { int i; @@ -955,7 +955,13 @@ static int psy_register_cooler(struct power_supply *psy) for (i = 0; i < psy->desc->num_properties; i++) { if (psy->desc->properties[i] == POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) { - psy->tcd = thermal_cooling_device_register( + if (dev) + psy->tcd = thermal_of_cooling_device_register( + dev_of_node(dev), + (char *)psy->desc->name, + psy, &psy_tcd_ops); + else + psy->tcd = thermal_cooling_device_register( (char *)psy->desc->name, psy, &psy_tcd_ops); return PTR_ERR_OR_ZERO(psy->tcd); @@ -980,7 +986,7 @@ static void psy_unregister_thermal(struct power_supply *psy) { } -static int psy_register_cooler(struct power_supply *psy) +static int psy_register_cooler(struct device *dev, struct power_supply *psy) { return 0; } @@ -1063,7 +1069,7 @@ __power_supply_register(struct device *parent, if (rc) goto register_thermal_failed; - rc = psy_register_cooler(psy); + rc = psy_register_cooler(parent, psy); if (rc) goto register_cooler_failed; From fe7d188ad17f6e07ff7f2bcac063e88d8a9bad3c Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Fri, 28 Feb 2020 09:28:21 -0800 Subject: [PATCH 2/3] driver: thermal: bcl_pmic5: Register vbat only when enabled Vbat in BCL peripheral can be disabled by default depending on the PMIC configuration. In those cases, registering vbat sensor will read 0 Volt always. Before registering the vbat sensor, check if the vbat ADC measurement is enabled in the hardware. If not, skip the registration of vbat sensor. Change-Id: Ic937201349a505825615a412bdbbfb7348b30689 Signed-off-by: Ram Chandrasekar --- drivers/thermal/qcom/bcl_pmic5.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/qcom/bcl_pmic5.c b/drivers/thermal/qcom/bcl_pmic5.c index 7c6d27167782..f44dad55b7f1 100644 --- a/drivers/thermal/qcom/bcl_pmic5.c +++ b/drivers/thermal/qcom/bcl_pmic5.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__ @@ -34,6 +34,7 @@ #define BCL_VBAT_ADC_LOW 0x48 #define BCL_VBAT_COMP_LOW 0x49 #define BCL_VBAT_COMP_TLOW 0x4A +#define BCL_VBAT_CONV_REQ 0x72 #define BCL_IRQ_L0 0x1 #define BCL_IRQ_L1 0x2 @@ -503,11 +504,17 @@ static void bcl_vbat_init(struct platform_device *pdev, enum bcl_dev_type type, struct bcl_device *bcl_perph) { struct bcl_peripheral_data *vbat = &bcl_perph->param[type]; + unsigned int val = 0; + int ret; mutex_init(&vbat->state_trans_lock); vbat->dev = bcl_perph; vbat->irq_num = 0; vbat->irq_enabled = false; + vbat->tz_dev = NULL; + ret = bcl_read_register(bcl_perph, BCL_VBAT_CONV_REQ, &val); + if (ret || !val) + return; vbat->tz_dev = thermal_zone_device_register("vbat", 3, 0, vbat, &vbat_tzd_ops, &vbat_tzp, 0, 0); if (IS_ERR(vbat->tz_dev)) { From 9e2415b0ae9442fcfeabc36763183cfd17891871 Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Fri, 28 Feb 2020 09:35:47 -0800 Subject: [PATCH 3/3] drivers: thermal: bcl_soc: Read charge depletion percentage soc driver is used to read percentage of charge left on the battery, which will require the thermal framework to monitor the value falling below a threshold. This support is not natively available. soc driver will read the charge depletion percentage, which will indicate the percentage of charge depleted in the battery. This can use the native trip threshold monitoring functionality of thermal framework. Change-Id: I8c332910c08df2573ab564be96b82c642ac7701e Signed-off-by: Ram Chandrasekar --- drivers/thermal/qcom/bcl_soc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/thermal/qcom/bcl_soc.c b/drivers/thermal/qcom/bcl_soc.c index bce7ebeb33b9..71e04377fe78 100644 --- a/drivers/thermal/qcom/bcl_soc.c +++ b/drivers/thermal/qcom/bcl_soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__ @@ -36,13 +36,13 @@ static struct bcl_device *bcl_perph; static int bcl_set_soc(void *data, int low, int high) { - if (low == bcl_perph->trip_temp) + if (high == bcl_perph->trip_temp) return 0; mutex_lock(&bcl_perph->state_trans_lock); - pr_debug("low soc threshold:%d\n", low); - bcl_perph->trip_temp = low; - if (low == INT_MIN) { + pr_debug("socd threshold:%d\n", high); + bcl_perph->trip_temp = high; + if (high == INT_MAX) { bcl_perph->irq_enabled = false; goto unlock_and_exit; } @@ -60,7 +60,7 @@ static int bcl_read_soc(void *data, int *val) union power_supply_propval ret = {0,}; int err = 0; - *val = 100; + *val = 0; if (!batt_psy) batt_psy = power_supply_get_by_name("battery"); if (batt_psy) { @@ -71,7 +71,7 @@ static int bcl_read_soc(void *data, int *val) err); return err; } - *val = ret.intval; + *val = 100 - ret.intval; } pr_debug("soc:%d\n", *val); @@ -80,21 +80,21 @@ static int bcl_read_soc(void *data, int *val) static void bcl_evaluate_soc(struct work_struct *work) { - int battery_percentage; + int battery_depletion; if (!bcl_perph->tz_dev) return; - if (bcl_read_soc(NULL, &battery_percentage)) + if (bcl_read_soc(NULL, &battery_depletion)) return; mutex_lock(&bcl_perph->state_trans_lock); if (!bcl_perph->irq_enabled) goto eval_exit; - if (battery_percentage > bcl_perph->trip_temp) + if (battery_depletion < bcl_perph->trip_temp) goto eval_exit; - bcl_perph->trip_val = battery_percentage; + bcl_perph->trip_val = battery_depletion; mutex_unlock(&bcl_perph->state_trans_lock); of_thermal_handle_trip_temp(bcl_perph->dev, bcl_perph->tz_dev, bcl_perph->trip_val);