diff options
Diffstat (limited to 'drivers/thermal')
68 files changed, 1261 insertions, 594 deletions
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index eed300e83d48..058664bc3ec0 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -2,7 +2,7 @@ # # Makefile for sensor chip drivers. # - +CFLAGS_thermal_core.o := -I$(src) obj-$(CONFIG_THERMAL) += thermal_sys.o thermal_sys-y += thermal_core.o thermal_sysfs.o thermal_sys-y += thermal_trip.o thermal_helpers.o @@ -16,6 +16,7 @@ thermal_sys-$(CONFIG_THERMAL_OF) += thermal_of.o thermal_sys-$(CONFIG_THERMAL_ACPI) += thermal_acpi.o # governors +CFLAGS_gov_power_allocator.o := -I$(src) thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += gov_fair_share.o thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += gov_step_wise.o diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c index 9235fda4ec1e..3abc2dcef408 100644 --- a/drivers/thermal/amlogic_thermal.c +++ b/drivers/thermal/amlogic_thermal.c @@ -181,7 +181,7 @@ static int amlogic_thermal_disable(struct amlogic_thermal *data) static int amlogic_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { unsigned int tval; - struct amlogic_thermal *pdata = tz->devdata; + struct amlogic_thermal *pdata = thermal_zone_device_priv(tz); if (!pdata) return -EINVAL; @@ -262,11 +262,8 @@ static int amlogic_thermal_probe(struct platform_device *pdev) return PTR_ERR(pdata->regmap); pdata->clk = devm_clk_get(dev, NULL); - if (IS_ERR(pdata->clk)) { - if (PTR_ERR(pdata->clk) != -EPROBE_DEFER) - dev_err(dev, "failed to get clock\n"); - return PTR_ERR(pdata->clk); - } + if (IS_ERR(pdata->clk)) + return dev_err_probe(dev, PTR_ERR(pdata->clk), "failed to get clock\n"); pdata->sec_ao_map = syscon_regmap_lookup_by_phandle (pdev->dev.of_node, "amlogic,ao-secure"); @@ -285,7 +282,7 @@ static int amlogic_thermal_probe(struct platform_device *pdev) return ret; } - if (devm_thermal_add_hwmon_sysfs(pdata->tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd)) dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n"); ret = amlogic_thermal_initialize(pdata); diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 2efc222a379b..0e8dfa6a7757 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -360,11 +360,8 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel) * we must absolutely wait for the sensor validity bit to ensure we read * actual data. */ - if (armada_wait_sensor_validity(priv)) { - dev_err(priv->dev, - "Temperature sensor reading not valid\n"); + if (armada_wait_sensor_validity(priv)) return -EIO; - } return 0; } @@ -398,15 +395,12 @@ static int armada_read_sensor(struct armada_thermal_priv *priv, int *temp) static int armada_get_temp_legacy(struct thermal_zone_device *thermal, int *temp) { - struct armada_thermal_priv *priv = thermal->devdata; + struct armada_thermal_priv *priv = thermal_zone_device_priv(thermal); int ret; /* Valid check */ - if (!armada_is_valid(priv)) { - dev_err(priv->dev, - "Temperature sensor reading not valid\n"); + if (!armada_is_valid(priv)) return -EIO; - } /* Do the actual reading */ ret = armada_read_sensor(priv, temp); @@ -420,7 +414,7 @@ static struct thermal_zone_device_ops legacy_ops = { static int armada_get_temp(struct thermal_zone_device *tz, int *temp) { - struct armada_thermal_sensor *sensor = tz->devdata; + struct armada_thermal_sensor *sensor = thermal_zone_device_priv(tz); struct armada_thermal_priv *priv = sensor->priv; int ret; diff --git a/drivers/thermal/broadcom/bcm2711_thermal.c b/drivers/thermal/broadcom/bcm2711_thermal.c index 1f8651d15160..c243a76a3471 100644 --- a/drivers/thermal/broadcom/bcm2711_thermal.c +++ b/drivers/thermal/broadcom/bcm2711_thermal.c @@ -33,7 +33,7 @@ struct bcm2711_thermal_priv { static int bcm2711_get_temp(struct thermal_zone_device *tz, int *temp) { - struct bcm2711_thermal_priv *priv = tz->devdata; + struct bcm2711_thermal_priv *priv = thermal_zone_device_priv(tz); int slope = thermal_zone_get_slope(tz); int offset = thermal_zone_get_offset(tz); u32 val; @@ -98,7 +98,6 @@ static int bcm2711_thermal_probe(struct platform_device *pdev) priv->thermal = thermal; - thermal->tzp->no_hwmon = false; return thermal_add_hwmon_sysfs(thermal); } diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 23918bb76ae6..3acc9288b310 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -90,7 +90,7 @@ static int bcm2835_thermal_temp2adc(int temp, int offset, int slope) static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct bcm2835_thermal_data *data = tz->devdata; + struct bcm2835_thermal_data *data = thermal_zone_device_priv(tz); u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT); if (!(val & BCM2835_TS_TSENSSTAT_VALID)) @@ -267,7 +267,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) * Thermal_zone doesn't enable hwmon as default, * enable it here */ - tz->tzp->no_hwmon = false; err = thermal_add_hwmon_sysfs(tz); if (err) goto err_tz; @@ -276,7 +275,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) return 0; err_tz: - thermal_of_zone_unregister(tz); + devm_thermal_of_zone_unregister(&pdev->dev, tz); err_clk: clk_disable_unprepare(data->clk); @@ -286,10 +285,8 @@ err_clk: static int bcm2835_thermal_remove(struct platform_device *pdev) { struct bcm2835_thermal_data *data = platform_get_drvdata(pdev); - struct thermal_zone_device *tz = data->tz; debugfs_remove_recursive(data->debugfsdir); - thermal_of_zone_unregister(tz); clk_disable_unprepare(data->clk); return 0; diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c index 4d02c28331e3..72d1dbe60b8f 100644 --- a/drivers/thermal/broadcom/brcmstb_thermal.c +++ b/drivers/thermal/broadcom/brcmstb_thermal.c @@ -152,16 +152,14 @@ static inline u32 avs_tmon_temp_to_code(struct brcmstb_thermal_priv *priv, static int brcmstb_get_temp(struct thermal_zone_device *tz, int *temp) { - struct brcmstb_thermal_priv *priv = tz->devdata; + struct brcmstb_thermal_priv *priv = thermal_zone_device_priv(tz); u32 val; long t; val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS); - if (!(val & AVS_TMON_STATUS_valid_msk)) { - dev_err(priv->dev, "reading not valid\n"); + if (!(val & AVS_TMON_STATUS_valid_msk)) return -EIO; - } val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; @@ -262,7 +260,7 @@ static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data) static int brcmstb_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct brcmstb_thermal_priv *priv = tz->devdata; + struct brcmstb_thermal_priv *priv = thermal_zone_device_priv(tz); dev_dbg(priv->dev, "set trips %d <--> %d\n", low, high); diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c index 07a8a3f49bd0..d255aa879fc0 100644 --- a/drivers/thermal/broadcom/ns-thermal.c +++ b/drivers/thermal/broadcom/ns-thermal.c @@ -16,7 +16,7 @@ static int ns_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - void __iomem *pvtmon = tz->devdata; + void __iomem *pvtmon = thermal_zone_device_priv(tz); int offset = thermal_zone_get_offset(tz); int slope = thermal_zone_get_slope(tz); u32 val; diff --git a/drivers/thermal/broadcom/sr-thermal.c b/drivers/thermal/broadcom/sr-thermal.c index 2b93502543ff..747915890022 100644 --- a/drivers/thermal/broadcom/sr-thermal.c +++ b/drivers/thermal/broadcom/sr-thermal.c @@ -32,7 +32,7 @@ struct sr_thermal { static int sr_get_temp(struct thermal_zone_device *tz, int *temp) { - struct sr_tmon *tmon = tz->devdata; + struct sr_tmon *tmon = thermal_zone_device_priv(tz); struct sr_thermal *sr_thermal = tmon->priv; *temp = readl(sr_thermal->regs + SR_TMON_TEMP_BASE(tmon->tmon_id)); diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 9f8b438fcf8f..e2cc7bd30862 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -23,7 +23,7 @@ #include <linux/thermal.h> #include <linux/units.h> -#include <trace/events/thermal.h> +#include "thermal_trace.h" /* * Cooling state <-> CPUFreq frequency @@ -633,7 +633,7 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) return NULL; } - if (of_find_property(np, "#cooling-cells", NULL)) { + if (of_property_present(np, "#cooling-cells")) { struct em_perf_domain *em = em_cpu_get(policy->cpu); cdev = __cpufreq_cooling_register(np, policy, em); diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c index a805a6666c44..2d31b1f73423 100644 --- a/drivers/thermal/da9062-thermal.c +++ b/drivers/thermal/da9062-thermal.c @@ -41,6 +41,8 @@ #define DA9062_MILLI_CELSIUS(t) ((t) * 1000) +static unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD; + struct da9062_thermal_config { const char *name; }; @@ -95,7 +97,10 @@ static void da9062_thermal_poll_on(struct work_struct *work) thermal_zone_device_update(thermal->zone, THERMAL_EVENT_UNSPECIFIED); - delay = thermal->zone->passive_delay_jiffies; + /* + * pp_tmp is between 1s and 10s, so we can round the jiffies + */ + delay = round_jiffies(msecs_to_jiffies(pp_tmp)); queue_delayed_work(system_freezable_wq, &thermal->work, delay); return; } @@ -123,7 +128,7 @@ static irqreturn_t da9062_thermal_irq_handler(int irq, void *data) static int da9062_thermal_get_temp(struct thermal_zone_device *z, int *temp) { - struct da9062_thermal *thermal = z->devdata; + struct da9062_thermal *thermal = thermal_zone_device_priv(z); mutex_lock(&thermal->lock); *temp = thermal->temperature; @@ -155,7 +160,6 @@ static int da9062_thermal_probe(struct platform_device *pdev) { struct da9062 *chip = dev_get_drvdata(pdev->dev.parent); struct da9062_thermal *thermal; - unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD; const struct of_device_id *match; int ret = 0; @@ -208,8 +212,7 @@ static int da9062_thermal_probe(struct platform_device *pdev) } dev_dbg(&pdev->dev, - "TJUNC temperature polling period set at %d ms\n", - jiffies_to_msecs(thermal->zone->passive_delay_jiffies)); + "TJUNC temperature polling period set at %d ms\n", pp_tmp); ret = platform_get_irq_byname(pdev, "THERMAL"); if (ret < 0) diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c index cb10e280681f..fca5c2c93bf9 100644 --- a/drivers/thermal/db8500_thermal.c +++ b/drivers/thermal/db8500_thermal.c @@ -53,6 +53,7 @@ static const unsigned long db8500_thermal_points[] = { struct db8500_thermal_zone { struct thermal_zone_device *tz; + struct device *dev; unsigned long interpolated_temp; unsigned int cur_index; }; @@ -60,7 +61,7 @@ struct db8500_thermal_zone { /* Callback to get current temperature */ static int db8500_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct db8500_thermal_zone *th = tz->devdata; + struct db8500_thermal_zone *th = thermal_zone_device_priv(tz); /* * TODO: There is no PRCMU interface to get temperature data currently, @@ -114,7 +115,7 @@ static irqreturn_t prcmu_low_irq_handler(int irq, void *irq_data) idx -= 1; db8500_thermal_update_config(th, idx, next_low, next_high); - dev_dbg(&th->tz->device, + dev_dbg(th->dev, "PRCMU set max %ld, min %ld\n", next_high, next_low); thermal_zone_device_update(th->tz, THERMAL_EVENT_UNSPECIFIED); @@ -136,7 +137,7 @@ static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data) db8500_thermal_update_config(th, idx, next_low, next_high); - dev_dbg(&th->tz->device, + dev_dbg(th->dev, "PRCMU set max %ld, min %ld\n", next_high, next_low); } else if (idx == num_points - 1) /* So we roof out 1 degree over the max point */ @@ -157,6 +158,8 @@ static int db8500_thermal_probe(struct platform_device *pdev) if (!th) return -ENOMEM; + th->dev = dev; + low_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_LOW"); if (low_irq < 0) return low_irq; diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 24b474925cd6..262e62ab6cf2 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -20,7 +20,7 @@ #include <linux/thermal.h> #include <linux/units.h> -#include <trace/events/thermal.h> +#include "thermal_trace.h" #define SCALE_ERROR_MITIGATION 100 diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c index 056622a58d00..9954040d1d2c 100644 --- a/drivers/thermal/dove_thermal.c +++ b/drivers/thermal/dove_thermal.c @@ -87,15 +87,12 @@ static int dove_get_temp(struct thermal_zone_device *thermal, int *temp) { unsigned long reg; - struct dove_thermal_priv *priv = thermal->devdata; + struct dove_thermal_priv *priv = thermal_zone_device_priv(thermal); /* Valid check */ reg = readl_relaxed(priv->control + PMU_TEMP_DIOD_CTRL1_REG); - if ((reg & PMU_TDC1_TEMP_VALID_MASK) == 0x0) { - dev_err(&thermal->device, - "Temperature sensor reading not valid\n"); + if ((reg & PMU_TDC1_TEMP_VALID_MASK) == 0x0) return -EIO; - } /* * Calculate temperature. According to Marvell internal diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index aad7d5fe3a14..03c2daeb6ee8 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -11,7 +11,7 @@ */ #include <linux/thermal.h> -#include <trace/events/thermal.h> +#include "thermal_trace.h" #include "thermal_core.h" diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 0eaf1527d3e3..8642f1096b91 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -12,7 +12,7 @@ #include <linux/thermal.h> #define CREATE_TRACE_POINTS -#include <trace/events/thermal_power_allocator.h> +#include "thermal_trace_ipa.h" #include "thermal_core.h" diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c index 31235e169c5a..3d3067804df2 100644 --- a/drivers/thermal/gov_step_wise.c +++ b/drivers/thermal/gov_step_wise.c @@ -12,7 +12,7 @@ #include <linux/thermal.h> #include <linux/minmax.h> -#include <trace/events/thermal.h> +#include "thermal_trace.h" #include "thermal_core.h" diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 32a7c3cf073d..3f09ef8be41a 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -431,14 +431,11 @@ static int hi3660_thermal_probe(struct hisi_thermal_data *data) static int hisi_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct hisi_thermal_sensor *sensor = tz->devdata; + struct hisi_thermal_sensor *sensor = thermal_zone_device_priv(tz); struct hisi_thermal_data *data = sensor->data; *temp = data->ops->get_temp(sensor); - dev_dbg(&data->pdev->dev, "tzd=%p, id=%d, temp=%d, thres=%d\n", - sensor->tzd, sensor->id, *temp, sensor->thres_temp); - return 0; } @@ -547,7 +544,6 @@ static int hisi_thermal_probe(struct platform_device *pdev) { struct hisi_thermal_data *data; struct device *dev = &pdev->dev; - struct resource *res; int i, ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); @@ -558,8 +554,7 @@ static int hisi_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); data->ops = of_device_get_match_data(dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data->regs = devm_ioremap_resource(dev, res); + data->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(data->regs)) return PTR_ERR(data->regs); diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c index 72b5d6f319c1..d8005e9ec992 100644 --- a/drivers/thermal/imx8mm_thermal.c +++ b/drivers/thermal/imx8mm_thermal.c @@ -141,7 +141,7 @@ static int imx8mp_tmu_get_temp(void *data, int *temp) static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) { - struct tmu_sensor *sensor = tz->devdata; + struct tmu_sensor *sensor = thermal_zone_device_priv(tz); struct imx8mm_tmu *tmu = sensor->priv; return tmu->socdata->get_temp(sensor, temp); @@ -282,7 +282,7 @@ static int imx8mm_tmu_probe_set_calib(struct platform_device *pdev, * strongly recommended to update such old DTs to get correct * temperature compensation values for each SoC. */ - if (!of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { + if (!of_property_present(pdev->dev.of_node, "nvmem-cells")) { dev_warn(dev, "No OCOTP nvmem reference found, SoC-specific calibration not loaded. Please update your DT.\n"); return 0; @@ -343,7 +343,7 @@ static int imx8mm_tmu_probe(struct platform_device *pdev) } tmu->sensors[i].hw_id = i; - if (devm_thermal_add_hwmon_sysfs(tmu->sensors[i].tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, tmu->sensors[i].tzd)) dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c index f32e59e74623..839bb9958f60 100644 --- a/drivers/thermal/imx_sc_thermal.c +++ b/drivers/thermal/imx_sc_thermal.c @@ -46,7 +46,7 @@ static int imx_sc_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { struct imx_sc_msg_misc_get_temp msg; struct imx_sc_rpc_msg *hdr = &msg.hdr; - struct imx_sc_sensor *sensor = tz->devdata; + struct imx_sc_sensor *sensor = thermal_zone_device_priv(tz); int ret; msg.data.req.resource_id = sensor->resource_id; @@ -58,11 +58,8 @@ static int imx_sc_thermal_get_temp(struct thermal_zone_device *tz, int *temp) hdr->size = 2; ret = imx_scu_call_rpc(thermal_ipc_handle, &msg, true); - if (ret) { - dev_err(&sensor->tzd->device, "read temp sensor %d failed, ret %d\n", - sensor->resource_id, ret); + if (ret) return ret; - } *temp = msg.data.resp.celsius * 1000 + msg.data.resp.tenths * 100; @@ -119,7 +116,7 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) return ret; } - if (devm_thermal_add_hwmon_sysfs(sensor->tzd)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd)) dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index fb0d5cab70af..a94ec0a0c9dd 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -252,7 +252,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data, static int imx_get_temp(struct thermal_zone_device *tz, int *temp) { - struct imx_thermal_data *data = tz->devdata; + struct imx_thermal_data *data = thermal_zone_device_priv(tz); const struct thermal_soc_data *soc_data = data->socdata; struct regmap *map = data->tempmon; unsigned int n_meas; @@ -265,10 +265,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) regmap_read(map, soc_data->temp_data, &val); - if ((val & soc_data->temp_valid_mask) == 0) { - dev_dbg(&tz->device, "temp measurement never finished\n"); + if ((val & soc_data->temp_valid_mask) == 0) return -EAGAIN; - } n_meas = (val & soc_data->temp_value_mask) >> soc_data->temp_value_shift; @@ -287,13 +285,13 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) if (data->alarm_temp == trips[IMX_TRIP_CRITICAL].temperature && *temp < trips[IMX_TRIP_PASSIVE].temperature) { imx_set_alarm_temp(data, trips[IMX_TRIP_PASSIVE].temperature); - dev_dbg(&tz->device, "thermal alarm off: T < %d\n", + dev_dbg(data->dev, "thermal alarm off: T < %d\n", data->alarm_temp / 1000); } } if (*temp != data->last_temp) { - dev_dbg(&tz->device, "millicelsius: %d\n", *temp); + dev_dbg(data->dev, "millicelsius: %d\n", *temp); data->last_temp = *temp; } @@ -311,7 +309,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) static int imx_change_mode(struct thermal_zone_device *tz, enum thermal_device_mode mode) { - struct imx_thermal_data *data = tz->devdata; + struct imx_thermal_data *data = thermal_zone_device_priv(tz); if (mode == THERMAL_DEVICE_ENABLED) { pm_runtime_get(data->dev); @@ -332,33 +330,29 @@ static int imx_change_mode(struct thermal_zone_device *tz, return 0; } -static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp) -{ - *temp = trips[IMX_TRIP_CRITICAL].temperature; - - return 0; -} - -static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, +static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { - struct imx_thermal_data *data = tz->devdata; + struct imx_thermal_data *data = thermal_zone_device_priv(tz); + struct thermal_trip trip; int ret; ret = pm_runtime_resume_and_get(data->dev); if (ret < 0) return ret; + ret = __thermal_zone_get_trip(tz, trip_id, &trip); + if (ret) + return ret; + /* do not allow changing critical threshold */ - if (trip == IMX_TRIP_CRITICAL) + if (trip.type == THERMAL_TRIP_CRITICAL) return -EPERM; /* do not allow passive to be set higher than critical */ if (temp < 0 || temp > trips[IMX_TRIP_CRITICAL].temperature) return -EINVAL; - trips[IMX_TRIP_PASSIVE].temperature = temp; - imx_set_alarm_temp(data, temp); pm_runtime_put(data->dev); @@ -369,36 +363,16 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, static int imx_bind(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev) { - int ret; - - ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev, - THERMAL_NO_LIMIT, - THERMAL_NO_LIMIT, - THERMAL_WEIGHT_DEFAULT); - if (ret) { - dev_err(&tz->device, - "binding zone %s with cdev %s failed:%d\n", - tz->type, cdev->type, ret); - return ret; - } - - return 0; + return thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev, + THERMAL_NO_LIMIT, + THERMAL_NO_LIMIT, + THERMAL_WEIGHT_DEFAULT); } static int imx_unbind(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev) { - int ret; - - ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev); - if (ret) { - dev_err(&tz->device, - "unbinding zone %s with cdev %s failed:%d\n", - tz->type, cdev->type, ret); - return ret; - } - - return 0; + return thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev); } static struct thermal_zone_device_ops imx_tz_ops = { @@ -406,7 +380,6 @@ static struct thermal_zone_device_ops imx_tz_ops = { .unbind = imx_unbind, .get_temp = imx_get_temp, .change_mode = imx_change_mode, - .get_crit_temp = imx_get_crit_temp, .set_trip_temp = imx_set_trip_temp, }; @@ -560,8 +533,7 @@ static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev) { struct imx_thermal_data *data = dev; - dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n", - data->alarm_temp / 1000); + dev_dbg(data->dev, "THERMAL ALARM: T > %d\n", data->alarm_temp / 1000); thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED); @@ -594,7 +566,7 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) np = of_get_cpu_node(data->policy->cpu, NULL); - if (!np || !of_find_property(np, "#cooling-cells", NULL)) { + if (!np || !of_property_present(np, "#cooling-cells")) { data->cdev = cpufreq_cooling_register(data->policy); if (IS_ERR(data->cdev)) { ret = PTR_ERR(data->cdev); @@ -671,7 +643,7 @@ static int imx_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - if (of_find_property(pdev->dev.of_node, "nvmem-cells", NULL)) { + if (of_property_present(pdev->dev.of_node, "nvmem-cells")) { ret = imx_init_from_nvmem_cells(pdev); if (ret) return dev_err_probe(&pdev->dev, ret, diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index d0295123cc3e..810231b59dcd 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -497,7 +497,7 @@ static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, static int int3400_thermal_change_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode) { - struct int3400_thermal_priv *priv = thermal->devdata; + struct int3400_thermal_priv *priv = thermal_zone_device_priv(thermal); int result = 0; if (!priv) diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 00665967ca52..89cf007146ea 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -14,7 +14,7 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, int *temp) { - struct int34x_thermal_zone *d = zone->devdata; + struct int34x_thermal_zone *d = thermal_zone_device_priv(zone); unsigned long long tmp; acpi_status status; @@ -41,7 +41,7 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, int trip, int temp) { - struct int34x_thermal_zone *d = zone->devdata; + struct int34x_thermal_zone *d = thermal_zone_device_priv(zone); char name[] = {'P', 'A', 'T', '0' + trip, '\0'}; acpi_status status; diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index a1dc18be7609..3ca0a2f5937f 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -337,7 +337,8 @@ int proc_thermal_mmio_add(struct pci_dev *pdev, } if (feature_mask & PROC_THERMAL_FEATURE_FIVR || - feature_mask & PROC_THERMAL_FEATURE_DVFS) { + feature_mask & PROC_THERMAL_FEATURE_DVFS || + feature_mask & PROC_THERMAL_FEATURE_DLVR) { ret = proc_thermal_rfim_add(pdev, proc_priv); if (ret) { dev_err(&pdev->dev, "failed to add RFIM interface\n"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h index 7d52fcff4937..7acaa8f1b896 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h @@ -60,6 +60,7 @@ struct rapl_mmio_regs { #define PROC_THERMAL_FEATURE_FIVR 0x02 #define PROC_THERMAL_FEATURE_DVFS 0x04 #define PROC_THERMAL_FEATURE_MBOX 0x08 +#define PROC_THERMAL_FEATURE_DLVR 0x10 #if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL) int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c index 40725cbc6eb0..0d1e98007270 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -135,7 +135,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) { - struct proc_thermal_pci *pci_info = tzd->devdata; + struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd); u32 _temp; proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_PKG_TEMP, &_temp); @@ -146,14 +146,13 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { - struct proc_thermal_pci *pci_info = tzd->devdata; + struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd); int tjmax, _temp; if (temp <= 0) { cancel_delayed_work_sync(&pci_info->work); proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0); proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0); - thermal_zone_device_disable(tzd); pci_info->stored_thres = 0; return 0; } @@ -166,7 +165,6 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, _temp); proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 1); - thermal_zone_device_enable(tzd); pci_info->stored_thres = temp; return 0; @@ -268,6 +266,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ goto err_free_vectors; } + ret = thermal_zone_device_enable(pci_info->tzone); + if (ret) + goto err_free_vectors; + return 0; err_free_vectors: @@ -349,7 +351,7 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend, static const struct pci_device_id proc_thermal_pci_ids[] = { { PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) }, - { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) }, + { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX | PROC_THERMAL_FEATURE_DLVR) }, { PCI_DEVICE_DATA(INTEL, RPL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_MBOX) }, { }, }; diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index 92ed1213fe37..546b70434004 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -39,6 +39,29 @@ static const struct mmio_reg tgl_fivr_mmio_regs[] = { { 1, 0x5A14, 2, 0x3, 1}, /* fivr_fffc_rev */ }; +static const char * const dlvr_strings[] = { + "dlvr_spread_spectrum_pct", + "dlvr_control_mode", + "dlvr_control_lock", + "dlvr_rfim_enable", + "dlvr_freq_select", + "dlvr_hardware_rev", + "dlvr_freq_mhz", + "dlvr_pll_busy", + NULL +}; + +static const struct mmio_reg dlvr_mmio_regs[] = { + { 0, 0x15A08, 5, 0x1F, 0}, /* dlvr_spread_spectrum_pct */ + { 0, 0x15A08, 1, 0x1, 5}, /* dlvr_control_mode */ + { 0, 0x15A08, 1, 0x1, 6}, /* dlvr_control_lock */ + { 0, 0x15A08, 1, 0x1, 7}, /* dlvr_rfim_enable */ + { 0, 0x15A08, 12, 0xFFF, 8}, /* dlvr_freq_select */ + { 1, 0x15A10, 2, 0x3, 30}, /* dlvr_hardware_rev */ + { 1, 0x15A10, 16, 0xFFFF, 0}, /* dlvr_freq_mhz */ + { 1, 0x15A10, 1, 0x1, 16}, /* dlvr_pll_busy */ +}; + /* These will represent sysfs attribute names */ static const char * const dvfs_strings[] = { "rfi_restriction_run_busy", @@ -78,14 +101,16 @@ static ssize_t suffix##_show(struct device *dev,\ int ret;\ \ proc_priv = pci_get_drvdata(pdev);\ - if (table) {\ + if (table == 1) {\ match_strs = (const char **)dvfs_strings;\ mmio_regs = adl_dvfs_mmio_regs;\ - } else { \ + } else if (table == 2) { \ + match_strs = (const char **)dlvr_strings;\ + mmio_regs = dlvr_mmio_regs;\ + } else {\ match_strs = (const char **)fivr_strings;\ mmio_regs = tgl_fivr_mmio_regs;\ } \ - \ ret = match_string(match_strs, -1, attr->attr.name);\ if (ret < 0)\ return ret;\ @@ -109,10 +134,13 @@ static ssize_t suffix##_store(struct device *dev,\ u32 mask;\ \ proc_priv = pci_get_drvdata(pdev);\ - if (table) {\ + if (table == 1) {\ match_strs = (const char **)dvfs_strings;\ mmio_regs = adl_dvfs_mmio_regs;\ - } else { \ + } else if (table == 2) { \ + match_strs = (const char **)dlvr_strings;\ + mmio_regs = dlvr_mmio_regs;\ + } else {\ match_strs = (const char **)fivr_strings;\ mmio_regs = tgl_fivr_mmio_regs;\ } \ @@ -147,6 +175,47 @@ RFIM_STORE(spread_spectrum_clk_enable, 0) RFIM_STORE(rfi_vco_ref_code, 0) RFIM_STORE(fivr_fffc_rev, 0) +RFIM_SHOW(dlvr_spread_spectrum_pct, 2) +RFIM_SHOW(dlvr_control_mode, 2) +RFIM_SHOW(dlvr_control_lock, 2) +RFIM_SHOW(dlvr_hardware_rev, 2) +RFIM_SHOW(dlvr_freq_mhz, 2) +RFIM_SHOW(dlvr_pll_busy, 2) +RFIM_SHOW(dlvr_freq_select, 2) +RFIM_SHOW(dlvr_rfim_enable, 2) + +RFIM_STORE(dlvr_spread_spectrum_pct, 2) +RFIM_STORE(dlvr_rfim_enable, 2) +RFIM_STORE(dlvr_freq_select, 2) +RFIM_STORE(dlvr_control_mode, 2) +RFIM_STORE(dlvr_control_lock, 2) + +static DEVICE_ATTR_RW(dlvr_spread_spectrum_pct); +static DEVICE_ATTR_RW(dlvr_control_mode); +static DEVICE_ATTR_RW(dlvr_control_lock); +static DEVICE_ATTR_RW(dlvr_freq_select); +static DEVICE_ATTR_RO(dlvr_hardware_rev); +static DEVICE_ATTR_RO(dlvr_freq_mhz); +static DEVICE_ATTR_RO(dlvr_pll_busy); +static DEVICE_ATTR_RW(dlvr_rfim_enable); + +static struct attribute *dlvr_attrs[] = { + &dev_attr_dlvr_spread_spectrum_pct.attr, + &dev_attr_dlvr_control_mode.attr, + &dev_attr_dlvr_control_lock.attr, + &dev_attr_dlvr_freq_select.attr, + &dev_attr_dlvr_hardware_rev.attr, + &dev_attr_dlvr_freq_mhz.attr, + &dev_attr_dlvr_pll_busy.attr, + &dev_attr_dlvr_rfim_enable.attr, + NULL +}; + +static const struct attribute_group dlvr_attribute_group = { + .attrs = dlvr_attrs, + .name = "dlvr" +}; + static DEVICE_ATTR_RW(vco_ref_code_lo); static DEVICE_ATTR_RW(vco_ref_code_hi); static DEVICE_ATTR_RW(spread_spectrum_pct); @@ -277,12 +346,22 @@ int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc return ret; } + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) { + ret = sysfs_create_group(&pdev->dev.kobj, &dlvr_attribute_group); + if (ret) + return ret; + } + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS) { ret = sysfs_create_group(&pdev->dev.kobj, &dvfs_attribute_group); if (ret && proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR) { sysfs_remove_group(&pdev->dev.kobj, &fivr_attribute_group); return ret; } + if (ret && proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) { + sysfs_remove_group(&pdev->dev.kobj, &dlvr_attribute_group); + return ret; + } } return 0; @@ -296,6 +375,9 @@ void proc_thermal_rfim_remove(struct pci_dev *pdev) if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR) sysfs_remove_group(&pdev->dev.kobj, &fivr_attribute_group); + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) + sysfs_remove_group(&pdev->dev.kobj, &dlvr_attribute_group); + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS) sysfs_remove_group(&pdev->dev.kobj, &dvfs_attribute_group); } diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c index b855d031a855..dce50d239357 100644 --- a/drivers/thermal/intel/intel_pch_thermal.c +++ b/drivers/thermal/intel/intel_pch_thermal.c @@ -119,7 +119,7 @@ static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip) static int pch_thermal_get_temp(struct thermal_zone_device *tzd, int *temp) { - struct pch_thermal_device *ptd = tzd->devdata; + struct pch_thermal_device *ptd = thermal_zone_device_priv(tzd); *temp = GET_WPT_TEMP(WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP)); return 0; diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index c7ba5680cd48..91fc7e239497 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -235,6 +235,12 @@ static int max_idle_set(const char *arg, const struct kernel_param *kp) goto skip_limit_set; } + if (!cpumask_available(idle_injection_cpu_mask)) { + ret = allocate_copy_idle_injection_mask(cpu_present_mask); + if (ret) + goto skip_limit_set; + } + if (check_invalid(idle_injection_cpu_mask, new_max_idle)) { ret = -EINVAL; goto skip_limit_set; @@ -791,7 +797,8 @@ static int __init powerclamp_init(void) return retval; mutex_lock(&powerclamp_lock); - retval = allocate_copy_idle_injection_mask(cpu_present_mask); + if (!cpumask_available(idle_injection_cpu_mask)) + retval = allocate_copy_idle_injection_mask(cpu_present_mask); mutex_unlock(&powerclamp_lock); if (retval) diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c index ffdc95047838..646ca8bd40a9 100644 --- a/drivers/thermal/intel/intel_quark_dts_thermal.c +++ b/drivers/thermal/intel/intel_quark_dts_thermal.c @@ -120,7 +120,7 @@ static DEFINE_MUTEX(dts_update_mutex); static int soc_dts_enable(struct thermal_zone_device *tzd) { u32 out; - struct soc_sensor_entry *aux_entry = tzd->devdata; + struct soc_sensor_entry *aux_entry = thermal_zone_device_priv(tzd); int ret; ret = iosf_mbi_read(QRK_MBI_UNIT_RMU, MBI_REG_READ, @@ -148,7 +148,7 @@ static int soc_dts_enable(struct thermal_zone_device *tzd) static int soc_dts_disable(struct thermal_zone_device *tzd) { u32 out; - struct soc_sensor_entry *aux_entry = tzd->devdata; + struct soc_sensor_entry *aux_entry = thermal_zone_device_priv(tzd); int ret; ret = iosf_mbi_read(QRK_MBI_UNIT_RMU, MBI_REG_READ, @@ -250,7 +250,7 @@ failed: static inline int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { - return update_trip_temp(tzd->devdata, trip, temp); + return update_trip_temp(thermal_zone_device_priv(tzd), trip, temp); } static int sys_get_curr_temp(struct thermal_zone_device *tzd, diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index 8c26f7b2316b..f99dc7e4ae89 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -54,7 +54,7 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip, struct intel_soc_dts_sensor_entry *dts; struct intel_soc_dts_sensors *sensors; - dts = tzd->devdata; + dts = thermal_zone_device_priv(tzd); sensors = dts->sensors; mutex_lock(&sensors->dts_update_lock); status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, @@ -168,7 +168,7 @@ err_restore_ptps: static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { - struct intel_soc_dts_sensor_entry *dts = tzd->devdata; + struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd); struct intel_soc_dts_sensors *sensors = dts->sensors; int status; @@ -176,7 +176,7 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, return -EINVAL; mutex_lock(&sensors->dts_update_lock); - status = update_trip_temp(tzd->devdata, trip, temp, + status = update_trip_temp(dts, trip, temp, dts->trip_types[trip]); mutex_unlock(&sensors->dts_update_lock); @@ -186,9 +186,7 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, static int sys_get_trip_type(struct thermal_zone_device *tzd, int trip, enum thermal_trip_type *type) { - struct intel_soc_dts_sensor_entry *dts; - - dts = tzd->devdata; + struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd); *type = dts->trip_types[trip]; @@ -200,11 +198,10 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, { int status; u32 out; - struct intel_soc_dts_sensor_entry *dts; + struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd); struct intel_soc_dts_sensors *sensors; unsigned long raw; - dts = tzd->devdata; sensors = dts->sensors; status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, SOC_DTS_OFFSET_TEMP, &out); diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/therm_throt.c index 2e22bb82b738..e69868e868eb 100644 --- a/drivers/thermal/intel/therm_throt.c +++ b/drivers/thermal/intel/therm_throt.c @@ -193,8 +193,67 @@ static const struct attribute_group thermal_attr_group = { #define THERM_THROT_POLL_INTERVAL HZ #define THERM_STATUS_PROCHOT_LOG BIT(1) -#define THERM_STATUS_CLEAR_CORE_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11) | BIT(13) | BIT(15)) -#define THERM_STATUS_CLEAR_PKG_MASK (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11)) +static u64 therm_intr_core_clear_mask; +static u64 therm_intr_pkg_clear_mask; + +static void thermal_intr_init_core_clear_mask(void) +{ + if (therm_intr_core_clear_mask) + return; + + /* + * Reference: Intel SDM Volume 4 + * "Table 2-2. IA-32 Architectural MSRs", MSR 0x19C + * IA32_THERM_STATUS. + */ + + /* + * Bit 1, 3, 5: CPUID.01H:EDX[22] = 1. This driver will not + * enable interrupts, when 0 as it checks for X86_FEATURE_ACPI. + */ + therm_intr_core_clear_mask = (BIT(1) | BIT(3) | BIT(5)); + + /* + * Bit 7 and 9: Thermal Threshold #1 and #2 log + * If CPUID.01H:ECX[8] = 1 + */ + if (boot_cpu_has(X86_FEATURE_TM2)) + therm_intr_core_clear_mask |= (BIT(7) | BIT(9)); + + /* Bit 11: Power Limitation log (R/WC0) If CPUID.06H:EAX[4] = 1 */ + if (boot_cpu_has(X86_FEATURE_PLN)) + therm_intr_core_clear_mask |= BIT(11); + + /* + * Bit 13: Current Limit log (R/WC0) If CPUID.06H:EAX[7] = 1 + * Bit 15: Cross Domain Limit log (R/WC0) If CPUID.06H:EAX[7] = 1 + */ + if (boot_cpu_has(X86_FEATURE_HWP)) + therm_intr_core_clear_mask |= (BIT(13) | BIT(15)); +} + +static void thermal_intr_init_pkg_clear_mask(void) +{ + if (therm_intr_pkg_clear_mask) + return; + + /* + * Reference: Intel SDM Volume 4 + * "Table 2-2. IA-32 Architectural MSRs", MSR 0x1B1 + * IA32_PACKAGE_THERM_STATUS. + */ + + /* All bits except BIT 26 depend on CPUID.06H: EAX[6] = 1 */ + if (boot_cpu_has(X86_FEATURE_PTS)) + therm_intr_pkg_clear_mask = (BIT(1) | BIT(3) | BIT(5) | BIT(7) | BIT(9) | BIT(11)); + + /* + * Intel SDM Volume 2A: Thermal and Power Management Leaf + * Bit 26: CPUID.06H: EAX[19] = 1 + */ + if (boot_cpu_has(X86_FEATURE_HFI)) + therm_intr_pkg_clear_mask |= BIT(26); +} /* * Clear the bits in package thermal status register for bit = 1 @@ -207,13 +266,10 @@ void thermal_clear_package_intr_status(int level, u64 bit_mask) if (level == CORE_LEVEL) { msr = MSR_IA32_THERM_STATUS; - msr_val = THERM_STATUS_CLEAR_CORE_MASK; + msr_val = therm_intr_core_clear_mask; } else { msr = MSR_IA32_PACKAGE_THERM_STATUS; - msr_val = THERM_STATUS_CLEAR_PKG_MASK; - if (boot_cpu_has(X86_FEATURE_HFI)) - msr_val |= BIT(26); - + msr_val = therm_intr_pkg_clear_mask; } msr_val &= ~bit_mask; @@ -708,6 +764,9 @@ void intel_init_thermal(struct cpuinfo_x86 *c) h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED; apic_write(APIC_LVTTHMR, h); + thermal_intr_init_core_clear_mask(); + thermal_intr_init_pkg_clear_mask(); + rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable) wrmsr(MSR_IA32_THERM_INTERRUPT, diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 1c2de84742df..11a7f8108bbb 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -107,7 +107,7 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu) static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) { - struct zone_device *zonedev = tzd->devdata; + struct zone_device *zonedev = thermal_zone_device_priv(tzd); int val; val = intel_tcc_get_temp(zonedev->cpu, true); @@ -122,16 +122,18 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { - struct zone_device *zonedev = tzd->devdata; + struct zone_device *zonedev = thermal_zone_device_priv(tzd); u32 l, h, mask, shift, intr; - int tj_max, ret; + int tj_max, val, ret; tj_max = intel_tcc_get_tjmax(zonedev->cpu); if (tj_max < 0) return tj_max; tj_max *= 1000; - if (trip >= MAX_NUMBER_OF_TRIPS || temp >= tj_max) + val = (tj_max - temp)/1000; + + if (trip >= MAX_NUMBER_OF_TRIPS || val < 0 || val > 0x7f) return -EINVAL; ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, @@ -156,7 +158,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) if (!temp) { l &= ~intr; } else { - l |= (tj_max - temp)/1000 << shift; + l |= val << shift; l |= intr; } diff --git a/drivers/thermal/k3_bandgap.c b/drivers/thermal/k3_bandgap.c index 22c9bcb899c3..791210458606 100644 --- a/drivers/thermal/k3_bandgap.c +++ b/drivers/thermal/k3_bandgap.c @@ -141,7 +141,7 @@ static int k3_bgp_read_temp(struct k3_thermal_data *devdata, static int k3_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct k3_thermal_data *data = tz->devdata; + struct k3_thermal_data *data = thermal_zone_device_priv(tz); int ret = 0; ret = k3_bgp_read_temp(data, temp); @@ -222,7 +222,7 @@ static int k3_bandgap_probe(struct platform_device *pdev) goto err_alloc; } - if (devm_thermal_add_hwmon_sysfs(data[id].tzd)) + if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c index 031ea1091909..5be1f09eeb2c 100644 --- a/drivers/thermal/k3_j72xx_bandgap.c +++ b/drivers/thermal/k3_j72xx_bandgap.c @@ -248,7 +248,7 @@ static inline int k3_bgp_read_temp(struct k3_thermal_data *devdata, /* Get temperature callback function for thermal zone */ static int k3_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - return k3_bgp_read_temp(tz->devdata, temp); + return k3_bgp_read_temp(thermal_zone_device_priv(tz), temp); } static const struct thermal_zone_device_ops k3_of_thermal_ops = { diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c index bec7ec20e79d..668747bd86ef 100644 --- a/drivers/thermal/kirkwood_thermal.c +++ b/drivers/thermal/kirkwood_thermal.c @@ -27,17 +27,14 @@ static int kirkwood_get_temp(struct thermal_zone_device *thermal, int *temp) { unsigned long reg; - struct kirkwood_thermal_priv *priv = thermal->devdata; + struct kirkwood_thermal_priv *priv = thermal_zone_device_priv(thermal); reg = readl_relaxed(priv->sensor); /* Valid check */ if (!((reg >> KIRKWOOD_THERMAL_VALID_OFFSET) & - KIRKWOOD_THERMAL_VALID_MASK)) { - dev_err(&thermal->device, - "Temperature sensor reading not valid\n"); + KIRKWOOD_THERMAL_VALID_MASK)) return -EIO; - } /* * Calculate temperature. According to Marvell internal diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c index 6451a55eb582..61c7622d9945 100644 --- a/drivers/thermal/max77620_thermal.c +++ b/drivers/thermal/max77620_thermal.c @@ -46,15 +46,13 @@ struct max77620_therm_info { static int max77620_thermal_read_temp(struct thermal_zone_device *tz, int *temp) { - struct max77620_therm_info *mtherm = tz->devdata; + struct max77620_therm_info *mtherm = thermal_zone_device_priv(tz); unsigned int val; int ret; ret = regmap_read(mtherm->rmap, MAX77620_REG_STATLBT, &val); - if (ret < 0) { - dev_err(mtherm->dev, "Failed to read STATLBT: %d\n", ret); + if (ret < 0) return ret; - } if (val & MAX77620_IRQ_TJALRM2_MASK) *temp = MAX77620_TJALARM2_TEMP; diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c index ab730f9552d0..b6bb9eaafb74 100644 --- a/drivers/thermal/mediatek/auxadc_thermal.c +++ b/drivers/thermal/mediatek/auxadc_thermal.c @@ -31,6 +31,7 @@ #define AUXADC_CON2_V 0x010 #define AUXADC_DATA(channel) (0x14 + (channel) * 4) +#define APMIXED_SYS_TS_CON0 0x600 #define APMIXED_SYS_TS_CON1 0x604 /* Thermal Controller Registers */ @@ -281,6 +282,17 @@ enum mtk_thermal_version { /* The calibration coefficient of sensor */ #define MT7986_CALIBRATION 165 +/* MT8365 */ +#define MT8365_TEMP_AUXADC_CHANNEL 11 +#define MT8365_CALIBRATION 164 +#define MT8365_NUM_CONTROLLER 1 +#define MT8365_NUM_BANKS 1 +#define MT8365_NUM_SENSORS 3 +#define MT8365_NUM_SENSORS_PER_ZONE 3 +#define MT8365_TS1 0 +#define MT8365_TS2 1 +#define MT8365_TS3 2 + struct mtk_thermal; struct thermal_bank_cfg { @@ -307,6 +319,9 @@ struct mtk_thermal_data { bool need_switch_bank; struct thermal_bank_cfg bank_data[MAX_NUM_ZONES]; enum mtk_thermal_version version; + u32 apmixed_buffer_ctl_reg; + u32 apmixed_buffer_ctl_mask; + u32 apmixed_buffer_ctl_set; }; struct mtk_thermal { @@ -432,6 +447,24 @@ static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, }; static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 }; static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, }; +/* MT8365 thermal sensor data */ +static const int mt8365_bank_data[MT8365_NUM_SENSORS] = { + MT8365_TS1, MT8365_TS2, MT8365_TS3 +}; + +static const int mt8365_msr[MT8365_NUM_SENSORS_PER_ZONE] = { + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2 +}; + +static const int mt8365_adcpnp[MT8365_NUM_SENSORS_PER_ZONE] = { + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2 +}; + +static const int mt8365_mux_values[MT8365_NUM_SENSORS] = { 0, 1, 2 }; +static const int mt8365_tc_offset[MT8365_NUM_CONTROLLER] = { 0 }; + +static const int mt8365_vts_index[MT8365_NUM_SENSORS] = { VTS1, VTS2, VTS3 }; + /* * The MT8173 thermal controller has four banks. Each bank can read up to * four temperature sensors simultaneously. The MT8173 has a total of 5 @@ -507,6 +540,40 @@ static const struct mtk_thermal_data mt2701_thermal_data = { }; /* + * The MT8365 thermal controller has one bank, which can read up to + * four temperature sensors simultaneously. The MT8365 has a total of 3 + * temperature sensors. + * + * The thermal core only gets the maximum temperature of this one bank, + * so the bank concept wouldn't be necessary here. However, the SVS (Smart + * Voltage Scaling) unit makes its decisions based on the same bank + * data. + */ +static const struct mtk_thermal_data mt8365_thermal_data = { + .auxadc_channel = MT8365_TEMP_AUXADC_CHANNEL, + .num_banks = MT8365_NUM_BANKS, + .num_sensors = MT8365_NUM_SENSORS, + .vts_index = mt8365_vts_index, + .cali_val = MT8365_CALIBRATION, + .num_controller = MT8365_NUM_CONTROLLER, + .controller_offset = mt8365_tc_offset, + .need_switch_bank = false, + .bank_data = { + { + .num_sensors = MT8365_NUM_SENSORS, + .sensors = mt8365_bank_data + }, + }, + .msr = mt8365_msr, + .adcpnp = mt8365_adcpnp, + .sensor_mux_values = mt8365_mux_values, + .version = MTK_THERMAL_V1, + .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON0, + .apmixed_buffer_ctl_mask = (u32) ~GENMASK(29, 28), + .apmixed_buffer_ctl_set = 0, +}; + +/* * The MT2712 thermal controller has one bank, which can read up to * four temperature sensors simultaneously. The MT2712 has a total of 4 * temperature sensors. @@ -560,6 +627,9 @@ static const struct mtk_thermal_data mt7622_thermal_data = { .adcpnp = mt7622_adcpnp, .sensor_mux_values = mt7622_mux_values, .version = MTK_THERMAL_V2, + .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON1, + .apmixed_buffer_ctl_mask = GENMASK(31, 6) | BIT(3), + .apmixed_buffer_ctl_set = BIT(0), }; /* @@ -746,14 +816,6 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) mt, conf->bank_data[bank->id].sensors[i], raw); - /* - * The first read of a sensor often contains very high bogus - * temperature value. Filter these out so that the system does - * not immediately shut down. - */ - if (temp > 200000) - temp = 0; - if (temp > max) max = temp; } @@ -763,7 +825,7 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) { - struct mtk_thermal *mt = tz->devdata; + struct mtk_thermal *mt = thermal_zone_device_priv(tz); int i; int tempmax = INT_MIN; @@ -1074,19 +1136,27 @@ static const struct of_device_id mtk_thermal_of_match[] = { { .compatible = "mediatek,mt8183-thermal", .data = (void *)&mt8183_thermal_data, + }, + { + .compatible = "mediatek,mt8365-thermal", + .data = (void *)&mt8365_thermal_data, }, { }, }; MODULE_DEVICE_TABLE(of, mtk_thermal_of_match); -static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base) +static void mtk_thermal_turn_on_buffer(struct mtk_thermal *mt, + void __iomem *apmixed_base) { - int tmp; + u32 tmp; - tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1); - tmp &= ~(0x37); - tmp |= 0x1; - writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1); + if (!mt->conf->apmixed_buffer_ctl_reg) + return; + + tmp = readl(apmixed_base + mt->conf->apmixed_buffer_ctl_reg); + tmp &= mt->conf->apmixed_buffer_ctl_mask; + tmp |= mt->conf->apmixed_buffer_ctl_set; + writel(tmp, apmixed_base + mt->conf->apmixed_buffer_ctl_reg); udelay(200); } @@ -1184,10 +1254,10 @@ static int mtk_thermal_probe(struct platform_device *pdev) goto err_disable_clk_auxadc; } - if (mt->conf->version != MTK_THERMAL_V1) { - mtk_thermal_turn_on_buffer(apmixed_base); + mtk_thermal_turn_on_buffer(mt, apmixed_base); + + if (mt->conf->version != MTK_THERMAL_V2) mtk_thermal_release_periodic_ts(mt, auxadc_base); - } if (mt->conf->version == MTK_THERMAL_V1) mt->raw_to_mcelsius = raw_to_mcelsius_v1; @@ -1203,6 +1273,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mt); + /* Delay for thermal banks to be ready */ + msleep(30); + tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, &mtk_thermal_ops); if (IS_ERR(tzdev)) { @@ -1210,7 +1283,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) goto err_disable_clk_peri_therm; } - ret = devm_thermal_add_hwmon_sysfs(tzdev); + ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev); if (ret) dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs"); diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 84ba65a27acf..d0a3f95b7884 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -66,7 +66,7 @@ #define LVTS_MONINT_CONF 0x9FBF7BDE #define LVTS_INT_SENSOR0 0x0009001F -#define LVTS_INT_SENSOR1 0X000881F0 +#define LVTS_INT_SENSOR1 0x001203E0 #define LVTS_INT_SENSOR2 0x00247C00 #define LVTS_INT_SENSOR3 0x1FC00000 @@ -252,7 +252,7 @@ static u32 lvts_temp_to_raw(int temperature) static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) { - struct lvts_sensor *lvts_sensor = tz->devdata; + struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); void __iomem *msr = lvts_sensor->msr; u32 value; @@ -290,7 +290,7 @@ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp) static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct lvts_sensor *lvts_sensor = tz->devdata; + struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz); void __iomem *base = lvts_sensor->base; u32 raw_low = lvts_temp_to_raw(low); u32 raw_high = lvts_temp_to_raw(high); @@ -305,7 +305,8 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) * 14-0 : Raw temperature for threshold */ if (low != -INT_MAX) { - dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low); + pr_debug("%s: Setting low limit temperature interrupt: %d\n", + thermal_zone_device_type(tz), low); writel(raw_low, LVTS_H2NTHRE(base)); } @@ -318,7 +319,8 @@ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high) * * 14-0 : Raw temperature for threshold */ - dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high); + pr_debug("%s: Setting high limit temperature interrupt: %d\n", + thermal_zone_device_type(tz), high); writel(raw_high, LVTS_HTHRE(base)); return 0; @@ -393,8 +395,8 @@ static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl) * => 0x1FC00000 * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000 * => 0x00247C00 - * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000 - * => 0X000881F0 + * sensor 1 interrupt: 0000 0000 0001 0010 0000 0011 1110 0000 + * => 0X001203E0 * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111 * => 0x0009001F */ @@ -528,29 +530,33 @@ static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl, * The efuse blob values follows the sensor enumeration per thermal * controller. The decoding of the stream is as follow: * - * <--?-> <----big0 ???---> <-sensor0-> <-0-> - * ------------------------------------------ - * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | - * ------------------------------------------ + * stream index map for MCU Domain : * - * <--sensor1--><-0-> <----big1 ???---> <-sen - * ------------------------------------------ - * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD | - * ------------------------------------------ + * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1-----> + * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 * - * sor0-> <-0-> <-sensor1-> <-0-> .......... - * ------------------------------------------ - * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD | - * ------------------------------------------ + * <-----mcu-tc#1-----> <-----sensor#2-----> <-----sensor#3-----> + * 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12 * - * And so on ... + * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7-----> + * 0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 + * + * stream index map for AP Domain : + * + * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1-----> + * 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A + * + * <-----ap--tc#1-----> <-----sensor#2-----> <-----sensor#3-----> + * 0x2B | 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33 + * + * <-----ap--tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> + * 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F + * + * <-----ap--tc#3-----> <-----sensor#7-----> <-----sensor#8-----> + * 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47 | 0x48 * * The data description gives the offset of the calibration data in * this bytes stream for each sensor. - * - * Each thermal controller can handle up to 4 sensors max, we don't - * care if there are less as the array of calibration is sized to 4 - * anyway. The unused sensor slot will be zeroed. */ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl, const struct lvts_ctrl_data *lvts_ctrl_data, @@ -1163,7 +1169,7 @@ static int lvts_remove(struct platform_device *pdev) return 0; } -static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = { +static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = { { .cal_offset = { 0x04, 0x07 }, .lvts_sensor = { @@ -1198,13 +1204,63 @@ static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = { } }; +static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = { + { + .cal_offset = { 0x25, 0x28 }, + .lvts_sensor = { + { .dt_id = MT8195_AP_VPU0 }, + { .dt_id = MT8195_AP_VPU1 } + }, + .num_lvts_sensor = 2, + .offset = 0x0, + .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195, + }, + { + .cal_offset = { 0x2e, 0x31 }, + .lvts_sensor = { + { .dt_id = MT8195_AP_GPU0 }, + { .dt_id = MT8195_AP_GPU1 } + }, + .num_lvts_sensor = 2, + .offset = 0x100, + .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195, + }, + { + .cal_offset = { 0x37, 0x3a, 0x3d }, + .lvts_sensor = { + { .dt_id = MT8195_AP_VDEC }, + { .dt_id = MT8195_AP_IMG }, + { .dt_id = MT8195_AP_INFRA }, + }, + .num_lvts_sensor = 3, + .offset = 0x200, + .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195, + }, + { + .cal_offset = { 0x43, 0x46 }, + .lvts_sensor = { + { .dt_id = MT8195_AP_CAM0 }, + { .dt_id = MT8195_AP_CAM1 } + }, + .num_lvts_sensor = 2, + .offset = 0x300, + .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195, + } +}; + static const struct lvts_data mt8195_lvts_mcu_data = { - .lvts_ctrl = mt8195_lvts_data_ctrl, - .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_data_ctrl), + .lvts_ctrl = mt8195_lvts_mcu_data_ctrl, + .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl), +}; + +static const struct lvts_data mt8195_lvts_ap_data = { + .lvts_ctrl = mt8195_lvts_ap_data_ctrl, + .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl), }; static const struct of_device_id lvts_of_match[] = { { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data }, + { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data }, {}, }; MODULE_DEVICE_TABLE(of, lvts_of_match); diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 31164ade2dd1..5749149ae2e4 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -360,7 +360,7 @@ static irqreturn_t adc_tm5_gen2_isr(int irq, void *data) static int adc_tm5_get_temp(struct thermal_zone_device *tz, int *temp) { - struct adc_tm5_channel *channel = tz->devdata; + struct adc_tm5_channel *channel = thermal_zone_device_priv(tz); int ret; if (!channel || !channel->iio) @@ -642,7 +642,7 @@ config_fail: static int adc_tm5_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct adc_tm5_channel *channel = tz->devdata; + struct adc_tm5_channel *channel = thermal_zone_device_priv(tz); struct adc_tm5_chip *chip; int ret; @@ -689,7 +689,7 @@ static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm) return PTR_ERR(tzd); } adc_tm->channels[i].tzd = tzd; - if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd)) dev_warn(adc_tm->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 101c75d0e13f..0f88e98428ac 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -187,7 +187,7 @@ static int qpnp_tm_update_temp_no_adc(struct qpnp_tm_chip *chip) static int qpnp_tm_get_temp(struct thermal_zone_device *tz, int *temp) { - struct qpnp_tm_chip *chip = tz->devdata; + struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); int ret, mili_celsius; if (!temp) @@ -265,7 +265,7 @@ skip: static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { - struct qpnp_tm_chip *chip = tz->devdata; + struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); struct thermal_trip trip; int ret; @@ -459,7 +459,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) return ret; } - if (devm_thermal_add_hwmon_sysfs(chip->tz_dev)) + if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev)) dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n"); diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 8020ead2794e..d3218127e617 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -673,7 +673,7 @@ static irqreturn_t tsens_combined_irq_thread(int irq, void *data) static int tsens_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct tsens_sensor *s = tz->devdata; + struct tsens_sensor *s = thermal_zone_device_priv(tz); struct tsens_priv *priv = s->priv; struct device *dev = priv->dev; struct tsens_irq_data d; @@ -1057,7 +1057,7 @@ err_put_device: static int tsens_get_temp(struct thermal_zone_device *tz, int *temp) { - struct tsens_sensor *s = tz->devdata; + struct tsens_sensor *s = thermal_zone_device_priv(tz); struct tsens_priv *priv = s->priv; return priv->ops->get_temp(s, temp); @@ -1189,7 +1189,7 @@ static int tsens_register(struct tsens_priv *priv) if (priv->ops->enable) priv->ops->enable(priv, i); - if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd)) dev_warn(priv->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index 431c29c0898a..e58756323457 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -83,7 +83,7 @@ static struct qoriq_tmu_data *qoriq_sensor_to_data(struct qoriq_sensor *s) static int tmu_get_temp(struct thermal_zone_device *tz, int *temp) { - struct qoriq_sensor *qsensor = tz->devdata; + struct qoriq_sensor *qsensor = thermal_zone_device_priv(tz); struct qoriq_tmu_data *qdata = qoriq_sensor_to_data(qsensor); u32 val; /* @@ -157,7 +157,7 @@ static int qoriq_tmu_register_tmu_zone(struct device *dev, return ret; } - if (devm_thermal_add_hwmon_sysfs(tzd)) + if (devm_thermal_add_hwmon_sysfs(dev, tzd)) dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index d6b5b59c5c53..42a4724d3920 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -14,7 +14,6 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <linux/sys_soc.h> #include <linux/thermal.h> #include "thermal_hwmon.h" @@ -27,7 +26,6 @@ #define REG_GEN3_IRQTEMP1 0x14 #define REG_GEN3_IRQTEMP2 0x18 #define REG_GEN3_IRQTEMP3 0x1C -#define REG_GEN3_CTSR 0x20 #define REG_GEN3_THCTR 0x20 #define REG_GEN3_TEMP 0x28 #define REG_GEN3_THCODE1 0x50 @@ -46,14 +44,6 @@ #define IRQ_TEMPD2 BIT(4) #define IRQ_TEMPD3 BIT(5) -/* CTSR bits */ -#define CTSR_PONM BIT(8) -#define CTSR_AOUT BIT(7) -#define CTSR_THBGR BIT(5) -#define CTSR_VMEN BIT(4) -#define CTSR_VMST BIT(1) -#define CTSR_THSST BIT(0) - /* THCTR bits */ #define THCTR_PONM BIT(6) #define THCTR_THSST BIT(0) @@ -88,8 +78,6 @@ struct rcar_gen3_thermal_priv { struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; struct thermal_zone_device_ops ops; unsigned int num_tscs; - void (*thermal_init)(struct rcar_gen3_thermal_priv *priv, - struct rcar_gen3_thermal_tsc *tsc); int ptat[3]; }; @@ -167,7 +155,7 @@ static int rcar_gen3_thermal_round(int temp) static int rcar_gen3_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct rcar_gen3_thermal_tsc *tsc = tz->devdata; + struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); int mcelsius, val; int reg; @@ -206,7 +194,7 @@ static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc, static int rcar_gen3_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct rcar_gen3_thermal_tsc *tsc = tz->devdata; + struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); u32 irqmsk = 0; if (low != -INT_MAX) { @@ -248,11 +236,6 @@ static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data) return IRQ_HANDLED; } -static const struct soc_device_attribute r8a7795es1[] = { - { .soc_id = "r8a7795", .revision = "ES1.*" }, - { /* sentinel */ } -}; - static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv) { unsigned int i; @@ -311,34 +294,6 @@ static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv) return true; } -static void rcar_gen3_thermal_init_r8a7795es1(struct rcar_gen3_thermal_priv *priv, - struct rcar_gen3_thermal_tsc *tsc) -{ - rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_THBGR); - rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, 0x0); - - usleep_range(1000, 2000); - - rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, CTSR_PONM); - - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0x3F); - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, 0); - if (priv->ops.set_trips) - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQEN, - IRQ_TEMPD1 | IRQ_TEMP2); - - rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, - CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN); - - usleep_range(100, 200); - - rcar_gen3_thermal_write(tsc, REG_GEN3_CTSR, - CTSR_PONM | CTSR_AOUT | CTSR_THBGR | CTSR_VMEN | - CTSR_VMST | CTSR_THSST); - - usleep_range(1000, 2000); -} - static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv, struct rcar_gen3_thermal_tsc *tsc) { @@ -474,9 +429,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) return -ENOMEM; priv->ops = rcar_gen3_tz_of_ops; - priv->thermal_init = rcar_gen3_thermal_init; - if (soc_device_match(r8a7795es1)) - priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; platform_set_drvdata(pdev, priv); @@ -516,7 +468,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) for (i = 0; i < priv->num_tscs; i++) { struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - priv->thermal_init(priv, tsc); + rcar_gen3_thermal_init(priv, tsc); rcar_gen3_thermal_calc_coefs(priv, tsc, *ths_tj_1); zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops); @@ -527,7 +479,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) } tsc->zone = zone; - tsc->zone->tzp->no_hwmon = false; ret = thermal_add_hwmon_sysfs(tsc->zone); if (ret) goto error_unregister; @@ -564,7 +515,7 @@ static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev) for (i = 0; i < priv->num_tscs; i++) { struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - priv->thermal_init(priv, tsc); + rcar_gen3_thermal_init(priv, tsc); } return 0; diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 436f5f9cf729..b8571f7090aa 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -101,7 +101,6 @@ struct rcar_thermal_priv { list_for_each_entry(pos, &common->head, list) #define MCELSIUS(temp) ((temp) * 1000) -#define rcar_zone_to_priv(zone) ((zone)->devdata) #define rcar_priv_to_dev(priv) ((priv)->common->dev) #define rcar_has_irq_support(priv) ((priv)->common->base) #define rcar_id_to_shift(priv) ((priv)->id * 8) @@ -273,7 +272,7 @@ static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv, static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) { - struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); + struct rcar_thermal_priv *priv = thermal_zone_device_priv(zone); return rcar_thermal_get_current_temp(priv, temp); } @@ -510,11 +509,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) } if (chip->use_of_thermal) { - /* - * thermal_zone doesn't enable hwmon as default, - * but, enable it here to keep compatible - */ - priv->zone->tzp->no_hwmon = false; ret = thermal_add_hwmon_sysfs(priv->zone); if (ret) goto error_unregister; diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 4b7c43f34d1a..77231a9d28ff 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -40,15 +40,6 @@ enum tshut_polarity { }; /* - * The system has two Temperature Sensors. - * sensor0 is for CPU, and sensor1 is for GPU. - */ -enum sensor_id { - SENSOR_CPU = 0, - SENSOR_GPU, -}; - -/* * The conversion table has the adc value and temperature. * ADC_DECREMENT: the adc value is of diminishing.(e.g. rk3288_code_table) * ADC_INCREMENT: the adc value is incremental.(e.g. rk3368_code_table) @@ -60,12 +51,6 @@ enum adc_sort_mode { #include "thermal_hwmon.h" -/* - * The max sensors is two in rockchip SoCs. - * Two sensors: CPU and GPU sensor. - */ -#define SOC_MAX_SENSORS 2 - /** * struct chip_tsadc_table - hold information about chip-specific differences * @id: conversion table @@ -82,7 +67,7 @@ struct chip_tsadc_table { /** * struct rockchip_tsadc_chip - hold the private data of tsadc chip - * @chn_id: array of sensor ids of chip corresponding to the channel + * @chn_offset: the channel offset of the first channel * @chn_num: the channel number of tsadc chip * @tshut_temp: the hardware-controlled shutdown temperature value * @tshut_mode: the hardware-controlled shutdown mode (0:CRU 1:GPIO) @@ -98,7 +83,7 @@ struct chip_tsadc_table { */ struct rockchip_tsadc_chip { /* The sensor id of chip correspond to the ADC channel */ - int chn_id[SOC_MAX_SENSORS]; + int chn_offset; int chn_num; /* The hardware-controlled tshut property */ @@ -156,7 +141,7 @@ struct rockchip_thermal_data { struct platform_device *pdev; struct reset_control *reset; - struct rockchip_thermal_sensor sensors[SOC_MAX_SENSORS]; + struct rockchip_thermal_sensor *sensors; struct clk *clk; struct clk *pclk; @@ -180,29 +165,49 @@ struct rockchip_thermal_data { #define TSADCV2_AUTO_CON 0x04 #define TSADCV2_INT_EN 0x08 #define TSADCV2_INT_PD 0x0c +#define TSADCV3_AUTO_SRC_CON 0x0c +#define TSADCV3_HT_INT_EN 0x14 +#define TSADCV3_HSHUT_GPIO_INT_EN 0x18 +#define TSADCV3_HSHUT_CRU_INT_EN 0x1c +#define TSADCV3_INT_PD 0x24 +#define TSADCV3_HSHUT_PD 0x28 #define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04) #define TSADCV2_COMP_INT(chn) (0x30 + (chn) * 0x04) #define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04) +#define TSADCV3_DATA(chn) (0x2c + (chn) * 0x04) +#define TSADCV3_COMP_INT(chn) (0x6c + (chn) * 0x04) +#define TSADCV3_COMP_SHUT(chn) (0x10c + (chn) * 0x04) #define TSADCV2_HIGHT_INT_DEBOUNCE 0x60 #define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64 +#define TSADCV3_HIGHT_INT_DEBOUNCE 0x14c +#define TSADCV3_HIGHT_TSHUT_DEBOUNCE 0x150 #define TSADCV2_AUTO_PERIOD 0x68 #define TSADCV2_AUTO_PERIOD_HT 0x6c +#define TSADCV3_AUTO_PERIOD 0x154 +#define TSADCV3_AUTO_PERIOD_HT 0x158 #define TSADCV2_AUTO_EN BIT(0) +#define TSADCV2_AUTO_EN_MASK BIT(16) #define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV3_AUTO_SRC_EN(chn) BIT(chn) +#define TSADCV3_AUTO_SRC_EN_MASK(chn) BIT(16 + chn) #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) +#define TSADCV2_AUTO_TSHUT_POLARITY_MASK BIT(24) #define TSADCV3_AUTO_Q_SEL_EN BIT(1) #define TSADCV2_INT_SRC_EN(chn) BIT(chn) +#define TSADCV2_INT_SRC_EN_MASK(chn) BIT(16 + (chn)) #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8) #define TSADCV3_INT_PD_CLEAR_MASK ~BIT(16) +#define TSADCV4_INT_PD_CLEAR_MASK 0xffffffff #define TSADCV2_DATA_MASK 0xfff #define TSADCV3_DATA_MASK 0x3ff +#define TSADCV4_DATA_MASK 0x1ff #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 @@ -213,6 +218,8 @@ struct rockchip_thermal_data { #define TSADCV5_AUTO_PERIOD_TIME 1622 /* 2.5ms */ #define TSADCV5_AUTO_PERIOD_HT_TIME 1622 /* 2.5ms */ +#define TSADCV6_AUTO_PERIOD_TIME 5000 /* 2.5ms */ +#define TSADCV6_AUTO_PERIOD_HT_TIME 5000 /* 2.5ms */ #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ #define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */ @@ -229,6 +236,12 @@ struct rockchip_thermal_data { #define RK3568_GRF_TSADC_ANA_REG2 (0x10001 << 2) #define RK3568_GRF_TSADC_TSEN (0x10001 << 8) +#define RK3588_GRF0_TSADC_CON 0x0100 + +#define RK3588_GRF0_TSADC_TRM (0xff0077 << 0) +#define RK3588_GRF0_TSADC_SHUT_2CRU (0x30003 << 10) +#define RK3588_GRF0_TSADC_SHUT_2GPIO (0x70007 << 12) + #define GRF_SARADC_TESTBIT_ON (0x10001 << 2) #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) #define GRF_TSADC_VCM_EN_L (0x10001 << 7) @@ -523,6 +536,15 @@ static const struct tsadc_table rk3568_code_table[] = { {TSADCV2_DATA_MASK, 125000}, }; +static const struct tsadc_table rk3588_code_table[] = { + {0, -40000}, + {215, -40000}, + {285, 25000}, + {350, 85000}, + {395, 125000}, + {TSADCV4_DATA_MASK, 125000}, +}; + static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table, int temp) { @@ -793,6 +815,25 @@ static void rk_tsadcv7_initialize(struct regmap *grf, void __iomem *regs, } } +static void rk_tsadcv8_initialize(struct regmap *grf, void __iomem *regs, + enum tshut_polarity tshut_polarity) +{ + writel_relaxed(TSADCV6_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD); + writel_relaxed(TSADCV6_AUTO_PERIOD_HT_TIME, + regs + TSADCV3_AUTO_PERIOD_HT); + writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, + regs + TSADCV3_HIGHT_INT_DEBOUNCE); + writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, + regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE); + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH | + TSADCV2_AUTO_TSHUT_POLARITY_MASK, + regs + TSADCV2_AUTO_CON); + else + writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK, + regs + TSADCV2_AUTO_CON); +} + static void rk_tsadcv2_irq_ack(void __iomem *regs) { u32 val; @@ -809,6 +850,17 @@ static void rk_tsadcv3_irq_ack(void __iomem *regs) writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); } +static void rk_tsadcv4_irq_ack(void __iomem *regs) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV3_INT_PD); + writel_relaxed(val & TSADCV4_INT_PD_CLEAR_MASK, regs + TSADCV3_INT_PD); + val = readl_relaxed(regs + TSADCV3_HSHUT_PD); + writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, + regs + TSADCV3_HSHUT_PD); +} + static void rk_tsadcv2_control(void __iomem *regs, bool enable) { u32 val; @@ -844,6 +896,18 @@ static void rk_tsadcv3_control(void __iomem *regs, bool enable) writel_relaxed(val, regs + TSADCV2_AUTO_CON); } +static void rk_tsadcv4_control(void __iomem *regs, bool enable) +{ + u32 val; + + if (enable) + val = TSADCV2_AUTO_EN | TSADCV2_AUTO_EN_MASK; + else + val = TSADCV2_AUTO_EN_MASK; + + writel_relaxed(val, regs + TSADCV2_AUTO_CON); +} + static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table, int chn, void __iomem *regs, int *temp) { @@ -854,6 +918,16 @@ static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table, return rk_tsadcv2_code_to_temp(table, val, temp); } +static int rk_tsadcv4_get_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int *temp) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV3_DATA(chn)); + + return rk_tsadcv2_code_to_temp(table, val, temp); +} + static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, int chn, void __iomem *regs, int temp) { @@ -888,6 +962,33 @@ static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, return 0; } +static int rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) +{ + u32 alarm_value; + + /* + * In some cases, some sensors didn't need the trip points, the + * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm + * in the end, ignore this case and disable the high temperature + * interrupt. + */ + if (temp == INT_MAX) { + writel_relaxed(TSADCV2_INT_SRC_EN_MASK(chn), + regs + TSADCV3_HT_INT_EN); + return 0; + } + /* Make sure the value is valid */ + alarm_value = rk_tsadcv2_temp_to_code(table, temp); + if (alarm_value == table->data_mask) + return -ERANGE; + writel_relaxed(alarm_value & table->data_mask, + regs + TSADCV3_COMP_INT(chn)); + writel_relaxed(TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn), + regs + TSADCV3_HT_INT_EN); + return 0; +} + static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, int chn, void __iomem *regs, int temp) { @@ -907,6 +1008,25 @@ static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, return 0; } +static int rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) +{ + u32 tshut_value; + + /* Make sure the value is valid */ + tshut_value = rk_tsadcv2_temp_to_code(table, temp); + if (tshut_value == table->data_mask) + return -ERANGE; + + writel_relaxed(tshut_value, regs + TSADCV3_COMP_SHUT(chn)); + + /* TSHUT will be valid */ + writel_relaxed(TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn), + regs + TSADCV3_AUTO_SRC_CON); + + return 0; +} + static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, enum tshut_mode mode) { @@ -924,9 +1044,25 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, writel_relaxed(val, regs + TSADCV2_INT_EN); } +static void rk_tsadcv3_tshut_mode(int chn, void __iomem *regs, + enum tshut_mode mode) +{ + u32 val_gpio, val_cru; + + if (mode == TSHUT_MODE_GPIO) { + val_gpio = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_cru = TSADCV2_INT_SRC_EN_MASK(chn); + } else { + val_cru = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_gpio = TSADCV2_INT_SRC_EN_MASK(chn); + } + writel_relaxed(val_gpio, regs + TSADCV3_HSHUT_GPIO_INT_EN); + writel_relaxed(val_cru, regs + TSADCV3_HSHUT_CRU_INT_EN); +} + static const struct rockchip_tsadc_chip px30_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ + /* cpu, gpu */ + .chn_offset = 0, .chn_num = 2, /* 2 channels for tsadc */ .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ @@ -949,7 +1085,8 @@ static const struct rockchip_tsadc_chip px30_tsadc_data = { }; static const struct rockchip_tsadc_chip rv1108_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + /* cpu */ + .chn_offset = 0, .chn_num = 1, /* one channel for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -973,7 +1110,8 @@ static const struct rockchip_tsadc_chip rv1108_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3228_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + /* cpu */ + .chn_offset = 0, .chn_num = 1, /* one channel for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -997,8 +1135,8 @@ static const struct rockchip_tsadc_chip rk3228_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3288_tsadc_data = { - .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */ - .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */ + /* cpu, gpu */ + .chn_offset = 1, .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -1022,7 +1160,8 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3328_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + /* cpu */ + .chn_offset = 0, .chn_num = 1, /* one channels for tsadc */ .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ @@ -1045,8 +1184,8 @@ static const struct rockchip_tsadc_chip rk3328_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3366_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ + /* cpu, gpu */ + .chn_offset = 0, .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -1070,8 +1209,8 @@ static const struct rockchip_tsadc_chip rk3366_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3368_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ + /* cpu, gpu */ + .chn_offset = 0, .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -1095,8 +1234,8 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3399_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ + /* cpu, gpu */ + .chn_offset = 0, .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -1120,8 +1259,8 @@ static const struct rockchip_tsadc_chip rk3399_tsadc_data = { }; static const struct rockchip_tsadc_chip rk3568_tsadc_data = { - .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ - .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ + /* cpu, gpu */ + .chn_offset = 0, .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ @@ -1144,6 +1283,28 @@ static const struct rockchip_tsadc_chip rk3568_tsadc_data = { }, }; +static const struct rockchip_tsadc_chip rk3588_tsadc_data = { + /* top, big_core0, big_core1, little_core, center, gpu, npu */ + .chn_offset = 0, + .chn_num = 7, /* seven channels for tsadc */ + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + .initialize = rk_tsadcv8_initialize, + .irq_ack = rk_tsadcv4_irq_ack, + .control = rk_tsadcv4_control, + .get_temp = rk_tsadcv4_get_temp, + .set_alarm_temp = rk_tsadcv3_alarm_temp, + .set_tshut_temp = rk_tsadcv3_tshut_temp, + .set_tshut_mode = rk_tsadcv3_tshut_mode, + .table = { + .id = rk3588_code_table, + .length = ARRAY_SIZE(rk3588_code_table), + .data_mask = TSADCV4_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + static const struct of_device_id of_rockchip_thermal_match[] = { { .compatible = "rockchip,px30-tsadc", .data = (void *)&px30_tsadc_data, @@ -1180,6 +1341,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3568-tsadc", .data = (void *)&rk3568_tsadc_data, }, + { + .compatible = "rockchip,rk3588-tsadc", + .data = (void *)&rk3588_tsadc_data, + }, { /* end */ }, }; MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); @@ -1213,7 +1378,7 @@ static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev) static int rockchip_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct rockchip_thermal_sensor *sensor = tz->devdata; + struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz); struct rockchip_thermal_data *thermal = sensor->thermal; const struct rockchip_tsadc_chip *tsadc = thermal->chip; @@ -1226,16 +1391,13 @@ static int rockchip_thermal_set_trips(struct thermal_zone_device *tz, int low, i static int rockchip_thermal_get_temp(struct thermal_zone_device *tz, int *out_temp) { - struct rockchip_thermal_sensor *sensor = tz->devdata; + struct rockchip_thermal_sensor *sensor = thermal_zone_device_priv(tz); struct rockchip_thermal_data *thermal = sensor->thermal; const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; int retval; retval = tsadc->get_temp(&tsadc->table, sensor->id, thermal->regs, out_temp); - dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n", - sensor->id, *out_temp, retval); - return retval; } @@ -1353,15 +1515,10 @@ static int rockchip_thermal_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct rockchip_thermal_data *thermal; - const struct of_device_id *match; int irq; int i; int error; - match = of_match_node(of_rockchip_thermal_match, np); - if (!match) - return -ENXIO; - irq = platform_get_irq(pdev, 0); if (irq < 0) return -EINVAL; @@ -1373,57 +1530,40 @@ static int rockchip_thermal_probe(struct platform_device *pdev) thermal->pdev = pdev; - thermal->chip = (const struct rockchip_tsadc_chip *)match->data; + thermal->chip = device_get_match_data(&pdev->dev); if (!thermal->chip) return -EINVAL; + thermal->sensors = devm_kcalloc(&pdev->dev, thermal->chip->chn_num, + sizeof(*thermal->sensors), GFP_KERNEL); + if (!thermal->sensors) + return -ENOMEM; + thermal->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(thermal->regs)) return PTR_ERR(thermal->regs); - thermal->reset = devm_reset_control_array_get(&pdev->dev, false, false); - if (IS_ERR(thermal->reset)) { - error = PTR_ERR(thermal->reset); - dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error); - return error; - } - - thermal->clk = devm_clk_get(&pdev->dev, "tsadc"); - if (IS_ERR(thermal->clk)) { - error = PTR_ERR(thermal->clk); - dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error); - return error; - } + thermal->reset = devm_reset_control_array_get_exclusive(&pdev->dev); + if (IS_ERR(thermal->reset)) + return dev_err_probe(&pdev->dev, PTR_ERR(thermal->reset), + "failed to get tsadc reset.\n"); - thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); - if (IS_ERR(thermal->pclk)) { - error = PTR_ERR(thermal->pclk); - dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", - error); - return error; - } + thermal->clk = devm_clk_get_enabled(&pdev->dev, "tsadc"); + if (IS_ERR(thermal->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(thermal->clk), + "failed to get tsadc clock.\n"); - error = clk_prepare_enable(thermal->clk); - if (error) { - dev_err(&pdev->dev, "failed to enable converter clock: %d\n", - error); - return error; - } - - error = clk_prepare_enable(thermal->pclk); - if (error) { - dev_err(&pdev->dev, "failed to enable pclk: %d\n", error); - goto err_disable_clk; - } + thermal->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); + if (IS_ERR(thermal->pclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(thermal->pclk), + "failed to get apb_pclk clock.\n"); rockchip_thermal_reset_controller(thermal->reset); error = rockchip_configure_from_dt(&pdev->dev, np, thermal); - if (error) { - dev_err(&pdev->dev, "failed to parse device tree data: %d\n", - error); - goto err_disable_pclk; - } + if (error) + return dev_err_probe(&pdev->dev, error, + "failed to parse device tree data\n"); thermal->chip->initialize(thermal->grf, thermal->regs, thermal->tshut_polarity); @@ -1431,30 +1571,24 @@ static int rockchip_thermal_probe(struct platform_device *pdev) for (i = 0; i < thermal->chip->chn_num; i++) { error = rockchip_thermal_register_sensor(pdev, thermal, &thermal->sensors[i], - thermal->chip->chn_id[i]); - if (error) { - dev_err(&pdev->dev, - "failed to register sensor[%d] : error = %d\n", - i, error); - goto err_disable_pclk; - } + thermal->chip->chn_offset + i); + if (error) + return dev_err_probe(&pdev->dev, error, + "failed to register sensor[%d].\n", i); } error = devm_request_threaded_irq(&pdev->dev, irq, NULL, &rockchip_thermal_alarm_irq_thread, IRQF_ONESHOT, "rockchip_thermal", thermal); - if (error) { - dev_err(&pdev->dev, - "failed to request tsadc irq: %d\n", error); - goto err_disable_pclk; - } + if (error) + return dev_err_probe(&pdev->dev, error, + "failed to request tsadc irq.\n"); thermal->chip->control(thermal->regs, true); for (i = 0; i < thermal->chip->chn_num; i++) { rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); - thermal->sensors[i].tzd->tzp->no_hwmon = false; error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd); if (error) dev_warn(&pdev->dev, @@ -1465,13 +1599,6 @@ static int rockchip_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, thermal); return 0; - -err_disable_pclk: - clk_disable_unprepare(thermal->pclk); -err_disable_clk: - clk_disable_unprepare(thermal->clk); - - return error; } static int rockchip_thermal_remove(struct platform_device *pdev) @@ -1488,9 +1615,6 @@ static int rockchip_thermal_remove(struct platform_device *pdev) thermal->chip->control(thermal->regs, false); - clk_disable_unprepare(thermal->pclk); - clk_disable_unprepare(thermal->clk); - return 0; } diff --git a/drivers/thermal/rzg2l_thermal.c b/drivers/thermal/rzg2l_thermal.c index 2e0649f38506..b56981f85306 100644 --- a/drivers/thermal/rzg2l_thermal.c +++ b/drivers/thermal/rzg2l_thermal.c @@ -75,7 +75,7 @@ static inline void rzg2l_thermal_write(struct rzg2l_thermal_priv *priv, u32 reg, static int rzg2l_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct rzg2l_thermal_priv *priv = tz->devdata; + struct rzg2l_thermal_priv *priv = thermal_zone_device_priv(tz); u32 result = 0, dsensor, ts_code_ave; int val, i; @@ -216,7 +216,6 @@ static int rzg2l_thermal_probe(struct platform_device *pdev) } priv->zone = zone; - priv->zone->tzp->no_hwmon = false; ret = thermal_add_hwmon_sysfs(priv->zone); if (ret) goto err; diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 527d1eb0663a..45e5c840d130 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -645,7 +645,7 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) static int exynos_get_temp(struct thermal_zone_device *tz, int *temp) { - struct exynos_tmu_data *data = tz->devdata; + struct exynos_tmu_data *data = thermal_zone_device_priv(tz); int value, ret = 0; if (!data || !data->tmu_read) @@ -723,7 +723,7 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp) { - struct exynos_tmu_data *data = tz->devdata; + struct exynos_tmu_data *data = thermal_zone_device_priv(tz); int ret = -EINVAL; if (data->soc == SOC_ARCH_EXYNOS4210) diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c index 6a722b10d738..6e78616a576e 100644 --- a/drivers/thermal/spear_thermal.c +++ b/drivers/thermal/spear_thermal.c @@ -31,7 +31,7 @@ struct spear_thermal_dev { static inline int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) { - struct spear_thermal_dev *stdev = thermal->devdata; + struct spear_thermal_dev *stdev = thermal_zone_device_priv(thermal); /* * Data are ready to be read after 628 usec from POWERDOWN signal @@ -48,7 +48,7 @@ static struct thermal_zone_device_ops ops = { static int __maybe_unused spear_thermal_suspend(struct device *dev) { struct thermal_zone_device *spear_thermal = dev_get_drvdata(dev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; + struct spear_thermal_dev *stdev = thermal_zone_device_priv(spear_thermal); unsigned int actual_mask = 0; /* Disable SPEAr Thermal Sensor */ @@ -64,7 +64,7 @@ static int __maybe_unused spear_thermal_suspend(struct device *dev) static int __maybe_unused spear_thermal_resume(struct device *dev) { struct thermal_zone_device *spear_thermal = dev_get_drvdata(dev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; + struct spear_thermal_dev *stdev = thermal_zone_device_priv(spear_thermal); unsigned int actual_mask = 0; int ret = 0; @@ -137,7 +137,7 @@ static int spear_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, spear_thermal); - dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n", + dev_info(&pdev->dev, "Thermal Sensor Loaded at: 0x%p.\n", stdev->thermal_base); return 0; @@ -154,7 +154,7 @@ static int spear_thermal_exit(struct platform_device *pdev) { unsigned int actual_mask = 0; struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; + struct spear_thermal_dev *stdev = thermal_zone_device_priv(spear_thermal); thermal_zone_device_unregister(spear_thermal); diff --git a/drivers/thermal/sprd_thermal.c b/drivers/thermal/sprd_thermal.c index ac884514f116..2fb90fdad76e 100644 --- a/drivers/thermal/sprd_thermal.c +++ b/drivers/thermal/sprd_thermal.c @@ -206,7 +206,7 @@ static int sprd_thm_temp_to_rawdata(int temp, struct sprd_thermal_sensor *sen) static int sprd_thm_read_temp(struct thermal_zone_device *tz, int *temp) { - struct sprd_thermal_sensor *sen = tz->devdata; + struct sprd_thermal_sensor *sen = thermal_zone_device_priv(tz); u32 data; data = readl(sen->data->base + SPRD_THM_TEMP(sen->id)) & diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c index 1009f08e64e3..2d3042098445 100644 --- a/drivers/thermal/st/st_thermal.c +++ b/drivers/thermal/st/st_thermal.c @@ -108,8 +108,7 @@ static int st_thermal_calibration(struct st_thermal_sensor *sensor) /* Callback to get temperature from HW*/ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature) { - struct st_thermal_sensor *sensor = th->devdata; - struct device *dev = sensor->dev; + struct st_thermal_sensor *sensor = thermal_zone_device_priv(th); unsigned int temp; unsigned int overflow; int ret; @@ -127,8 +126,6 @@ static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature) temp += sensor->cdata->temp_adjust_val; temp = mcelsius(temp); - dev_dbg(dev, "temperature: %d\n", temp); - *temperature = temp; return 0; diff --git a/drivers/thermal/st/stm_thermal.c b/drivers/thermal/st/stm_thermal.c index 735401958f01..903fcf1763f1 100644 --- a/drivers/thermal/st/stm_thermal.c +++ b/drivers/thermal/st/stm_thermal.c @@ -303,7 +303,7 @@ static int stm_disable_irq(struct stm_thermal_sensor *sensor) static int stm_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct stm_thermal_sensor *sensor = tz->devdata; + struct stm_thermal_sensor *sensor = thermal_zone_device_priv(tz); u32 itr1, th; int ret; @@ -351,7 +351,7 @@ static int stm_thermal_set_trips(struct thermal_zone_device *tz, int low, int hi /* Callback to get temperature from HW */ static int stm_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct stm_thermal_sensor *sensor = tz->devdata; + struct stm_thermal_sensor *sensor = thermal_zone_device_priv(tz); u32 periods; int freqM, ret; @@ -558,7 +558,6 @@ static int stm_thermal_probe(struct platform_device *pdev) * Thermal_zone doesn't enable hwmon as default, * enable it here */ - sensor->th_dev->tzp->no_hwmon = false; ret = thermal_add_hwmon_sysfs(sensor->th_dev); if (ret) goto err_tz; diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index 497beac63e5d..793ddce72132 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -110,7 +110,7 @@ static int sun50i_h5_calc_temp(struct ths_device *tmdev, static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp) { - struct tsensor *s = tz->devdata; + struct tsensor *s = thermal_zone_device_priv(tz); struct ths_device *tmdev = s->tmdev; int val = 0; @@ -475,7 +475,7 @@ static int sun8i_ths_register(struct ths_device *tmdev) if (IS_ERR(tmdev->sensor[i].tzd)) return PTR_ERR(tmdev->sensor[i].tzd); - if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd)) + if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd)) dev_warn(tmdev->dev, "Failed to add hwmon sysfs attributes\n"); } diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index 220873298d77..ea66cba09e56 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -423,7 +423,7 @@ static int translate_temp(u16 val) static int tegra_thermctl_get_temp(struct thermal_zone_device *tz, int *out_temp) { - struct tegra_thermctl_zone *zone = tz->devdata; + struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz); u32 val; val = readl(zone->reg); @@ -584,7 +584,7 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id) static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { - struct tegra_thermctl_zone *zone = tz->devdata; + struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz); struct tegra_soctherm *ts = zone->ts; struct thermal_trip trip; const struct tegra_tsensor_group *sg = zone->sg; @@ -658,7 +658,7 @@ static void thermal_irq_disable(struct tegra_thermctl_zone *zn) static int tegra_thermctl_set_trips(struct thermal_zone_device *tz, int lo, int hi) { - struct tegra_thermctl_zone *zone = tz->devdata; + struct tegra_thermctl_zone *zone = thermal_zone_device_priv(tz); u32 r; thermal_irq_disable(zone); diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c index 0b7a1a1948cb..a2879d624945 100644 --- a/drivers/thermal/tegra/tegra-bpmp-thermal.c +++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c @@ -52,6 +52,8 @@ static int __tegra_bpmp_thermal_get_temp(struct tegra_bpmp_thermal_zone *zone, err = tegra_bpmp_transfer(zone->tegra->bpmp, &msg); if (err) return err; + if (msg.rx.ret == -BPMP_EFAULT) + return -EAGAIN; if (msg.rx.ret) return -EINVAL; @@ -62,12 +64,14 @@ static int __tegra_bpmp_thermal_get_temp(struct tegra_bpmp_thermal_zone *zone, static int tegra_bpmp_thermal_get_temp(struct thermal_zone_device *tz, int *out_temp) { - return __tegra_bpmp_thermal_get_temp(tz->devdata, out_temp); + struct tegra_bpmp_thermal_zone *zone = thermal_zone_device_priv(tz); + + return __tegra_bpmp_thermal_get_temp(zone, out_temp); } static int tegra_bpmp_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) { - struct tegra_bpmp_thermal_zone *zone = tz->devdata; + struct tegra_bpmp_thermal_zone *zone = thermal_zone_device_priv(tz); struct mrq_thermal_host_to_bpmp_request req; struct tegra_bpmp_message msg; int err; @@ -207,7 +211,12 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev) zone->tegra = tegra; err = __tegra_bpmp_thermal_get_temp(zone, &temp); - if (err < 0) { + + /* + * Sensors in powergated domains may temporarily fail to be read + * (-EAGAIN), but will become accessible when the domain is powered on. + */ + if (err < 0 && err != -EAGAIN) { devm_kfree(&pdev->dev, zone); continue; } diff --git a/drivers/thermal/tegra/tegra30-tsensor.c b/drivers/thermal/tegra/tegra30-tsensor.c index b3218b71b6d9..cb584a5735ed 100644 --- a/drivers/thermal/tegra/tegra30-tsensor.c +++ b/drivers/thermal/tegra/tegra30-tsensor.c @@ -160,7 +160,7 @@ static void devm_tegra_tsensor_hw_disable(void *data) static int tegra_tsensor_get_temp(struct thermal_zone_device *tz, int *temp) { - const struct tegra_tsensor_channel *tsc = tz->devdata; + const struct tegra_tsensor_channel *tsc = thermal_zone_device_priv(tz); const struct tegra_tsensor *ts = tsc->ts; int err, c1, c2, c3, c4, counter; u32 val; @@ -218,7 +218,7 @@ static int tegra_tsensor_temp_to_counter(const struct tegra_tsensor *ts, int tem static int tegra_tsensor_set_trips(struct thermal_zone_device *tz, int low, int high) { - const struct tegra_tsensor_channel *tsc = tz->devdata; + const struct tegra_tsensor_channel *tsc = thermal_zone_device_priv(tz); const struct tegra_tsensor *ts = tsc->ts; u32 val; @@ -359,9 +359,6 @@ static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts, tegra_tsensor_get_hw_channel_trips(tzd, &hot_trip, &crit_trip); - /* prevent potential racing with tegra_tsensor_set_trips() */ - mutex_lock(&tzd->lock); - dev_info_once(ts->dev, "ch%u: PMC emergency shutdown trip set to %dC\n", id, DIV_ROUND_CLOSEST(crit_trip, 1000)); @@ -404,8 +401,6 @@ static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts, val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG0_INTR_THERMAL_RST_EN, 1); writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0); - mutex_unlock(&tzd->lock); - err = thermal_zone_device_enable(tzd); if (err) { dev_err(ts->dev, "ch%u: failed to enable zone: %d\n", id, err); @@ -528,7 +523,7 @@ static int tegra_tsensor_register_channel(struct tegra_tsensor *ts, return 0; } - if (devm_thermal_add_hwmon_sysfs(tsc->tzd)) + if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd)) dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n"); return 0; @@ -585,6 +580,20 @@ static int tegra_tsensor_probe(struct platform_device *pdev) return err; } + /* + * Enable the channels before setting the interrupt so + * set_trips() can not be called while we are setting up the + * register TSENSOR_SENSOR0_CONFIG1. With this we close a + * potential race window where we are setting up the TH2 and + * the temperature hits TH1 resulting to an update of the + * TSENSOR_SENSOR0_CONFIG1 register in the ISR. + */ + for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { + err = tegra_tsensor_enable_hw_channel(ts, i); + if (err) + return err; + } + err = devm_request_threaded_irq(&pdev->dev, irq, NULL, tegra_tsensor_isr, IRQF_ONESHOT, "tegra_tsensor", ts); @@ -592,12 +601,6 @@ static int tegra_tsensor_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, err, "failed to request interrupt\n"); - for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { - err = tegra_tsensor_enable_hw_channel(ts, i); - if (err) - return err; - } - return 0; } diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index 323e273e3298..017b0ce52122 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -54,15 +54,14 @@ static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) static int gadc_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { - struct gadc_thermal_info *gti = tz->devdata; + struct gadc_thermal_info *gti = thermal_zone_device_priv(tz); int val; int ret; ret = iio_read_channel_processed(gti->channel, &val); - if (ret < 0) { - dev_err(gti->dev, "IIO channel read failed %d\n", ret); + if (ret < 0) return ret; - } + *temp = gadc_thermal_adc_to_temp(gti, val); return 0; diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 55679fd86505..c5025aca22ee 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -22,7 +22,7 @@ #include <linux/suspend.h> #define CREATE_TRACE_POINTS -#include <trace/events/thermal.h> +#include "thermal_trace.h" #include "thermal_core.h" #include "thermal_hwmon.h" @@ -613,6 +613,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, struct thermal_instance *pos; struct thermal_zone_device *pos1; struct thermal_cooling_device *pos2; + bool upper_no_limit; int result; if (trip >= tz->num_trips || trip < 0) @@ -632,7 +633,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, /* lower default 0, upper default max_state */ lower = lower == THERMAL_NO_LIMIT ? 0 : lower; - upper = upper == THERMAL_NO_LIMIT ? cdev->max_state : upper; + + if (upper == THERMAL_NO_LIMIT) { + upper = cdev->max_state; + upper_no_limit = true; + } else { + upper_no_limit = false; + } if (lower > upper || upper > cdev->max_state) return -EINVAL; @@ -644,6 +651,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, dev->cdev = cdev; dev->trip = trip; dev->upper = upper; + dev->upper_no_limit = upper_no_limit; dev->lower = lower; dev->target = THERMAL_NO_TARGET; dev->weight = weight; @@ -786,68 +794,18 @@ void print_bind_err_msg(struct thermal_zone_device *tz, tz->type, cdev->type, ret); } -static void __bind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev, - unsigned long *limits, - unsigned int weight) -{ - int i, ret; - - for (i = 0; i < tz->num_trips; i++) { - if (mask & (1 << i)) { - unsigned long upper, lower; - - upper = THERMAL_NO_LIMIT; - lower = THERMAL_NO_LIMIT; - if (limits) { - lower = limits[i * 2]; - upper = limits[i * 2 + 1]; - } - ret = thermal_zone_bind_cooling_device(tz, i, cdev, - upper, lower, - weight); - if (ret) - print_bind_err_msg(tz, cdev, ret); - } - } -} - static void bind_cdev(struct thermal_cooling_device *cdev) { - int i, ret; - const struct thermal_zone_params *tzp; + int ret; struct thermal_zone_device *pos = NULL; - mutex_lock(&thermal_list_lock); - list_for_each_entry(pos, &thermal_tz_list, node) { - if (!pos->tzp && !pos->ops->bind) - continue; - if (pos->ops->bind) { ret = pos->ops->bind(pos, cdev); if (ret) print_bind_err_msg(pos, cdev, ret); - continue; - } - - tzp = pos->tzp; - if (!tzp || !tzp->tbp) - continue; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(pos, cdev)) - continue; - tzp->tbp[i].cdev = cdev; - __bind(pos, tzp->tbp[i].trip_mask, cdev, - tzp->tbp[i].binding_limits, - tzp->tbp[i].weight); } } - - mutex_unlock(&thermal_list_lock); } /** @@ -925,17 +883,17 @@ __thermal_cooling_device_register(struct device_node *np, /* Add 'this' new cdev to the global cdev list */ mutex_lock(&thermal_list_lock); + list_add(&cdev->node, &thermal_cdev_list); - mutex_unlock(&thermal_list_lock); /* Update binding information for 'this' new cdev */ bind_cdev(cdev); - mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) if (atomic_cmpxchg(&pos->need_update, 1, 0)) thermal_zone_device_update(pos, THERMAL_EVENT_UNSPECIFIED); + mutex_unlock(&thermal_list_lock); return cdev; @@ -1045,17 +1003,92 @@ devm_thermal_of_cooling_device_register(struct device *dev, } EXPORT_SYMBOL_GPL(devm_thermal_of_cooling_device_register); -static void __unbind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev) +static bool thermal_cooling_device_present(struct thermal_cooling_device *cdev) { - int i; + struct thermal_cooling_device *pos = NULL; + + list_for_each_entry(pos, &thermal_cdev_list, node) { + if (pos == cdev) + return true; + } - for (i = 0; i < tz->num_trips; i++) - if (mask & (1 << i)) - thermal_zone_unbind_cooling_device(tz, i, cdev); + return false; } /** + * thermal_cooling_device_update - Update a cooling device object + * @cdev: Target cooling device. + * + * Update @cdev to reflect a change of the underlying hardware or platform. + * + * Must be called when the maximum cooling state of @cdev becomes invalid and so + * its .get_max_state() callback needs to be run to produce the new maximum + * cooling state value. + */ +void thermal_cooling_device_update(struct thermal_cooling_device *cdev) +{ + struct thermal_instance *ti; + unsigned long state; + + if (IS_ERR_OR_NULL(cdev)) + return; + + /* + * Hold thermal_list_lock throughout the update to prevent the device + * from going away while being updated. + */ + mutex_lock(&thermal_list_lock); + + if (!thermal_cooling_device_present(cdev)) + goto unlock_list; + + /* + * Update under the cdev lock to prevent the state from being set beyond + * the new limit concurrently. + */ + mutex_lock(&cdev->lock); + + if (cdev->ops->get_max_state(cdev, &cdev->max_state)) + goto unlock; + + thermal_cooling_device_stats_reinit(cdev); + + list_for_each_entry(ti, &cdev->thermal_instances, cdev_node) { + if (ti->upper == cdev->max_state) + continue; + + if (ti->upper < cdev->max_state) { + if (ti->upper_no_limit) + ti->upper = cdev->max_state; + + continue; + } + + ti->upper = cdev->max_state; + if (ti->lower > ti->upper) + ti->lower = ti->upper; + + if (ti->target == THERMAL_NO_TARGET) + continue; + + if (ti->target > ti->upper) + ti->target = ti->upper; + } + + if (cdev->ops->get_cur_state(cdev, &state) || state > cdev->max_state) + goto unlock; + + thermal_cooling_device_stats_update(cdev, state); + +unlock: + mutex_unlock(&cdev->lock); + +unlock_list: + mutex_unlock(&thermal_list_lock); +} +EXPORT_SYMBOL_GPL(thermal_cooling_device_update); + +/** * thermal_cooling_device_unregister - removes a thermal cooling device * @cdev: the thermal cooling device to remove. * @@ -1064,42 +1097,24 @@ static void __unbind(struct thermal_zone_device *tz, int mask, */ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) { - int i; - const struct thermal_zone_params *tzp; struct thermal_zone_device *tz; - struct thermal_cooling_device *pos = NULL; if (!cdev) return; mutex_lock(&thermal_list_lock); - list_for_each_entry(pos, &thermal_cdev_list, node) - if (pos == cdev) - break; - if (pos != cdev) { - /* thermal cooling device not found */ + + if (!thermal_cooling_device_present(cdev)) { mutex_unlock(&thermal_list_lock); return; } + list_del(&cdev->node); /* Unbind all thermal zones associated with 'this' cdev */ list_for_each_entry(tz, &thermal_tz_list, node) { - if (tz->ops->unbind) { + if (tz->ops->unbind) tz->ops->unbind(tz, cdev); - continue; - } - - if (!tz->tzp || !tz->tzp->tbp) - continue; - - tzp = tz->tzp; - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } } mutex_unlock(&thermal_list_lock); @@ -1110,41 +1125,20 @@ EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister); static void bind_tz(struct thermal_zone_device *tz) { - int i, ret; + int ret; struct thermal_cooling_device *pos = NULL; - const struct thermal_zone_params *tzp = tz->tzp; - if (!tzp && !tz->ops->bind) + if (!tz->ops->bind) return; mutex_lock(&thermal_list_lock); - /* If there is ops->bind, try to use ops->bind */ - if (tz->ops->bind) { - list_for_each_entry(pos, &thermal_cdev_list, node) { - ret = tz->ops->bind(tz, pos); - if (ret) - print_bind_err_msg(tz, pos, ret); - } - goto exit; - } - - if (!tzp || !tzp->tbp) - goto exit; - list_for_each_entry(pos, &thermal_cdev_list, node) { - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(tz, pos)) - continue; - tzp->tbp[i].cdev = pos; - __bind(tz, tzp->tbp[i].trip_mask, pos, - tzp->tbp[i].binding_limits, - tzp->tbp[i].weight); - } + ret = tz->ops->bind(tz, pos); + if (ret) + print_bind_err_msg(tz, pos, ret); } -exit: + mutex_unlock(&thermal_list_lock); } @@ -1262,13 +1256,21 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t if (!tz) return ERR_PTR(-ENOMEM); + if (tzp) { + tz->tzp = kmemdup(tzp, sizeof(*tzp), GFP_KERNEL); + if (!tz->tzp) { + result = -ENOMEM; + goto free_tz; + } + } + INIT_LIST_HEAD(&tz->thermal_instances); ida_init(&tz->ida); mutex_init(&tz->lock); id = ida_alloc(&thermal_tz_ida, GFP_KERNEL); if (id < 0) { result = id; - goto free_tz; + goto free_tzp; } tz->id = id; @@ -1278,7 +1280,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ops->critical = thermal_zone_device_critical; tz->ops = ops; - tz->tzp = tzp; tz->device.class = thermal_class; tz->devdata = devdata; tz->trips = trips; @@ -1309,7 +1310,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t struct thermal_trip trip; result = thermal_zone_get_trip(tz, count, &trip); - if (result) + if (result || !trip.temperature) set_bit(count, &tz->trips_disabled); } @@ -1360,6 +1361,8 @@ release_device: tz = NULL; remove_id: ida_free(&thermal_tz_ida, id); +free_tzp: + kfree(tz->tzp); free_tz: kfree(tz); return ERR_PTR(result); @@ -1377,21 +1380,37 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, int n } EXPORT_SYMBOL_GPL(thermal_zone_device_register); +void *thermal_zone_device_priv(struct thermal_zone_device *tzd) +{ + return tzd->devdata; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_priv); + +const char *thermal_zone_device_type(struct thermal_zone_device *tzd) +{ + return tzd->type; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_type); + +int thermal_zone_device_id(struct thermal_zone_device *tzd) +{ + return tzd->id; +} +EXPORT_SYMBOL_GPL(thermal_zone_device_id); + /** * thermal_zone_device_unregister - removes the registered thermal zone device * @tz: the thermal zone device to remove */ void thermal_zone_device_unregister(struct thermal_zone_device *tz) { - int i, tz_id; - const struct thermal_zone_params *tzp; + int tz_id; struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; if (!tz) return; - tzp = tz->tzp; tz_id = tz->id; mutex_lock(&thermal_list_lock); @@ -1406,22 +1425,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) list_del(&tz->node); /* Unbind all cdevs associated with 'this' thermal zone */ - list_for_each_entry(cdev, &thermal_cdev_list, node) { - if (tz->ops->unbind) { + list_for_each_entry(cdev, &thermal_cdev_list, node) + if (tz->ops->unbind) tz->ops->unbind(tz, cdev); - continue; - } - - if (!tzp || !tzp->tbp) - break; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } - } mutex_unlock(&thermal_list_lock); @@ -1437,6 +1443,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) device_del(&tz->device); mutex_unlock(&tz->lock); + kfree(tz->tzp); + put_device(&tz->device); thermal_notify_tz_delete(tz_id); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 7af54382e915..3d4a787c6b28 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -101,6 +101,7 @@ struct thermal_instance { struct list_head tz_node; /* node in tz->thermal_instances */ struct list_head cdev_node; /* node in cdev->thermal_instances */ unsigned int weight; /* The weight of the cooling device */ + bool upper_no_limit; }; #define to_thermal_zone(_dev) \ @@ -127,6 +128,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *, int); void thermal_zone_destroy_device_groups(struct thermal_zone_device *); void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *); void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev); +void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev); /* used only at binding time */ ssize_t trip_point_show(struct device *, struct device_attribute *, char *); ssize_t weight_show(struct device *, struct device_attribute *, char *); diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index 0f648131b0b5..cfba0965a22d 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -19,9 +19,8 @@ #include <linux/string.h> #include <linux/sysfs.h> -#include <trace/events/thermal.h> - #include "thermal_core.h" +#include "thermal_trace.h" int get_tz_trend(struct thermal_zone_device *tz, int trip) { @@ -107,6 +106,9 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) *temp = tz->emul_temperature; } + if (ret) + dev_dbg(&tz->device, "Failed to get temperature: %d\n", ret); + return ret; } diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index c594c42bea6d..fbe55509e307 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -17,6 +17,7 @@ #include <linux/thermal.h> #include "thermal_hwmon.h" +#include "thermal_core.h" /* hwmon sys I/F */ /* thermal zone devices with the same type share one hwmon device */ @@ -263,7 +264,7 @@ static void devm_thermal_hwmon_release(struct device *dev, void *res) thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res); } -int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) +int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz) { struct thermal_zone_device **ptr; int ret; @@ -280,7 +281,7 @@ int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) } *ptr = tz; - devres_add(&tz->device, ptr); + devres_add(dev, ptr); return ret; } diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h index 1a9d65f6a6a8..b429f6e7abdb 100644 --- a/drivers/thermal/thermal_hwmon.h +++ b/drivers/thermal/thermal_hwmon.h @@ -17,7 +17,7 @@ #ifdef CONFIG_THERMAL_HWMON int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); -int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz); +int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz); void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz); #else static inline int @@ -27,7 +27,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) } static inline int -devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) +devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz) { return 0; } diff --git a/drivers/thermal/thermal_mmio.c b/drivers/thermal/thermal_mmio.c index ea616731066c..6845756ad5e7 100644 --- a/drivers/thermal/thermal_mmio.c +++ b/drivers/thermal/thermal_mmio.c @@ -23,7 +23,7 @@ static u32 thermal_mmio_readb(void __iomem *mmio_base) static int thermal_mmio_get_temperature(struct thermal_zone_device *tz, int *temp) { int t; - struct thermal_mmio *sensor = tz->devdata; + struct thermal_mmio *sensor = thermal_zone_device_priv(tz); t = sensor->read_mmio(sensor->mmio_base) & sensor->mask; t *= sensor->factor; diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index ff4d12ef51bc..6fb14e521197 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -439,7 +439,7 @@ static int thermal_of_unbind(struct thermal_zone_device *tz, * * @tz: a pointer to the thermal zone structure */ -void thermal_of_zone_unregister(struct thermal_zone_device *tz) +static void thermal_of_zone_unregister(struct thermal_zone_device *tz) { struct thermal_trip *trips = tz->trips; struct thermal_zone_params *tzp = tz->tzp; @@ -451,7 +451,6 @@ void thermal_of_zone_unregister(struct thermal_zone_device *tz) kfree(tzp); kfree(ops); } -EXPORT_SYMBOL_GPL(thermal_of_zone_unregister); /** * thermal_of_zone_register - Register a thermal zone with device node @@ -473,8 +472,8 @@ EXPORT_SYMBOL_GPL(thermal_of_zone_unregister); * - ENOMEM: if one structure can not be allocated * - Other negative errors are returned by the underlying called functions */ -struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, - const struct thermal_zone_device_ops *ops) +static struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, + const struct thermal_zone_device_ops *ops) { struct thermal_zone_device *tz; struct thermal_trip *trips; @@ -550,7 +549,6 @@ out_kfree_of_ops: return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(thermal_of_zone_register); static void devm_thermal_of_zone_release(struct device *dev, void *res) { diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index cef860deaf91..6c20c9f90a05 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -685,6 +685,8 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, { struct cooling_dev_stats *stats = cdev->stats; + lockdep_assert_held(&cdev->lock); + if (!stats) return; @@ -706,13 +708,22 @@ static ssize_t total_trans_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_cooling_device *cdev = to_cooling_device(dev); - struct cooling_dev_stats *stats = cdev->stats; - int ret; + struct cooling_dev_stats *stats; + int ret = 0; + + mutex_lock(&cdev->lock); + + stats = cdev->stats; + if (!stats) + goto unlock; spin_lock(&stats->lock); ret = sprintf(buf, "%u\n", stats->total_trans); spin_unlock(&stats->lock); +unlock: + mutex_unlock(&cdev->lock); + return ret; } @@ -721,11 +732,18 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_cooling_device *cdev = to_cooling_device(dev); - struct cooling_dev_stats *stats = cdev->stats; + struct cooling_dev_stats *stats; ssize_t len = 0; int i; + mutex_lock(&cdev->lock); + + stats = cdev->stats; + if (!stats) + goto unlock; + spin_lock(&stats->lock); + update_time_in_state(stats); for (i = 0; i <= cdev->max_state; i++) { @@ -734,6 +752,9 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr, } spin_unlock(&stats->lock); +unlock: + mutex_unlock(&cdev->lock); + return len; } @@ -742,8 +763,16 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_cooling_device *cdev = to_cooling_device(dev); - struct cooling_dev_stats *stats = cdev->stats; - int i, states = cdev->max_state + 1; + struct cooling_dev_stats *stats; + int i, states; + + mutex_lock(&cdev->lock); + + stats = cdev->stats; + if (!stats) + goto unlock; + + states = cdev->max_state + 1; spin_lock(&stats->lock); @@ -757,6 +786,9 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf, spin_unlock(&stats->lock); +unlock: + mutex_unlock(&cdev->lock); + return count; } @@ -764,10 +796,18 @@ static ssize_t trans_table_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_cooling_device *cdev = to_cooling_device(dev); - struct cooling_dev_stats *stats = cdev->stats; + struct cooling_dev_stats *stats; ssize_t len = 0; int i, j; + mutex_lock(&cdev->lock); + + stats = cdev->stats; + if (!stats) { + len = -ENODATA; + goto unlock; + } + len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); len += snprintf(buf + len, PAGE_SIZE - len, " : "); for (i = 0; i <= cdev->max_state; i++) { @@ -775,8 +815,10 @@ static ssize_t trans_table_show(struct device *dev, break; len += snprintf(buf + len, PAGE_SIZE - len, "state%2u ", i); } - if (len >= PAGE_SIZE) - return PAGE_SIZE; + if (len >= PAGE_SIZE) { + len = PAGE_SIZE; + goto unlock; + } len += snprintf(buf + len, PAGE_SIZE - len, "\n"); @@ -799,8 +841,12 @@ static ssize_t trans_table_show(struct device *dev, if (len >= PAGE_SIZE) { pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n"); - return -EFBIG; + len = -EFBIG; } + +unlock: + mutex_unlock(&cdev->lock); + return len; } @@ -879,6 +925,14 @@ void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev) cooling_device_stats_destroy(cdev); } +void thermal_cooling_device_stats_reinit(struct thermal_cooling_device *cdev) +{ + lockdep_assert_held(&cdev->lock); + + cooling_device_stats_destroy(cdev); + cooling_device_stats_setup(cdev); +} + /* these helper will be used only at the time of bindig */ ssize_t trip_point_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/thermal/thermal_trace.h b/drivers/thermal/thermal_trace.h new file mode 100644 index 000000000000..459c8ce6cf3b --- /dev/null +++ b/drivers/thermal/thermal_trace.h @@ -0,0 +1,205 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM thermal + +#if !defined(_TRACE_THERMAL_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_THERMAL_H + +#include <linux/devfreq.h> +#include <linux/thermal.h> +#include <linux/tracepoint.h> + +TRACE_DEFINE_ENUM(THERMAL_TRIP_CRITICAL); +TRACE_DEFINE_ENUM(THERMAL_TRIP_HOT); +TRACE_DEFINE_ENUM(THERMAL_TRIP_PASSIVE); +TRACE_DEFINE_ENUM(THERMAL_TRIP_ACTIVE); + +#define show_tzt_type(type) \ + __print_symbolic(type, \ + { THERMAL_TRIP_CRITICAL, "CRITICAL"}, \ + { THERMAL_TRIP_HOT, "HOT"}, \ + { THERMAL_TRIP_PASSIVE, "PASSIVE"}, \ + { THERMAL_TRIP_ACTIVE, "ACTIVE"}) + +TRACE_EVENT(thermal_temperature, + + TP_PROTO(struct thermal_zone_device *tz), + + TP_ARGS(tz), + + TP_STRUCT__entry( + __string(thermal_zone, tz->type) + __field(int, id) + __field(int, temp_prev) + __field(int, temp) + ), + + TP_fast_assign( + __assign_str(thermal_zone, tz->type); + __entry->id = tz->id; + __entry->temp_prev = tz->last_temperature; + __entry->temp = tz->temperature; + ), + + TP_printk("thermal_zone=%s id=%d temp_prev=%d temp=%d", + __get_str(thermal_zone), __entry->id, __entry->temp_prev, + __entry->temp) +); + +TRACE_EVENT(cdev_update, + + TP_PROTO(struct thermal_cooling_device *cdev, unsigned long target), + + TP_ARGS(cdev, target), + + TP_STRUCT__entry( + __string(type, cdev->type) + __field(unsigned long, target) + ), + + TP_fast_assign( + __assign_str(type, cdev->type); + __entry->target = target; + ), + + TP_printk("type=%s target=%lu", __get_str(type), __entry->target) +); + +TRACE_EVENT(thermal_zone_trip, + + TP_PROTO(struct thermal_zone_device *tz, int trip, + enum thermal_trip_type trip_type), + + TP_ARGS(tz, trip, trip_type), + + TP_STRUCT__entry( + __string(thermal_zone, tz->type) + __field(int, id) + __field(int, trip) + __field(enum thermal_trip_type, trip_type) + ), + + TP_fast_assign( + __assign_str(thermal_zone, tz->type); + __entry->id = tz->id; + __entry->trip = trip; + __entry->trip_type = trip_type; + ), + + TP_printk("thermal_zone=%s id=%d trip=%d trip_type=%s", + __get_str(thermal_zone), __entry->id, __entry->trip, + show_tzt_type(__entry->trip_type)) +); + +#ifdef CONFIG_CPU_THERMAL +TRACE_EVENT(thermal_power_cpu_get_power_simple, + TP_PROTO(int cpu, u32 power), + + TP_ARGS(cpu, power), + + TP_STRUCT__entry( + __field(int, cpu) + __field(u32, power) + ), + + TP_fast_assign( + __entry->cpu = cpu; + __entry->power = power; + ), + + TP_printk("cpu=%d power=%u", __entry->cpu, __entry->power) +); + +TRACE_EVENT(thermal_power_cpu_limit, + TP_PROTO(const struct cpumask *cpus, unsigned int freq, + unsigned long cdev_state, u32 power), + + TP_ARGS(cpus, freq, cdev_state, power), + + TP_STRUCT__entry( + __bitmask(cpumask, num_possible_cpus()) + __field(unsigned int, freq ) + __field(unsigned long, cdev_state) + __field(u32, power ) + ), + + TP_fast_assign( + __assign_bitmask(cpumask, cpumask_bits(cpus), + num_possible_cpus()); + __entry->freq = freq; + __entry->cdev_state = cdev_state; + __entry->power = power; + ), + + TP_printk("cpus=%s freq=%u cdev_state=%lu power=%u", + __get_bitmask(cpumask), __entry->freq, __entry->cdev_state, + __entry->power) +); +#endif /* CONFIG_CPU_THERMAL */ + +#ifdef CONFIG_DEVFREQ_THERMAL +TRACE_EVENT(thermal_power_devfreq_get_power, + TP_PROTO(struct thermal_cooling_device *cdev, + struct devfreq_dev_status *status, unsigned long freq, + u32 power), + + TP_ARGS(cdev, status, freq, power), + + TP_STRUCT__entry( + __string(type, cdev->type ) + __field(unsigned long, freq ) + __field(u32, busy_time) + __field(u32, total_time) + __field(u32, power) + ), + + TP_fast_assign( + __assign_str(type, cdev->type); + __entry->freq = freq; + __entry->busy_time = status->busy_time; + __entry->total_time = status->total_time; + __entry->power = power; + ), + + TP_printk("type=%s freq=%lu load=%u power=%u", + __get_str(type), __entry->freq, + __entry->total_time == 0 ? 0 : + (100 * __entry->busy_time) / __entry->total_time, + __entry->power) +); + +TRACE_EVENT(thermal_power_devfreq_limit, + TP_PROTO(struct thermal_cooling_device *cdev, unsigned long freq, + unsigned long cdev_state, u32 power), + + TP_ARGS(cdev, freq, cdev_state, power), + + TP_STRUCT__entry( + __string(type, cdev->type) + __field(unsigned int, freq ) + __field(unsigned long, cdev_state) + __field(u32, power ) + ), + + TP_fast_assign( + __assign_str(type, cdev->type); + __entry->freq = freq; + __entry->cdev_state = cdev_state; + __entry->power = power; + ), + + TP_printk("type=%s freq=%u cdev_state=%lu power=%u", + __get_str(type), __entry->freq, __entry->cdev_state, + __entry->power) +); +#endif /* CONFIG_DEVFREQ_THERMAL */ +#endif /* _TRACE_THERMAL_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE thermal_trace + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/thermal/thermal_trace_ipa.h b/drivers/thermal/thermal_trace_ipa.h new file mode 100644 index 000000000000..84568db5421b --- /dev/null +++ b/drivers/thermal/thermal_trace_ipa.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM thermal_power_allocator + +#if !defined(_TRACE_THERMAL_POWER_ALLOCATOR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_THERMAL_POWER_ALLOCATOR_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(thermal_power_allocator, + TP_PROTO(struct thermal_zone_device *tz, u32 *req_power, + u32 total_req_power, u32 *granted_power, + u32 total_granted_power, size_t num_actors, + u32 power_range, u32 max_allocatable_power, + int current_temp, s32 delta_temp), + TP_ARGS(tz, req_power, total_req_power, granted_power, + total_granted_power, num_actors, power_range, + max_allocatable_power, current_temp, delta_temp), + TP_STRUCT__entry( + __field(int, tz_id ) + __dynamic_array(u32, req_power, num_actors ) + __field(u32, total_req_power ) + __dynamic_array(u32, granted_power, num_actors) + __field(u32, total_granted_power ) + __field(size_t, num_actors ) + __field(u32, power_range ) + __field(u32, max_allocatable_power ) + __field(int, current_temp ) + __field(s32, delta_temp ) + ), + TP_fast_assign( + __entry->tz_id = tz->id; + memcpy(__get_dynamic_array(req_power), req_power, + num_actors * sizeof(*req_power)); + __entry->total_req_power = total_req_power; + memcpy(__get_dynamic_array(granted_power), granted_power, + num_actors * sizeof(*granted_power)); + __entry->total_granted_power = total_granted_power; + __entry->num_actors = num_actors; + __entry->power_range = power_range; + __entry->max_allocatable_power = max_allocatable_power; + __entry->current_temp = current_temp; + __entry->delta_temp = delta_temp; + ), + + TP_printk("thermal_zone_id=%d req_power={%s} total_req_power=%u granted_power={%s} total_granted_power=%u power_range=%u max_allocatable_power=%u current_temperature=%d delta_temperature=%d", + __entry->tz_id, + __print_array(__get_dynamic_array(req_power), + __entry->num_actors, 4), + __entry->total_req_power, + __print_array(__get_dynamic_array(granted_power), + __entry->num_actors, 4), + __entry->total_granted_power, __entry->power_range, + __entry->max_allocatable_power, __entry->current_temp, + __entry->delta_temp) +); + +TRACE_EVENT(thermal_power_allocator_pid, + TP_PROTO(struct thermal_zone_device *tz, s32 err, s32 err_integral, + s64 p, s64 i, s64 d, s32 output), + TP_ARGS(tz, err, err_integral, p, i, d, output), + TP_STRUCT__entry( + __field(int, tz_id ) + __field(s32, err ) + __field(s32, err_integral) + __field(s64, p ) + __field(s64, i ) + __field(s64, d ) + __field(s32, output ) + ), + TP_fast_assign( + __entry->tz_id = tz->id; + __entry->err = err; + __entry->err_integral = err_integral; + __entry->p = p; + __entry->i = i; + __entry->d = d; + __entry->output = output; + ), + + TP_printk("thermal_zone_id=%d err=%d err_integral=%d p=%lld i=%lld d=%lld output=%d", + __entry->tz_id, __entry->err, __entry->err_integral, + __entry->p, __entry->i, __entry->d, __entry->output) +); +#endif /* _TRACE_THERMAL_POWER_ALLOCATOR_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE thermal_trace_ipa + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 8a9055bd376e..6a5335931f4d 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -23,6 +23,8 @@ #include "ti-bandgap.h" #include "../thermal_hwmon.h" +#define TI_BANDGAP_UPDATE_INTERVAL_MS 250 + /* common data structures */ struct ti_thermal_data { struct cpufreq_policy *policy; @@ -43,8 +45,8 @@ static void ti_thermal_work(struct work_struct *work) thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED); - dev_dbg(&data->ti_thermal->device, "updated thermal zone %s\n", - data->ti_thermal->type); + dev_dbg(data->bgp->dev, "updated thermal zone %s\n", + thermal_zone_device_type(data->ti_thermal)); } /** @@ -68,7 +70,7 @@ static inline int ti_thermal_hotspot_temperature(int t, int s, int c) static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *temp) { struct thermal_zone_device *pcb_tz = NULL; - struct ti_thermal_data *data = tz->devdata; + struct ti_thermal_data *data = thermal_zone_device_priv(tz); struct ti_bandgap *bgp; const struct ti_temp_sensor *s; int ret, tmp, slope, constant; @@ -109,7 +111,7 @@ static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *tem static int __ti_thermal_get_trend(struct thermal_zone_device *tz, int trip, enum thermal_trend *trend) { - struct ti_thermal_data *data = tz->devdata; + struct ti_thermal_data *data = thermal_zone_device_priv(tz); struct ti_bandgap *bgp; int id, tr, ret = 0; @@ -159,7 +161,6 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain) { struct ti_thermal_data *data; - int interval; data = ti_bandgap_get_sensor_data(bgp, id); @@ -177,12 +178,11 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, return PTR_ERR(data->ti_thermal); } - interval = jiffies_to_msecs(data->ti_thermal->polling_delay_jiffies); - ti_bandgap_set_sensor_data(bgp, id, data); - ti_bandgap_write_update_interval(bgp, data->sensor_id, interval); + ti_bandgap_write_update_interval(bgp, data->sensor_id, + TI_BANDGAP_UPDATE_INTERVAL_MS); - if (devm_thermal_add_hwmon_sysfs(data->ti_thermal)) + if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal)) dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n"); return 0; @@ -223,7 +223,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) * using DT, then it must be aware that the cooling device * loading has to happen via cpufreq driver. */ - if (of_find_property(np, "#thermal-sensor-cells", NULL)) + if (of_property_present(np, "#thermal-sensor-cells")) return 0; data = ti_bandgap_get_sensor_data(bgp, id); diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c index 47801841b3f5..aef6119cc004 100644 --- a/drivers/thermal/uniphier_thermal.c +++ b/drivers/thermal/uniphier_thermal.c @@ -187,7 +187,7 @@ static void uniphier_tm_disable_sensor(struct uniphier_tm_dev *tdev) static int uniphier_tm_get_temp(struct thermal_zone_device *tz, int *out_temp) { - struct uniphier_tm_dev *tdev = tz->devdata; + struct uniphier_tm_dev *tdev = thermal_zone_device_priv(tz); struct regmap *map = tdev->regmap; int ret; u32 temp; |