From 0f46ecc4242a49eb4630d0ac32afbb235f1239fa Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 28 May 2024 11:47:17 -0700 Subject: thermal: intel: intel_tcc_cooling: Switch to new Intel CPU model defines New CPU #defines encode vendor and family as well as model. Signed-off-by: Tony Luck Acked-by: Rafael J. Wysocki Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_tcc_cooling.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c index 6c392147e6d1..63696e7d7b3c 100644 --- a/drivers/thermal/intel/intel_tcc_cooling.c +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -49,21 +49,21 @@ static const struct thermal_cooling_device_ops tcc_cooling_ops = { }; static const struct x86_cpu_id tcc_ids[] __initconst = { - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, NULL), - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, NULL), - X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL), - X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL), - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, NULL), - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL), - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL), - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, NULL), + X86_MATCH_VFM(INTEL_SKYLAKE, NULL), + X86_MATCH_VFM(INTEL_SKYLAKE_L, NULL), + X86_MATCH_VFM(INTEL_KABYLAKE, NULL), + X86_MATCH_VFM(INTEL_KABYLAKE_L, NULL), + X86_MATCH_VFM(INTEL_ICELAKE, NULL), + X86_MATCH_VFM(INTEL_ICELAKE_L, NULL), + X86_MATCH_VFM(INTEL_TIGERLAKE, NULL), + X86_MATCH_VFM(INTEL_TIGERLAKE_L, NULL), + X86_MATCH_VFM(INTEL_COMETLAKE, NULL), + X86_MATCH_VFM(INTEL_ALDERLAKE, NULL), + X86_MATCH_VFM(INTEL_ALDERLAKE_L, NULL), + X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, NULL), + X86_MATCH_VFM(INTEL_RAPTORLAKE, NULL), + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, NULL), {} }; -- cgit v1.2.3-58-ga151 From a31a0a3e90b442c1a414be24b062e27624a40a8e Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 28 May 2024 11:47:16 -0700 Subject: thermal: intel: intel_soc_dts_thermal: Switch to new Intel CPU model defines New CPU #defines encode vendor and family as well as model. Signed-off-by: Tony Luck Acked-by: Rafael J. Wysocki Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_soc_dts_thermal.c | 2 +- include/linux/platform_data/x86/soc.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/intel/intel_soc_dts_thermal.c b/drivers/thermal/intel/intel_soc_dts_thermal.c index 9c825c6e1f38..718c6326eaf4 100644 --- a/drivers/thermal/intel/intel_soc_dts_thermal.c +++ b/drivers/thermal/intel/intel_soc_dts_thermal.c @@ -36,7 +36,7 @@ static irqreturn_t soc_irq_thread_fn(int irq, void *dev_data) } static const struct x86_cpu_id soc_thermal_ids[] = { - X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, BYT_SOC_DTS_APIC_IRQ), + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, BYT_SOC_DTS_APIC_IRQ), {} }; MODULE_DEVICE_TABLE(x86cpu, soc_thermal_ids); diff --git a/include/linux/platform_data/x86/soc.h b/include/linux/platform_data/x86/soc.h index a5705189e2ac..f981907a5cb0 100644 --- a/include/linux/platform_data/x86/soc.h +++ b/include/linux/platform_data/x86/soc.h @@ -20,7 +20,7 @@ static inline bool soc_intel_is_##soc(void) \ { \ static const struct x86_cpu_id soc##_cpu_ids[] = { \ - X86_MATCH_INTEL_FAM6_MODEL(type, NULL), \ + X86_MATCH_VFM(type, NULL), \ {} \ }; \ const struct x86_cpu_id *id; \ @@ -31,11 +31,11 @@ static inline bool soc_intel_is_##soc(void) \ return false; \ } -SOC_INTEL_IS_CPU(byt, ATOM_SILVERMONT); -SOC_INTEL_IS_CPU(cht, ATOM_AIRMONT); -SOC_INTEL_IS_CPU(apl, ATOM_GOLDMONT); -SOC_INTEL_IS_CPU(glk, ATOM_GOLDMONT_PLUS); -SOC_INTEL_IS_CPU(cml, KABYLAKE_L); +SOC_INTEL_IS_CPU(byt, INTEL_ATOM_SILVERMONT); +SOC_INTEL_IS_CPU(cht, INTEL_ATOM_AIRMONT); +SOC_INTEL_IS_CPU(apl, INTEL_ATOM_GOLDMONT); +SOC_INTEL_IS_CPU(glk, INTEL_ATOM_GOLDMONT_PLUS); +SOC_INTEL_IS_CPU(cml, INTEL_KABYLAKE_L); #undef SOC_INTEL_IS_CPU -- cgit v1.2.3-58-ga151 From 1007d2c5d77d2eab9dc2ba47f7de00a53d0bab73 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Thu, 6 Jun 2024 19:21:06 +0200 Subject: thermal: int3400: Use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index fa96972266e4..b0c0f0ffdcb0 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -571,7 +571,7 @@ static int int3400_thermal_probe(struct platform_device *pdev) if (!adev) return -ENODEV; - priv = kzalloc(sizeof(struct int3400_thermal_priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; -- cgit v1.2.3-58-ga151 From 68f2d1dc4826e7bafbfbf7acc745913623a48955 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 29 May 2024 18:53:09 +0100 Subject: thermal: int3403: remove unused struct 'int3403_performance_state' 'int3403_performance_state' has never been used since the original commit 4384b8fe162d ("Thermal: introduce int3403 thermal driver"). Remove it. Signed-off-by: Dr. David Alan Gilbert Acked-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/int3403_thermal.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c index 86901f9f54d8..c094a422ded3 100644 --- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c @@ -25,17 +25,6 @@ struct int3403_sensor { struct int34x_thermal_zone *int340x_zone; }; -struct int3403_performance_state { - u64 performance; - u64 power; - u64 latency; - u64 linear; - u64 control; - u64 raw_performace; - char *raw_unit; - int reserved; -}; - struct int3403_cdev { struct thermal_cooling_device *cdev; unsigned long max_state; -- cgit v1.2.3-58-ga151 From 68de0ae4d6b5ea675b835e4a6b00f52a26cd7f0c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 30 May 2024 23:17:04 +0800 Subject: thermal: intel: intel_pch: Improve cooling log The intel_pch_thermal cooling mechanism currently only provides one of the following final conclusions: 1. intel_pch_thermal 0000:00:12.0: CPU-PCH is cool [48C] 2. intel_pch_thermal 0000:00:12.0: CPU-PCH is cool [49C] after 30700 ms delay 3. intel_pch_thermal 0000:00:12.0: CPU-PCH is hot [60C] after 60000 ms delay. S0ix might fail 4. intel_pch_thermal 0000:00:12.0: Wakeup event detected, abort cooling This does not provide sufficient context about what is happening, especially for case 4. Add one line log to indicate when PCH overheats and the cooling delay has started. Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_pch_thermal.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c index f5be2c389351..fc326985796c 100644 --- a/drivers/thermal/intel/intel_pch_thermal.c +++ b/drivers/thermal/intel/intel_pch_thermal.c @@ -298,6 +298,11 @@ static int intel_pch_thermal_suspend_noirq(struct device *device) /* Get the PCH current temperature value */ pch_cur_temp = GET_PCH_TEMP(WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP)); + if (pch_cur_temp >= pch_thr_temp) + dev_warn(&ptd->pdev->dev, + "CPU-PCH current temp [%dC] higher than the threshold temp [%dC], S0ix might fail. Start cooling...\n", + pch_cur_temp, pch_thr_temp); + /* * If current PCH temperature is higher than configured PCH threshold * value, run some delay loop with sleep to let the current temperature -- cgit v1.2.3-58-ga151 From 8b95bed0cec98c9ff7a72acd6227c427a2b4f0a9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:52:50 +0200 Subject: thermal/debugfs: Use helper to update trip point overstepping duration Add a helper for updating trip point overstepping duration to be called from thermal_debug_tz_trip_down(). Subsequently, it will also be used during resume from system-wide suspend. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index 942447229157..66c0105465dd 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -653,14 +653,24 @@ unlock: mutex_unlock(&thermal_dbg->lock); } +static void tz_episode_close_trip(struct tz_episode *tze, int trip_id, ktime_t now) +{ + struct trip_stats *trip_stats = &tze->trip_stats[trip_id]; + ktime_t delta = ktime_sub(now, trip_stats->timestamp); + + trip_stats->duration = ktime_add(delta, trip_stats->duration); + /* Mark the end of mitigation for this trip point. */ + trip_stats->timestamp = KTIME_MAX; +} + void thermal_debug_tz_trip_down(struct thermal_zone_device *tz, const struct thermal_trip *trip) { struct thermal_debugfs *thermal_dbg = tz->debugfs; + int trip_id = thermal_zone_trip_id(tz, trip); + ktime_t now = ktime_get(); struct tz_episode *tze; struct tz_debugfs *tz_dbg; - ktime_t delta, now = ktime_get(); - int trip_id = thermal_zone_trip_id(tz, trip); int i; if (!thermal_dbg) @@ -695,13 +705,7 @@ void thermal_debug_tz_trip_down(struct thermal_zone_device *tz, tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); - delta = ktime_sub(now, tze->trip_stats[trip_id].timestamp); - - tze->trip_stats[trip_id].duration = - ktime_add(delta, tze->trip_stats[trip_id].duration); - - /* Mark the end of mitigation for this trip point. */ - tze->trip_stats[trip_id].timestamp = KTIME_MAX; + tz_episode_close_trip(tze, trip_id, now); /* * This event closes the mitigation as we are crossing the -- cgit v1.2.3-58-ga151 From 9b73b5052ae841037682da93a17f80f8ed57788d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:53:47 +0200 Subject: thermal/debugfs: Do not extend mitigation episodes beyond system resume Because thermal zone handling by the thermal core is started from scratch during resume from system-wide suspend, prevent the debug code from extending mitigation episodes beyond that point by ending the mitigation episode currently in progress, if any, for each thermal zone. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_core.c | 1 + drivers/thermal/thermal_debugfs.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/thermal/thermal_debugfs.h | 2 ++ 3 files changed, 39 insertions(+) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d70e76dd3c94..bd31193bb583 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1648,6 +1648,7 @@ static void thermal_zone_device_resume(struct work_struct *work) tz->suspended = false; + thermal_debug_tz_resume(tz); thermal_zone_device_init(tz); __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index 66c0105465dd..c592eca11a50 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -926,3 +926,39 @@ void thermal_debug_tz_remove(struct thermal_zone_device *tz) thermal_debugfs_remove_id(thermal_dbg); kfree(trips_crossed); } + +void thermal_debug_tz_resume(struct thermal_zone_device *tz) +{ + struct thermal_debugfs *thermal_dbg = tz->debugfs; + ktime_t now = ktime_get(); + struct tz_debugfs *tz_dbg; + struct tz_episode *tze; + int i; + + if (!thermal_dbg) + return; + + mutex_lock(&thermal_dbg->lock); + + tz_dbg = &thermal_dbg->tz_dbg; + + if (!tz_dbg->nr_trips) + goto out; + + /* + * A mitigation episode was in progress before the preceding system + * suspend transition, so close it because the zone handling is starting + * over from scratch. + */ + tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); + + for (i = 0; i < tz_dbg->nr_trips; i++) + tz_episode_close_trip(tze, tz_dbg->trips_crossed[i], now); + + tze->duration = ktime_sub(now, tze->timestamp); + + tz_dbg->nr_trips = 0; + +out: + mutex_unlock(&thermal_dbg->lock); +} diff --git a/drivers/thermal/thermal_debugfs.h b/drivers/thermal/thermal_debugfs.h index 74ee65ee82ff..1c957ce2ec8f 100644 --- a/drivers/thermal/thermal_debugfs.h +++ b/drivers/thermal/thermal_debugfs.h @@ -7,6 +7,7 @@ void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev); void thermal_debug_cdev_state_update(const struct thermal_cooling_device *cdev, int state); void thermal_debug_tz_add(struct thermal_zone_device *tz); void thermal_debug_tz_remove(struct thermal_zone_device *tz); +void thermal_debug_tz_resume(struct thermal_zone_device *tz); void thermal_debug_tz_trip_up(struct thermal_zone_device *tz, const struct thermal_trip *trip); void thermal_debug_tz_trip_down(struct thermal_zone_device *tz, @@ -20,6 +21,7 @@ static inline void thermal_debug_cdev_state_update(const struct thermal_cooling_ int state) {} static inline void thermal_debug_tz_add(struct thermal_zone_device *tz) {} static inline void thermal_debug_tz_remove(struct thermal_zone_device *tz) {} +static inline void thermal_debug_tz_resume(struct thermal_zone_device *tz) {} static inline void thermal_debug_tz_trip_up(struct thermal_zone_device *tz, const struct thermal_trip *trip) {}; static inline void thermal_debug_tz_trip_down(struct thermal_zone_device *tz, -- cgit v1.2.3-58-ga151 From cc86c139ae41a6107955db0b4c79d549cbccb4a6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:55:00 +0200 Subject: thermal/debugfs: Print mitigation timestamp value in milliseconds Because mitigation episode duration is printed in milliseconds, there is no reason to print timestamp information for mitigation episodes in smaller units which also makes it somewhat harder to interpret the numbers. Print it in milliseconds for consistency. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index c592eca11a50..d74d4cf3ac7b 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -797,8 +797,8 @@ static int tze_seq_show(struct seq_file *s, void *v) c = '='; } - seq_printf(s, ",-Mitigation at %lluus, duration%c%llums\n", - ktime_to_us(tze->timestamp), c, duration_ms); + seq_printf(s, ",-Mitigation at %llums, duration%c%llums\n", + ktime_to_ms(tze->timestamp), c, duration_ms); seq_printf(s, "| trip | type | temp(°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°mC) |\n"); -- cgit v1.2.3-58-ga151 From ea6a3c52021e552d904d0b1b67ef695bc5c3a54a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:55:53 +0200 Subject: thermal/debugfs: Fix up units in "mitigations" files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print temperature units as m°C rather than °mC (the meaning of which is unclear) and add time unit to the duration column. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index d74d4cf3ac7b..ee9fc627ec81 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -800,7 +800,7 @@ static int tze_seq_show(struct seq_file *s, void *v) seq_printf(s, ",-Mitigation at %llums, duration%c%llums\n", ktime_to_ms(tze->timestamp), c, duration_ms); - seq_printf(s, "| trip | type | temp(°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°mC) |\n"); + seq_printf(s, "| trip | type | temp(m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°C) | max(m°C) |\n"); for_each_trip_desc(tz, td) { const struct thermal_trip *trip = &td->trip; @@ -846,7 +846,7 @@ static int tze_seq_show(struct seq_file *s, void *v) 8, type, 9, trip_stats->trip_temp, 9, trip_stats->trip_hyst, - c, 10, duration_ms, + c, 11, duration_ms, 9, trip_stats->avg, 9, trip_stats->min, 9, trip_stats->max); -- cgit v1.2.3-58-ga151 From 993c87047ddebb9cf922c489199d3a402a440979 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:57:13 +0200 Subject: thermal/debugfs: Adjust check for trips without statistics in tze_seq_show() Initialize the trip_temp field in struct trip_stats to THERMAL_TEMP_INVALID and adjust the check for trips without statistics in tze_seq_show() to look at that field instead of comparing min and max. This will mostly be useful to simplify subsequent changes. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index ee9fc627ec81..5f9e5e9d403c 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -563,6 +563,7 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev tze->duration = KTIME_MIN; for (i = 0; i < tz->num_trips; i++) { + tze->trip_stats[i].trip_temp = THERMAL_TEMP_INVALID; tze->trip_stats[i].min = INT_MAX; tze->trip_stats[i].max = INT_MIN; } @@ -818,7 +819,7 @@ static int tze_seq_show(struct seq_file *s, void *v) trip_stats = &tze->trip_stats[trip_id]; /* Skip trips without any stats. */ - if (trip_stats->min > trip_stats->max) + if (trip_stats->trip_temp == THERMAL_TEMP_INVALID) continue; if (trip->type == THERMAL_TRIP_PASSIVE) -- cgit v1.2.3-58-ga151 From 881c084fc980d05d05dceac4d789a473b42e177d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:58:56 +0200 Subject: thermal/debugfs: Compute maximum temperature for mitigation episode as a whole Notice that the maximum temperature above the trip point must be the same for all of the trip points involved in a given mitigation episode, so it need not be computerd for each of them separately. It is sufficient to compute the maximum temperature for the mitigation episode as a whole and print it accordingly, so do that. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index 5f9e5e9d403c..dbfe678bd404 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -94,7 +94,6 @@ struct cdev_record { * @trip_temp: trip temperature at mitigation start * @trip_hyst: trip hysteresis at mitigation start * @count: the number of times the zone temperature was above the trip point - * @max: maximum recorded temperature above the trip point * @min: minimum recorded temperature above the trip point * @avg: average temperature above the trip point */ @@ -104,7 +103,6 @@ struct trip_stats { int trip_temp; int trip_hyst; int count; - int max; int min; int avg; }; @@ -122,12 +120,14 @@ struct trip_stats { * @timestamp: first trip point crossed the way up * @duration: total duration of the mitigation episode * @node: a list element to be added to the list of tz events + * @max_temp: maximum zone temperature during this episode * @trip_stats: per trip point statistics, flexible array */ struct tz_episode { ktime_t timestamp; ktime_t duration; struct list_head node; + int max_temp; struct trip_stats trip_stats[]; }; @@ -561,11 +561,11 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev INIT_LIST_HEAD(&tze->node); tze->timestamp = now; tze->duration = KTIME_MIN; + tze->max_temp = INT_MIN; for (i = 0; i < tz->num_trips; i++) { tze->trip_stats[i].trip_temp = THERMAL_TEMP_INVALID; tze->trip_stats[i].min = INT_MAX; - tze->trip_stats[i].max = INT_MIN; } return tze; @@ -738,11 +738,13 @@ void thermal_debug_update_trip_stats(struct thermal_zone_device *tz) tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); + if (tz->temperature > tze->max_temp) + tze->max_temp = tz->temperature; + for (i = 0; i < tz_dbg->nr_trips; i++) { int trip_id = tz_dbg->trips_crossed[i]; struct trip_stats *trip_stats = &tze->trip_stats[trip_id]; - trip_stats->max = max(trip_stats->max, tz->temperature); trip_stats->min = min(trip_stats->min, tz->temperature); trip_stats->avg += (tz->temperature - trip_stats->avg) / ++trip_stats->count; @@ -798,10 +800,10 @@ static int tze_seq_show(struct seq_file *s, void *v) c = '='; } - seq_printf(s, ",-Mitigation at %llums, duration%c%llums\n", - ktime_to_ms(tze->timestamp), c, duration_ms); + seq_printf(s, ",-Mitigation at %llums, duration%c%llums, max. temp=%dm°C\n", + ktime_to_ms(tze->timestamp), c, duration_ms, tze->max_temp); - seq_printf(s, "| trip | type | temp(m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°C) | max(m°C) |\n"); + seq_printf(s, "| trip | type | temp(m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°C) |\n"); for_each_trip_desc(tz, td) { const struct thermal_trip *trip = &td->trip; @@ -842,15 +844,14 @@ static int tze_seq_show(struct seq_file *s, void *v) c = ' '; } - seq_printf(s, "| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d | %*d |\n", + seq_printf(s, "| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d |\n", 4 , trip_id, 8, type, 9, trip_stats->trip_temp, 9, trip_stats->trip_hyst, c, 11, duration_ms, 9, trip_stats->avg, - 9, trip_stats->min, - 9, trip_stats->max); + 9, trip_stats->min); } return 0; -- cgit v1.2.3-58-ga151 From 8f9025baf66ff4781ae3d40f9bc457b0a022b1a3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:59:55 +0200 Subject: thermal/debugfs: Move some statements from under thermal_dbg->lock The tz_dbg local variable assignments in thermal_debug_tz_trip_up(), thermal_debug_tz_trip_down(), and thermal_debug_update_trip_stats() need not be carried out under thermal_dbg->lock, so move them from under that lock (to avoid possible future confusion). While at it, reorder local variable definitions in thermal_debug_tz_trip_up() for more clarity. No functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_debugfs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index dbfe678bd404..d83263101ec3 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -574,20 +574,20 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev void thermal_debug_tz_trip_up(struct thermal_zone_device *tz, const struct thermal_trip *trip) { - struct tz_episode *tze; - struct tz_debugfs *tz_dbg; struct thermal_debugfs *thermal_dbg = tz->debugfs; int trip_id = thermal_zone_trip_id(tz, trip); ktime_t now = ktime_get(); struct trip_stats *trip_stats; + struct tz_debugfs *tz_dbg; + struct tz_episode *tze; if (!thermal_dbg) return; - mutex_lock(&thermal_dbg->lock); - tz_dbg = &thermal_dbg->tz_dbg; + mutex_lock(&thermal_dbg->lock); + /* * The mitigation is starting. A mitigation can contain * several episodes where each of them is related to a @@ -677,10 +677,10 @@ void thermal_debug_tz_trip_down(struct thermal_zone_device *tz, if (!thermal_dbg) return; - mutex_lock(&thermal_dbg->lock); - tz_dbg = &thermal_dbg->tz_dbg; + mutex_lock(&thermal_dbg->lock); + /* * The temperature crosses the way down but there was not * mitigation detected before. That may happen when the @@ -729,10 +729,10 @@ void thermal_debug_update_trip_stats(struct thermal_zone_device *tz) if (!thermal_dbg) return; - mutex_lock(&thermal_dbg->lock); - tz_dbg = &thermal_dbg->tz_dbg; + mutex_lock(&thermal_dbg->lock); + if (!tz_dbg->nr_trips) goto out; -- cgit v1.2.3-58-ga151 From f41f23b0cae1d069c680dd9e5e2cd42db8ff6dfc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 17:00:51 +0200 Subject: thermal: trip: Use common set of trip type names Use the same set of trip type names in sysfs and in the thermal debug code output. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_core.h | 2 ++ drivers/thermal/thermal_debugfs.c | 10 +--------- drivers/thermal/thermal_sysfs.c | 13 +------------ drivers/thermal/thermal_trip.c | 15 +++++++++++++++ 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 20e7b45673d6..afb00b567e68 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -240,6 +240,8 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz, #define trip_to_trip_desc(__trip) \ container_of(__trip, struct thermal_trip_desc, trip) +const char *thermal_trip_type_name(enum thermal_trip_type trip_type); + void __thermal_zone_set_trips(struct thermal_zone_device *tz); int thermal_zone_trip_id(const struct thermal_zone_device *tz, const struct thermal_trip *trip); diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index d83263101ec3..7dd67bf48571 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -784,7 +784,6 @@ static int tze_seq_show(struct seq_file *s, void *v) struct thermal_zone_device *tz = thermal_dbg->tz_dbg.tz; struct thermal_trip_desc *td; struct tz_episode *tze; - const char *type; u64 duration_ms; int trip_id; char c; @@ -824,13 +823,6 @@ static int tze_seq_show(struct seq_file *s, void *v) if (trip_stats->trip_temp == THERMAL_TEMP_INVALID) continue; - if (trip->type == THERMAL_TRIP_PASSIVE) - type = "passive"; - else if (trip->type == THERMAL_TRIP_ACTIVE) - type = "active"; - else - type = "hot"; - if (trip_stats->timestamp != KTIME_MAX) { /* Mitigation in progress. */ ktime_t delta = ktime_sub(ktime_get(), @@ -846,7 +838,7 @@ static int tze_seq_show(struct seq_file *s, void *v) seq_printf(s, "| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d |\n", 4 , trip_id, - 8, type, + 8, thermal_trip_type_name(trip->type), 9, trip_stats->trip_temp, 9, trip_stats->trip_hyst, c, 11, duration_ms, diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 88211ccdfbd6..e65bbbbf0054 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -88,18 +88,7 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1) return -EINVAL; - switch (tz->trips[trip_id].trip.type) { - case THERMAL_TRIP_CRITICAL: - return sprintf(buf, "critical\n"); - case THERMAL_TRIP_HOT: - return sprintf(buf, "hot\n"); - case THERMAL_TRIP_PASSIVE: - return sprintf(buf, "passive\n"); - case THERMAL_TRIP_ACTIVE: - return sprintf(buf, "active\n"); - default: - return sprintf(buf, "unknown\n"); - } + return sprintf(buf, "%s\n", thermal_trip_type_name(tz->trips[trip_id].trip.type)); } static ssize_t diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 49e63db68517..1ffb5aeab7fb 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -9,6 +9,21 @@ */ #include "thermal_core.h" +static const char *trip_type_names[] = { + [THERMAL_TRIP_ACTIVE] = "active", + [THERMAL_TRIP_PASSIVE] = "passive", + [THERMAL_TRIP_HOT] = "hot", + [THERMAL_TRIP_CRITICAL] = "critical", +}; + +const char *thermal_trip_type_name(enum thermal_trip_type trip_type) +{ + if (trip_type < THERMAL_TRIP_ACTIVE || trip_type > THERMAL_TRIP_CRITICAL) + return "unknown"; + + return trip_type_names[trip_type]; +} + int for_each_thermal_trip(struct thermal_zone_device *tz, int (*cb)(struct thermal_trip *, void *), void *data) -- cgit v1.2.3-58-ga151 From 28d5cc12671c8b23d928128d8d4ced586b873e5f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 7 Jun 2024 09:33:53 +0200 Subject: thermal: trip: Rename __thermal_zone_set_trips() to thermal_zone_set_trips() Drop the pointless double underline prefix from the function name as per the subject. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_core.c | 2 +- drivers/thermal/thermal_core.h | 2 +- drivers/thermal/thermal_trip.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index bd31193bb583..6acaa4b50273 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -513,7 +513,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, if (tz->temperature == THERMAL_TEMP_INVALID) return; - __thermal_zone_set_trips(tz); + thermal_zone_set_trips(tz); tz->notify_event = event; diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index afb00b567e68..4af6b940ed7a 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -242,7 +242,7 @@ void thermal_governor_update_tz(struct thermal_zone_device *tz, const char *thermal_trip_type_name(enum thermal_trip_type trip_type); -void __thermal_zone_set_trips(struct thermal_zone_device *tz); +void thermal_zone_set_trips(struct thermal_zone_device *tz); int thermal_zone_trip_id(const struct thermal_zone_device *tz, const struct thermal_trip *trip); void thermal_zone_trip_updated(struct thermal_zone_device *tz, diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 1ffb5aeab7fb..6ab1beb9bf0d 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -62,7 +62,7 @@ int thermal_zone_get_num_trips(struct thermal_zone_device *tz) EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips); /** - * __thermal_zone_set_trips - Computes the next trip points for the driver + * thermal_zone_set_trips - Computes the next trip points for the driver * @tz: a pointer to a thermal zone device structure * * The function computes the next temperature boundaries by browsing @@ -76,7 +76,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips); * * It does not return a value */ -void __thermal_zone_set_trips(struct thermal_zone_device *tz) +void thermal_zone_set_trips(struct thermal_zone_device *tz) { const struct thermal_trip_desc *td; int low = -INT_MAX, high = INT_MAX; -- cgit v1.2.3-58-ga151 From 893bae92237d824334d68d6b67222aaf32e41458 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 18:51:11 +0200 Subject: thermal: trip: Make thermal_zone_set_trips() use trip thresholds Modify thermal_zone_set_trips() to use trip thresholds instead of computing the low temperature for each trip to avoid deriving both the high and low temperature levels from the same trip (which may happen if the zone temperature falls into the hysteresis range of one trip). Accordingly, make __thermal_zone_device_update() call thermal_zone_set_trips() later, when threshold values have been updated for all trips. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_core.c | 4 ++-- drivers/thermal/thermal_trip.c | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 6acaa4b50273..57f20326aa91 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -513,13 +513,13 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, if (tz->temperature == THERMAL_TEMP_INVALID) return; - thermal_zone_set_trips(tz); - tz->notify_event = event; for_each_trip_desc(tz, td) handle_thermal_trip(tz, td, &way_up_list, &way_down_list); + thermal_zone_set_trips(tz); + list_sort(&way_up_list, &way_up_list, thermal_trip_notify_cmp); list_for_each_entry(td, &way_up_list, notify_list_node) thermal_trip_crossed(tz, &td->trip, governor, true); diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 6ab1beb9bf0d..86f408f84f17 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -88,17 +88,11 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz) return; for_each_trip_desc(tz, td) { - const struct thermal_trip *trip = &td->trip; - int trip_low; + if (td->threshold < tz->temperature && td->threshold > low) + low = td->threshold; - trip_low = trip->temperature - trip->hysteresis; - - if (trip_low < tz->temperature && trip_low > low) - low = trip_low; - - if (trip->temperature > tz->temperature && - trip->temperature < high) - high = trip->temperature; + if (td->threshold > tz->temperature && td->threshold < high) + high = td->threshold; } /* No need to change trip points */ -- cgit v1.2.3-58-ga151 From a52641bc6293a24f25956a597e7f32148b0e2bb8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 18:52:13 +0200 Subject: thermal: trip: Use READ_ONCE() for lockless access to trip properties When accessing trip temperature and hysteresis without locking, it is better to use READ_ONCE() to prevent compiler optimizations possibly affecting the read from being applied. Of course, for the READ_ONCE() to be effective, WRITE_ONCE() needs to be used when updating their values. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_sysfs.c | 6 +++--- drivers/thermal/thermal_trip.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index e65bbbbf0054..434b577950be 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -139,7 +139,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) return -EINVAL; - return sprintf(buf, "%d\n", tz->trips[trip_id].trip.temperature); + return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature)); } static ssize_t @@ -163,7 +163,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, trip = &tz->trips[trip_id].trip; if (hyst != trip->hysteresis) { - trip->hysteresis = hyst; + WRITE_ONCE(trip->hysteresis, hyst); thermal_zone_trip_updated(tz, trip); } @@ -183,7 +183,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) return -EINVAL; - return sprintf(buf, "%d\n", tz->trips[trip_id].trip.hysteresis); + return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis)); } static ssize_t diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 86f408f84f17..2a876d3b93aa 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -161,7 +161,7 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, if (trip->temperature == temp) return; - trip->temperature = temp; + WRITE_ONCE(trip->temperature, temp); thermal_notify_tz_trip_change(tz, trip); if (temp == THERMAL_TEMP_INVALID) { -- cgit v1.2.3-58-ga151 From 2c637af8a74d9a2a52ee5456a75dd29c8cb52da5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 18:54:01 +0200 Subject: thermal: gov_bang_bang: Drop unnecessary cooling device target state checks Some cooling device target state checks in bang_bang_control() done before setting the new target state are not necessary after recent changes, so drop them. Also avoid updating the target state before checking it for unexpected values. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/gov_bang_bang.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c index acb52c9ee10f..4a2e869b9538 100644 --- a/drivers/thermal/gov_bang_bang.c +++ b/drivers/thermal/gov_bang_bang.c @@ -57,24 +57,16 @@ static void bang_bang_control(struct thermal_zone_device *tz, if (instance->trip != trip) continue; - if (instance->target == THERMAL_NO_TARGET) - instance->target = 0; - - if (instance->target != 0 && instance->target != 1) { + if (instance->target != 0 && instance->target != 1 && + instance->target != THERMAL_NO_TARGET) pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n", instance->target, instance->name); - instance->target = 1; - } - /* * Enable the fan when the trip is crossed on the way up and * disable it when the trip is crossed on the way down. */ - if (instance->target == 0 && crossed_up) - instance->target = 1; - else if (instance->target == 1 && !crossed_up) - instance->target = 0; + instance->target = crossed_up; dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target); -- cgit v1.2.3-58-ga151 From 72196c20c38b50c4293696377145e6c4ad9a7c67 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 18:54:11 +0200 Subject: thermal: core: Avoid calling .trip_crossed() for critical and hot trips Invoking the governor .trip_crossed() callback for critical and hot trips is pointless because they are handled directly by the core, so make thermal_governor_trip_crossed() avoid doing that. Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 57f20326aa91..8bb63a364cba 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -463,6 +463,9 @@ static void thermal_governor_trip_crossed(struct thermal_governor *governor, const struct thermal_trip *trip, bool crossed_up) { + if (trip->type == THERMAL_TRIP_HOT || trip->type == THERMAL_TRIP_CRITICAL) + return; + if (governor->trip_crossed) governor->trip_crossed(tz, trip, crossed_up); } -- cgit v1.2.3-58-ga151 From 6ae0092ca7adfce79336c6525cb0da561ecd4f04 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Fri, 14 Jun 2024 14:16:05 -0700 Subject: thermal: intel: intel_tcc: Add model checks for temperature registers The register MSR_TEMPERATURE_TARGET is not architectural. Its fields may be defined differently for each processor model. TCC_OFFSET is an example of such case. Despite being specified as architectural, the registers IA32_[PACKAGE]_ THERM_STATUS have become model-specific: in recent processors, the digital temperature readout uses bits [23:16] whereas the Intel Software Developer's manual specifies bits [22:16]. Create an array of processor models and their bitmasks for TCC_OFFSET and the digital temperature readout fields. Do not include recent processors. Instead, use the bitmasks of these recent processors as default. Use these model-specific bitmasks when reading TCC_OFFSET or the temperature sensors. Initialize a model-specific data structure during subsys_initcall() to have it ready when thermal drivers are loaded. Expose the new interface intel_tcc_get_offset_mask(). The intel_tcc_cooling driver will use it. Reviewed-by: Zhang Rui Signed-off-by: Ricardo Neri Link: https://patch.msgid.link/20240614211606.5896-2-ricardo.neri-calderon@linux.intel.com Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_tcc.c | 177 ++++++++++++++++++++++++++++++++++++-- include/linux/intel_tcc.h | 1 + 2 files changed, 173 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/intel/intel_tcc.c b/drivers/thermal/intel/intel_tcc.c index 5e8b7f34b395..c86654f28aa5 100644 --- a/drivers/thermal/intel/intel_tcc.c +++ b/drivers/thermal/intel/intel_tcc.c @@ -6,8 +6,170 @@ #include #include +#include +#include #include +/** + * struct temp_masks - Bitmasks for temperature readings + * @tcc_offset: TCC offset in MSR_TEMPERATURE_TARGET + * @digital_readout: Digital readout in MSR_IA32_THERM_STATUS + * @pkg_digital_readout: Digital readout in MSR_IA32_PACKAGE_THERM_STATUS + * + * Bitmasks to extract the fields of the MSR_TEMPERATURE and IA32_[PACKAGE]_ + * THERM_STATUS registers for different processor models. + * + * The bitmask of TjMax is not included in this structure. It is always 0xff. + */ +struct temp_masks { + u32 tcc_offset; + u32 digital_readout; + u32 pkg_digital_readout; +}; + +#define TCC_MODEL_TEMP_MASKS(model, _tcc_offset, _digital_readout, \ + _pkg_digital_readout) \ + static const struct temp_masks temp_##model __initconst = { \ + .tcc_offset = _tcc_offset, \ + .digital_readout = _digital_readout, \ + .pkg_digital_readout = _pkg_digital_readout \ + } + +TCC_MODEL_TEMP_MASKS(nehalem, 0, 0x7f, 0x7f); +TCC_MODEL_TEMP_MASKS(haswell_x, 0xf, 0x7f, 0x7f); +TCC_MODEL_TEMP_MASKS(broadwell, 0x3f, 0x7f, 0x7f); +TCC_MODEL_TEMP_MASKS(goldmont, 0x7f, 0x7f, 0x7f); +TCC_MODEL_TEMP_MASKS(tigerlake, 0x3f, 0xff, 0xff); +TCC_MODEL_TEMP_MASKS(sapphirerapids, 0x3f, 0x7f, 0xff); + +/* Use these masks for processors not included in @tcc_cpu_ids. */ +static struct temp_masks intel_tcc_temp_masks __ro_after_init = { + .tcc_offset = 0x7f, + .digital_readout = 0xff, + .pkg_digital_readout = 0xff, +}; + +static const struct x86_cpu_id intel_tcc_cpu_ids[] __initconst = { + X86_MATCH_VFM(INTEL_CORE_YONAH, &temp_nehalem), + X86_MATCH_VFM(INTEL_CORE2_MEROM, &temp_nehalem), + X86_MATCH_VFM(INTEL_CORE2_MEROM_L, &temp_nehalem), + X86_MATCH_VFM(INTEL_CORE2_PENRYN, &temp_nehalem), + X86_MATCH_VFM(INTEL_CORE2_DUNNINGTON, &temp_nehalem), + X86_MATCH_VFM(INTEL_NEHALEM, &temp_nehalem), + X86_MATCH_VFM(INTEL_NEHALEM_G, &temp_nehalem), + X86_MATCH_VFM(INTEL_NEHALEM_EP, &temp_nehalem), + X86_MATCH_VFM(INTEL_NEHALEM_EX, &temp_nehalem), + X86_MATCH_VFM(INTEL_WESTMERE, &temp_nehalem), + X86_MATCH_VFM(INTEL_WESTMERE_EP, &temp_nehalem), + X86_MATCH_VFM(INTEL_WESTMERE_EX, &temp_nehalem), + X86_MATCH_VFM(INTEL_SANDYBRIDGE, &temp_nehalem), + X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &temp_nehalem), + X86_MATCH_VFM(INTEL_IVYBRIDGE, &temp_nehalem), + X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &temp_haswell_x), + X86_MATCH_VFM(INTEL_HASWELL, &temp_nehalem), + X86_MATCH_VFM(INTEL_HASWELL_X, &temp_haswell_x), + X86_MATCH_VFM(INTEL_HASWELL_L, &temp_nehalem), + X86_MATCH_VFM(INTEL_HASWELL_G, &temp_nehalem), + X86_MATCH_VFM(INTEL_BROADWELL, &temp_broadwell), + X86_MATCH_VFM(INTEL_BROADWELL_G, &temp_broadwell), + X86_MATCH_VFM(INTEL_BROADWELL_X, &temp_haswell_x), + X86_MATCH_VFM(INTEL_BROADWELL_D, &temp_haswell_x), + X86_MATCH_VFM(INTEL_SKYLAKE_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_SKYLAKE, &temp_broadwell), + X86_MATCH_VFM(INTEL_SKYLAKE_X, &temp_haswell_x), + X86_MATCH_VFM(INTEL_KABYLAKE_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_KABYLAKE, &temp_broadwell), + X86_MATCH_VFM(INTEL_COMETLAKE, &temp_broadwell), + X86_MATCH_VFM(INTEL_COMETLAKE_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_CANNONLAKE_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_ICELAKE_X, &temp_broadwell), + X86_MATCH_VFM(INTEL_ICELAKE_D, &temp_broadwell), + X86_MATCH_VFM(INTEL_ICELAKE, &temp_broadwell), + X86_MATCH_VFM(INTEL_ICELAKE_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &temp_broadwell), + X86_MATCH_VFM(INTEL_ROCKETLAKE, &temp_broadwell), + X86_MATCH_VFM(INTEL_TIGERLAKE_L, &temp_tigerlake), + X86_MATCH_VFM(INTEL_TIGERLAKE, &temp_tigerlake), + X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &temp_sapphirerapids), + X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &temp_sapphirerapids), + X86_MATCH_VFM(INTEL_LAKEFIELD, &temp_broadwell), + X86_MATCH_VFM(INTEL_ALDERLAKE, &temp_tigerlake), + X86_MATCH_VFM(INTEL_ALDERLAKE_L, &temp_tigerlake), + X86_MATCH_VFM(INTEL_RAPTORLAKE, &temp_tigerlake), + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &temp_tigerlake), + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &temp_tigerlake), + X86_MATCH_VFM(INTEL_ATOM_BONNELL, &temp_nehalem), + X86_MATCH_VFM(INTEL_ATOM_BONNELL_MID, &temp_nehalem), + X86_MATCH_VFM(INTEL_ATOM_SALTWELL, &temp_nehalem), + X86_MATCH_VFM(INTEL_ATOM_SALTWELL_MID, &temp_nehalem), + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_AIRMONT_MID, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &temp_goldmont), + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &temp_goldmont), + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &temp_goldmont), + X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_TREMONT, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &temp_broadwell), + X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &temp_tigerlake), + X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &temp_broadwell), + X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &temp_broadwell), + {} +}; + +static int __init intel_tcc_init(void) +{ + const struct x86_cpu_id *id; + + id = x86_match_cpu(intel_tcc_cpu_ids); + if (id) + memcpy(&intel_tcc_temp_masks, (const void *)id->driver_data, + sizeof(intel_tcc_temp_masks)); + + return 0; +} +/* + * Use subsys_initcall to ensure temperature bitmasks are initialized before + * the drivers that use this library. + */ +subsys_initcall(intel_tcc_init); + +/** + * intel_tcc_get_offset_mask() - Returns the bitmask to read TCC offset + * + * Get the model-specific bitmask to extract TCC_OFFSET from the MSR + * TEMPERATURE_TARGET register. If the mask is 0, it means the processor does + * not support TCC offset. + * + * Return: The model-specific bitmask for TCC offset. + */ +u32 intel_tcc_get_offset_mask(void) +{ + return intel_tcc_temp_masks.tcc_offset; +} +EXPORT_SYMBOL_NS(intel_tcc_get_offset_mask, INTEL_TCC); + +/** + * get_temp_mask() - Returns the model-specific bitmask for temperature + * + * @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor. + * + * Get the model-specific bitmask to extract the temperature reading from the + * MSR_IA32_[PACKAGE]_THERM_STATUS register. + * + * Callers must check if the thermal status registers are supported. + * + * Return: The model-specific bitmask for temperature reading + */ +static u32 get_temp_mask(bool pkg) +{ + return pkg ? intel_tcc_temp_masks.pkg_digital_readout : + intel_tcc_temp_masks.digital_readout; +} + /** * intel_tcc_get_tjmax() - returns the default TCC activation Temperature * @cpu: cpu that the MSR should be run on, nagative value means any cpu. @@ -56,7 +218,7 @@ int intel_tcc_get_offset(int cpu) if (err) return err; - return (low >> 24) & 0x3f; + return (low >> 24) & intel_tcc_temp_masks.tcc_offset; } EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, INTEL_TCC); @@ -76,7 +238,10 @@ int intel_tcc_set_offset(int cpu, int offset) u32 low, high; int err; - if (offset < 0 || offset > 0x3f) + if (!intel_tcc_temp_masks.tcc_offset) + return -ENODEV; + + if (offset < 0 || offset > intel_tcc_temp_masks.tcc_offset) return -EINVAL; if (cpu < 0) @@ -90,7 +255,7 @@ int intel_tcc_set_offset(int cpu, int offset) if (low & BIT(31)) return -EPERM; - low &= ~(0x3f << 24); + low &= ~(intel_tcc_temp_masks.tcc_offset << 24); low |= offset << 24; if (cpu < 0) @@ -113,8 +278,8 @@ EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC); */ int intel_tcc_get_temp(int cpu, int *temp, bool pkg) { - u32 low, high; u32 msr = pkg ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS; + u32 low, high, mask; int tjmax, err; tjmax = intel_tcc_get_tjmax(cpu); @@ -132,7 +297,9 @@ int intel_tcc_get_temp(int cpu, int *temp, bool pkg) if (!(low & BIT(31))) return -ENODATA; - *temp = tjmax - ((low >> 16) & 0x7f); + mask = get_temp_mask(pkg); + + *temp = tjmax - ((low >> 16) & mask); return 0; } diff --git a/include/linux/intel_tcc.h b/include/linux/intel_tcc.h index 8ff8eabb4a98..fa788817acfc 100644 --- a/include/linux/intel_tcc.h +++ b/include/linux/intel_tcc.h @@ -14,5 +14,6 @@ int intel_tcc_get_tjmax(int cpu); int intel_tcc_get_offset(int cpu); int intel_tcc_set_offset(int cpu, int offset); int intel_tcc_get_temp(int cpu, int *temp, bool pkg); +u32 intel_tcc_get_offset_mask(void); #endif /* __INTEL_TCC_H__ */ -- cgit v1.2.3-58-ga151 From be6bfb29c55e48567983e24aba7b6bf9a66a45ab Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Fri, 14 Jun 2024 14:16:06 -0700 Subject: thermal: intel: intel_tcc_cooling: Use a model-specific bitmask for TCC offset The TCC offset field in the register MSR_TEMPERATURE_TARGET is not architectural. The TCC library provides a model-specific bitmask. Use it to determine the maximum TCC offset. Suggested-by: Zhang Rui Reviewed-by: Zhang Rui Signed-off-by: Ricardo Neri Link: https://patch.msgid.link/20240614211606.5896-3-ricardo.neri-calderon@linux.intel.com Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_tcc_cooling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c index 63696e7d7b3c..17110ffa80bb 100644 --- a/drivers/thermal/intel/intel_tcc_cooling.c +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -20,7 +20,7 @@ static struct thermal_cooling_device *tcc_cdev; static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - *state = 0x3f; + *state = intel_tcc_get_offset_mask(); return 0; } -- cgit v1.2.3-58-ga151 From 822b2a7c958c7115feb94417d6b941bdc558d621 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 05:45:58 -0700 Subject: thermal: intel: int340x: Cleanup of DLVR sysfs on driver remove When only DLVR enabled without DVFS, during driver remove, proc_thermal_rfim_remove() is not called. Hence the DLVR sysfs is not deleted. On Lunar Lake DLVR is enabled without DVFS, hence this issue can be reproduced. Check also PROC_THERMAL_FEATURE_DLVR to call proc_thermal_rfim_remove(). Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619124600.491168-2-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/processor_thermal_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index d75fae7b7ed2..7c46dd6bee73 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -440,7 +440,8 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device * proc_thermal_rapl_remove(); if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR || - proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS) + proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS || + proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR) proc_thermal_rfim_remove(pdev); if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR) -- cgit v1.2.3-58-ga151 From 332ed4e5c4a347f79acc2a45575700cbf22ff9fe Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 05:45:59 -0700 Subject: thermal: intel: int340x: Capability to map user space to firmware values To ensure compatibility between user inputs and firmware requirements, a conversion mechanism is necessary for certain attributes. For instance, on some platforms, the DLVR frequency must be translated into a predefined index before being communicated to the firmware. On Lunar Lake platform: RFI_FREQ_SELECT and RFI_FREQ: Index 0 corresponds to a DLVR frequency of 2227.2 MHz Index 1 corresponds to a DLVR frequency of 2140 MHz Introduce a feature that enables the conversion of values between user space inputs and firmware-accepted formats. This feature would also facilitate the reverse process, converting firmware values back into user friendly display values. To support this functionality, a model-specific mapping table will be utilized. When available, this table will provide the necessary translations between user space values and firmware values, ensuring seamless communication and accurate settings. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619124600.491168-3-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- .../intel/int340x_thermal/processor_thermal_rfim.c | 80 ++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index e56db75a94fb..c9c77bca2014 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -19,6 +19,12 @@ struct mmio_reg { u16 shift; }; +struct mapping_table { + const char *attr_name; + const u32 value; + const char *mapped_str; +}; + /* These will represent sysfs attribute names */ static const char * const fivr_strings[] = { "vco_ref_code_lo", @@ -62,6 +68,59 @@ static const struct mmio_reg dlvr_mmio_regs[] = { { 1, 0x15A10, 1, 0x1, 16}, /* dlvr_pll_busy */ }; +static int match_mapping_table(const struct mapping_table *table, const char *attr_name, + bool match_int_value, const u32 value, const char *value_str, + char **result_str, u32 *result_int) +{ + bool attr_matched = false; + int i = 0; + + if (!table) + return -EOPNOTSUPP; + + while (table[i].attr_name) { + if (strncmp(table[i].attr_name, attr_name, strlen(attr_name))) + goto match_next; + + attr_matched = true; + + if (match_int_value) { + if (table[i].value != value) + goto match_next; + + *result_str = (char *)table[i].mapped_str; + return 0; + } + + if (strncmp(table[i].mapped_str, value_str, strlen(table[i].mapped_str))) + goto match_next; + + *result_int = table[i].value; + + return 0; +match_next: + i++; + } + + /* If attribute name is matched, then the user space value is invalid */ + if (attr_matched) + return -EINVAL; + + return -EOPNOTSUPP; +} + +static int get_mapped_string(const struct mapping_table *table, const char *attr_name, + u32 value, char **result) +{ + return match_mapping_table(table, attr_name, true, value, NULL, result, NULL); +} + +static int get_mapped_value(const struct mapping_table *table, const char *attr_name, + const char *value, unsigned int *result) +{ + return match_mapping_table(table, attr_name, false, 0, value, NULL, result); +} + /* These will represent sysfs attribute names */ static const char * const dvfs_strings[] = { "rfi_restriction_run_busy", @@ -93,12 +152,14 @@ static ssize_t suffix##_show(struct device *dev,\ struct device_attribute *attr,\ char *buf)\ {\ + const struct mapping_table *mapping = NULL;\ struct proc_thermal_device *proc_priv;\ struct pci_dev *pdev = to_pci_dev(dev);\ const struct mmio_reg *mmio_regs;\ const char **match_strs;\ + int ret, err;\ u32 reg_val;\ - int ret;\ + char *str;\ \ proc_priv = pci_get_drvdata(pdev);\ if (table == 1) {\ @@ -116,7 +177,12 @@ static ssize_t suffix##_show(struct device *dev,\ return ret;\ reg_val = readl((void __iomem *) (proc_priv->mmio_base + mmio_regs[ret].offset));\ ret = (reg_val >> mmio_regs[ret].shift) & mmio_regs[ret].mask;\ - return sprintf(buf, "%u\n", ret);\ + err = get_mapped_string(mapping, attr->attr.name, ret, &str);\ + if (!err)\ + return sprintf(buf, "%s\n", str);\ + if (err == -EOPNOTSUPP)\ + return sprintf(buf, "%u\n", ret);\ + return err;\ } #define RFIM_STORE(suffix, table)\ @@ -124,6 +190,7 @@ static ssize_t suffix##_store(struct device *dev,\ struct device_attribute *attr,\ const char *buf, size_t count)\ {\ + const struct mapping_table *mapping = NULL;\ struct proc_thermal_device *proc_priv;\ struct pci_dev *pdev = to_pci_dev(dev);\ unsigned int input;\ @@ -150,9 +217,14 @@ static ssize_t suffix##_store(struct device *dev,\ return ret;\ if (mmio_regs[ret].read_only)\ return -EPERM;\ - err = kstrtouint(buf, 10, &input);\ - if (err)\ + err = get_mapped_value(mapping, attr->attr.name, buf, &input);\ + if (err == -EINVAL)\ return err;\ + if (err == -EOPNOTSUPP) {\ + err = kstrtouint(buf, 10, &input);\ + if (err)\ + return err;\ + } \ mask = GENMASK(mmio_regs[ret].shift + mmio_regs[ret].bits - 1, mmio_regs[ret].shift);\ reg_val = readl((void __iomem *) (proc_priv->mmio_base + mmio_regs[ret].offset));\ reg_val &= ~mask;\ -- cgit v1.2.3-58-ga151 From 5ba206213a8a6e7f4389ba4f31600b4ee652f59e Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 05:46:00 -0700 Subject: thermal: intel: int340x: Add DLVR support for Lunar Lake Add support for DLVR (Digital Linear Voltage Regulator) for Lunar Lake. There are no new sysfs attributes or difference in operation compared to prior generations. MMIO offset and bit positions are changed compared to Meteor Lake processors. Also for two attributes dlvr_frequency_mhz and dlvr_frequency_select, the value presented or accepted by the firmware is not raw frequency value but an index. For example: RFI_FREQ_SELECT and RFI_FREQ : 0 DLVR freq point 2227.2 MHz : 1 DLVR freq point 2140 MHz Hence create a mapping table for Lunar Lake to map user space values to the firmware accepted values. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619124600.491168-4-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- .../int340x_thermal/processor_thermal_device_pci.c | 3 +- .../intel/int340x_thermal/processor_thermal_rfim.c | 33 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) 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 4a1bfebb1b8e..b6bb96d07ce2 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -408,7 +408,8 @@ 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_WT_REQ) }, - { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, + { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_RAPL | + PROC_THERMAL_FEATURE_DLVR) }, { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) }, diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index c9c77bca2014..0e2dc1426282 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -68,6 +68,25 @@ static const struct mmio_reg dlvr_mmio_regs[] = { { 1, 0x15A10, 1, 0x1, 16}, /* dlvr_pll_busy */ }; +static const struct mmio_reg lnl_dlvr_mmio_regs[] = { + { 0, 0x5A08, 5, 0x1F, 0}, /* dlvr_spread_spectrum_pct */ + { 0, 0x5A08, 1, 0x1, 5}, /* dlvr_control_mode */ + { 0, 0x5A08, 1, 0x1, 6}, /* dlvr_control_lock */ + { 0, 0x5A08, 1, 0x1, 7}, /* dlvr_rfim_enable */ + { 0, 0x5A08, 2, 0x3, 8}, /* dlvr_freq_select */ + { 1, 0x5A10, 2, 0x3, 30}, /* dlvr_hardware_rev */ + { 1, 0x5A10, 2, 0x3, 0}, /* dlvr_freq_mhz */ + { 1, 0x5A10, 1, 0x1, 23}, /* dlvr_pll_busy */ +}; + +static const struct mapping_table lnl_dlvr_mapping[] = { + {"dlvr_freq_select", 0, "2227.2"}, + {"dlvr_freq_select", 1, "2140"}, + {"dlvr_freq_mhz", 0, "2227.2"}, + {"dlvr_freq_mhz", 1, "2140"}, + {NULL, 0, NULL}, +}; + static int match_mapping_table(const struct mapping_table *table, const char *attr_name, bool match_int_value, const u32 value, const char *value_str, char **result_str, u32 *result_int) @@ -167,7 +186,12 @@ static ssize_t suffix##_show(struct device *dev,\ mmio_regs = adl_dvfs_mmio_regs;\ } else if (table == 2) { \ match_strs = (const char **)dlvr_strings;\ - mmio_regs = dlvr_mmio_regs;\ + if (pdev->device == PCI_DEVICE_ID_INTEL_LNLM_THERMAL) {\ + mmio_regs = lnl_dlvr_mmio_regs;\ + mapping = lnl_dlvr_mapping;\ + } else {\ + mmio_regs = dlvr_mmio_regs;\ + } \ } else {\ match_strs = (const char **)fivr_strings;\ mmio_regs = tgl_fivr_mmio_regs;\ @@ -206,7 +230,12 @@ static ssize_t suffix##_store(struct device *dev,\ mmio_regs = adl_dvfs_mmio_regs;\ } else if (table == 2) { \ match_strs = (const char **)dlvr_strings;\ - mmio_regs = dlvr_mmio_regs;\ + if (pdev->device == PCI_DEVICE_ID_INTEL_LNLM_THERMAL) {\ + mmio_regs = lnl_dlvr_mmio_regs;\ + mapping = lnl_dlvr_mapping;\ + } else {\ + mmio_regs = dlvr_mmio_regs;\ + } \ } else {\ match_strs = (const char **)fivr_strings;\ mmio_regs = tgl_fivr_mmio_regs;\ -- cgit v1.2.3-58-ga151 From a264cee31f13ae3b8d32b3e53774759afa55361e Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 10:21:07 -0700 Subject: thermal: intel: int340x: Remove unnecessary calls to free irq Remove calls to devm_free_irq() and pci_free_irq_vectors(). They will be called on driver release anyway. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619172109.497639-2-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c | 3 --- 1 file changed, 3 deletions(-) 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 b6bb96d07ce2..59eb76d4dd81 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -352,9 +352,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0); proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0); - devm_free_irq(&pdev->dev, pdev->irq, pci_info); - pci_free_irq_vectors(pdev); - thermal_zone_device_unregister(pci_info->tzone); proc_thermal_mmio_remove(pdev, pci_info->proc_priv); if (!pci_info->no_legacy) -- cgit v1.2.3-58-ga151 From 7a9a8c5faf418538b53cd63e8fcb1a34b1e3b680 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 10:21:08 -0700 Subject: thermal: intel: int340x: Support MSI interrupt for Lunar Lake The legacy PCI interrupt is no longer supported for processor thermal device on Lunar Lake. The support is via MSI. Add feature PROC_THERMAL_FEATURE_MSI_SUPPORT to support MSI feature per generation. Define this feature for Lunar Lake processors. There are 4 MSI sources: 0 - Package thermal 1 - DDR Thermal 2 - Power floor interrupt 3 - Workload type hint On interrupt, check the source and call the corresponding handler. Here don't need to call proc_thermal_check_wt_intr() and proc_thermal_check_power_floor_intr() to check if the interrupt is for those sources as there is a dedicated MSI interrupt. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619172109.497639-3-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- .../int340x_thermal/processor_thermal_device.h | 1 + .../int340x_thermal/processor_thermal_device_pci.c | 112 ++++++++++++++++----- 2 files changed, 90 insertions(+), 23 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h index 674f3c85dfbc..d5eca6db2c00 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h @@ -65,6 +65,7 @@ struct rapl_mmio_regs { #define PROC_THERMAL_FEATURE_DLVR 0x10 #define PROC_THERMAL_FEATURE_WT_HINT 0x20 #define PROC_THERMAL_FEATURE_POWER_FLOOR 0x40 +#define PROC_THERMAL_FEATURE_MSI_SUPPORT 0x80 #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 59eb76d4dd81..8c6d19fe37c0 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -63,6 +63,18 @@ static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = { { PROC_THERMAL_MMIO_INT_STATUS_1, 0x7200, 8, 0x01 }, }; +/* List of supported MSI IDs (sources) */ +enum proc_thermal_msi_ids { + PKG_THERMAL, + DDR_THERMAL, + THERM_POWER_FLOOR, + WORKLOAD_CHANGE, + MSI_THERMAL_MAX +}; + +/* Stores IRQ associated with a MSI ID */ +static int proc_thermal_msi_map[MSI_THERMAL_MAX]; + #define B0D4_THERMAL_NOTIFY_DELAY 1000 static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY; @@ -146,22 +158,41 @@ static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid) return IRQ_HANDLED; } +static int proc_thermal_match_msi_irq(int irq) +{ + int i; + + if (!use_msi) + goto msi_fail; + + for (i = 0; i < MSI_THERMAL_MAX; i++) { + if (proc_thermal_msi_map[i] == irq) + return i; + } + +msi_fail: + return -EOPNOTSUPP; +} + static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) { struct proc_thermal_pci *pci_info = devid; struct proc_thermal_device *proc_priv; - int ret = IRQ_NONE; + int ret = IRQ_NONE, msi_id; u32 status; proc_priv = pci_info->proc_priv; + msi_id = proc_thermal_match_msi_irq(irq); + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT) { - if (proc_thermal_check_wt_intr(pci_info->proc_priv)) + if (msi_id == WORKLOAD_CHANGE || proc_thermal_check_wt_intr(pci_info->proc_priv)) ret = IRQ_WAKE_THREAD; } if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR) { - if (proc_thermal_check_power_floor_intr(pci_info->proc_priv)) + if (msi_id == THERM_POWER_FLOOR || + proc_thermal_check_power_floor_intr(pci_info->proc_priv)) ret = IRQ_WAKE_THREAD; } @@ -171,7 +202,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) * interrupt before scheduling work function for thermal threshold. */ proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status); - if (status) { + if (msi_id == PKG_THERMAL || status) { /* Disable enable interrupt flag */ proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0); pkg_thermal_schedule_work(&pci_info->work); @@ -244,6 +275,45 @@ static struct thermal_zone_params tzone_params = { .no_hwmon = true, }; +static bool msi_irq; + +static int proc_thermal_setup_msi(struct pci_dev *pdev, struct proc_thermal_pci *pci_info) +{ + int ret, i, irq; + + ret = pci_alloc_irq_vectors(pdev, 1, MSI_THERMAL_MAX, PCI_IRQ_MSI | PCI_IRQ_MSIX); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to allocate vectors!\n"); + return ret; + } + + dev_info(&pdev->dev, "msi enabled:%d msix enabled:%d\n", pdev->msi_enabled, + pdev->msix_enabled); + + for (i = 0; i < MSI_THERMAL_MAX; i++) { + irq = pci_irq_vector(pdev, i); + + ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler, + proc_thermal_irq_thread_handler, + 0, KBUILD_MODNAME, pci_info); + if (ret) { + dev_err(&pdev->dev, "Request IRQ %d failed\n", irq); + goto err_free_msi_vectors; + } + + proc_thermal_msi_map[i] = irq; + } + + msi_irq = true; + + return 0; + +err_free_msi_vectors: + pci_free_irq_vectors(pdev); + + return ret; +} + static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct proc_thermal_device *proc_priv; @@ -253,7 +323,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ .flags = THERMAL_TRIP_FLAG_RW_TEMP, }; int irq_flag = 0, irq, ret; - bool msi_irq = false; proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL); if (!proc_priv) @@ -299,27 +368,24 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ goto err_del_legacy; } - if (use_msi && (pdev->msi_enabled || pdev->msix_enabled)) { - /* request and enable interrupt */ - ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to allocate vectors!\n"); - goto err_ret_tzone; - } + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MSI_SUPPORT) + use_msi = true; - irq = pci_irq_vector(pdev, 0); - msi_irq = true; + if (use_msi) { + ret = proc_thermal_setup_msi(pdev, pci_info); + if (ret) + goto err_ret_tzone; } else { irq_flag = IRQF_SHARED; irq = pdev->irq; - } - ret = devm_request_threaded_irq(&pdev->dev, irq, - proc_thermal_irq_handler, proc_thermal_irq_thread_handler, - irq_flag, KBUILD_MODNAME, pci_info); - if (ret) { - dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq); - goto err_free_vectors; + ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler, + proc_thermal_irq_thread_handler, irq_flag, + KBUILD_MODNAME, pci_info); + if (ret) { + dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq); + goto err_ret_tzone; + } } ret = thermal_zone_device_enable(pci_info->tzone); @@ -405,8 +471,8 @@ 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_WT_REQ) }, - { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_RAPL | - PROC_THERMAL_FEATURE_DLVR) }, + { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_MSI_SUPPORT | + PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR) }, { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) }, -- cgit v1.2.3-58-ga151 From 55397323f3eaba16b93182c35be85aa35cad1432 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 19 Jun 2024 10:21:09 -0700 Subject: thermal: intel: int340x: Enable WLT and power floor support for Lunar Lake Add feature flgas for WLT and power floor for Lunar Lake. Signed-off-by: Srinivas Pandruvada Link: https://patch.msgid.link/20240619172109.497639-4-srinivas.pandruvada@linux.intel.com Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 8c6d19fe37c0..7772bc63f64b 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -472,7 +472,8 @@ 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_WT_REQ) }, { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_MSI_SUPPORT | - PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR) }, + PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR | + PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) }, { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) }, -- cgit v1.2.3-58-ga151 From 6fb75c967162c28b2a50cb4673cce36e0e70e3dc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 17 Jun 2024 20:07:35 +0200 Subject: thermal: uniphier: Use thermal_zone_for_each_trip() for walking trip points It is generally inefficient to iterate over trip indices and call thermal_zone_get_trip() every time to get the struct thermal_trip corresponding to the given trip index, so modify the uniphier thermal driver to use thermal_zone_for_each_trip() for walking trips. Signed-off-by: Rafael J. Wysocki Reviewed-by: Kunihiko Hayashi Link: https://patch.msgid.link/2148114.bB369e8A3T@kreacher [ rjw: Add missing return statement, remove unused local variable ] Signed-off-by: Rafael J. Wysocki --- drivers/thermal/uniphier_thermal.c | 39 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c index 274f36358b21..0325b7195136 100644 --- a/drivers/thermal/uniphier_thermal.c +++ b/drivers/thermal/uniphier_thermal.c @@ -239,13 +239,34 @@ static irqreturn_t uniphier_tm_alarm_irq_thread(int irq, void *_tdev) return IRQ_HANDLED; } +struct trip_walk_data { + struct uniphier_tm_dev *tdev; + int crit_temp; + int index; +}; + +static int uniphier_tm_trip_walk_cb(struct thermal_trip *trip, void *arg) +{ + struct trip_walk_data *twd = arg; + + if (trip->type == THERMAL_TRIP_CRITICAL && + trip->temperature < twd->crit_temp) + twd->crit_temp = trip->temperature; + + uniphier_tm_set_alert(twd->tdev, twd->index, trip->temperature); + twd->tdev->alert_en[twd->index++] = true; + + return 0; +} + static int uniphier_tm_probe(struct platform_device *pdev) { + struct trip_walk_data twd = { .crit_temp = INT_MAX, .index = 0 }; struct device *dev = &pdev->dev; struct regmap *regmap; struct device_node *parent; struct uniphier_tm_dev *tdev; - int i, ret, irq, crit_temp = INT_MAX; + int ret, irq; tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); if (!tdev) @@ -293,20 +314,10 @@ static int uniphier_tm_probe(struct platform_device *pdev) } /* set alert temperatures */ - for (i = 0; i < thermal_zone_get_num_trips(tdev->tz_dev); i++) { - struct thermal_trip trip; + twd.tdev = tdev; + thermal_zone_for_each_trip(tdev->tz_dev, uniphier_tm_trip_walk_cb, &twd); - ret = thermal_zone_get_trip(tdev->tz_dev, i, &trip); - if (ret) - return ret; - - if (trip.type == THERMAL_TRIP_CRITICAL && - trip.temperature < crit_temp) - crit_temp = trip.temperature; - uniphier_tm_set_alert(tdev, i, trip.temperature); - tdev->alert_en[i] = true; - } - if (crit_temp > CRITICAL_TEMP_LIMIT) { + if (twd.crit_temp > CRITICAL_TEMP_LIMIT) { dev_err(dev, "critical trip is over limit(>%d), or not set\n", CRITICAL_TEMP_LIMIT); return -EINVAL; -- cgit v1.2.3-58-ga151 From 4acab508eb03dc1827db6005764de29299e07569 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 3 Jul 2024 10:31:41 +0200 Subject: thermal: core: constify 'type' in devm_thermal_of_cooling_device_register() The 'type' string passed to thermal_of_cooling_device_register() is a 'const char *', so do the same in the devm interface. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20240703083141.96013-1-krzysztof.kozlowski@linaro.org Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 2 +- include/linux/thermal.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 2aa04c46a425..3eb85301d325 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1129,7 +1129,7 @@ static void thermal_cooling_device_release(struct device *dev, void *res) struct thermal_cooling_device * devm_thermal_of_cooling_device_register(struct device *dev, struct device_node *np, - char *type, void *devdata, + const char *type, void *devdata, const struct thermal_cooling_device_ops *ops) { struct thermal_cooling_device **ptr, *tcd; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index f1155c0439c4..f732dab20368 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -261,7 +261,7 @@ thermal_of_cooling_device_register(struct device_node *np, const char *, void *, struct thermal_cooling_device * devm_thermal_of_cooling_device_register(struct device *dev, struct device_node *np, - char *type, void *devdata, + const char *type, void *devdata, const struct thermal_cooling_device_ops *ops); void thermal_cooling_device_update(struct thermal_cooling_device *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); @@ -305,7 +305,7 @@ thermal_of_cooling_device_register(struct device_node *np, static inline struct thermal_cooling_device * devm_thermal_of_cooling_device_register(struct device *dev, struct device_node *np, - char *type, void *devdata, + const char *type, void *devdata, const struct thermal_cooling_device_ops *ops) { return ERR_PTR(-ENODEV); -- cgit v1.2.3-58-ga151 From d05374dee295d771261d382f97c0c23cb15aa104 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 5 Jul 2024 21:44:50 +0200 Subject: thermal: core: Change passive_delay and polling_delay data type It is better to use unsigned int as the data type for the passive_delay and polling_delay arguments of thermal_zone_device_register_with_trips() because they are implicitly cast to unsigned int anyway in thermal_set_delay_jiffies() and if they happen to be negative at that point, the resulting behavior may not be as desired. Update the thermal_zone_device_register_with_trips() definition accordingly. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Link: https://patch.msgid.link/5803791.DvuYhMxLoT@rjwysocki.net Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 3 ++- include/linux/thermal.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 3eb85301d325..7139f729a83d 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1356,7 +1356,8 @@ thermal_zone_device_register_with_trips(const char *type, int num_trips, void *devdata, const struct thermal_zone_device_ops *ops, const struct thermal_zone_params *tzp, - int passive_delay, int polling_delay) + unsigned int passive_delay, + unsigned int polling_delay) { const struct thermal_trip *trip = trips; struct thermal_zone_device *tz; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index f732dab20368..cd0045915af5 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -221,7 +221,8 @@ struct thermal_zone_device *thermal_zone_device_register_with_trips( int num_trips, void *devdata, const struct thermal_zone_device_ops *ops, const struct thermal_zone_params *tzp, - int passive_delay, int polling_delay); + unsigned int passive_delay, + unsigned int polling_delay); struct thermal_zone_device *thermal_tripless_zone_device_register( const char *type, -- cgit v1.2.3-58-ga151 From 463b86fed2b25ddb5f576376bfea00134dd23030 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 2 Jul 2024 16:39:55 +0200 Subject: thermal: helpers: Introduce thermal_trip_is_bound_to_cdev() Introduce a new helper function thermal_trip_is_bound_to_cdev() for checking whether or not a given trip point has been bound to a given cooling device. The primary user of it will be the Tegra thermal driver. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/13545762.uLZWGnKmhe@rjwysocki.net --- drivers/thermal/thermal_helpers.c | 47 +++++++++++++++++++++++++++++---------- include/linux/thermal.h | 3 +++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index d9f4e26ec125..81e019493557 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -39,30 +39,53 @@ int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip return trend; } +static struct thermal_instance *get_instance(struct thermal_zone_device *tz, + struct thermal_cooling_device *cdev, + const struct thermal_trip *trip) +{ + struct thermal_instance *ti; + + list_for_each_entry(ti, &tz->thermal_instances, tz_node) { + if (ti->trip == trip && ti->cdev == cdev) + return ti; + } + + return NULL; +} + +bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev) +{ + bool ret; + + mutex_lock(&tz->lock); + mutex_lock(&cdev->lock); + + ret = !!get_instance(tz, cdev, trip); + + mutex_unlock(&cdev->lock); + mutex_unlock(&tz->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(thermal_trip_is_bound_to_cdev); + struct thermal_instance * get_thermal_instance(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev, int trip_index) { - struct thermal_instance *pos = NULL; - struct thermal_instance *target_instance = NULL; - const struct thermal_trip *trip; + struct thermal_instance *ti; mutex_lock(&tz->lock); mutex_lock(&cdev->lock); - trip = &tz->trips[trip_index].trip; - - list_for_each_entry(pos, &tz->thermal_instances, tz_node) { - if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { - target_instance = pos; - break; - } - } + ti = get_instance(tz, cdev, &tz->trips[trip_index].trip); mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); - return target_instance; + return ti; } EXPORT_SYMBOL(get_thermal_instance); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index cd0045915af5..5a0b66bd34f0 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -270,6 +270,9 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); int thermal_zone_get_slope(struct thermal_zone_device *tz); int thermal_zone_get_offset(struct thermal_zone_device *tz); +bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev); int thermal_zone_device_enable(struct thermal_zone_device *tz); int thermal_zone_device_disable(struct thermal_zone_device *tz); -- cgit v1.2.3-58-ga151 From d1fbf18a0f9403df2edeffa1c7f5a2d66e82c20a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 2 Jul 2024 16:41:03 +0200 Subject: thermal: trip: Add conversion macros for thermal trip priv field Some drivers will need to store integers in the priv field of struct thermal_trip, so add conversion macros for doing this in a consistent way and switch over the int340x_thermal driver that already does it and uses custom conversion functions to using the new macros. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/3297884.aeNJFYEL58@rjwysocki.net --- .../thermal/intel/int340x_thermal/int340x_thermal_zone.c | 14 ++------------ include/linux/thermal.h | 3 +++ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 400fde7cb3b1..cd28a5582a60 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -62,16 +62,6 @@ static void int340x_thermal_critical(struct thermal_zone_device *zone) thermal_zone_device_type(zone)); } -static inline void *int_to_trip_priv(int i) -{ - return (void *)(long)i; -} - -static inline int trip_priv_to_int(const struct thermal_trip *trip) -{ - return (long)trip->priv; -} - static int int340x_thermal_read_trips(struct acpi_device *zone_adev, struct thermal_trip *zone_trips, int trip_cnt) @@ -106,7 +96,7 @@ static int int340x_thermal_read_trips(struct acpi_device *zone_adev, break; zone_trips[trip_cnt].type = THERMAL_TRIP_ACTIVE; - zone_trips[trip_cnt].priv = int_to_trip_priv(i); + zone_trips[trip_cnt].priv = THERMAL_INT_TO_TRIP_PRIV(i); trip_cnt++; } @@ -224,7 +214,7 @@ static int int340x_update_one_trip(struct thermal_trip *trip, void *arg) break; case THERMAL_TRIP_ACTIVE: err = thermal_acpi_active_trip_temp(zone_adev, - trip_priv_to_int(trip), + THERMAL_TRIP_PRIV_TO_INT(trip->priv), &temp); break; default: diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 5a0b66bd34f0..3bd1b361ec34 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -79,6 +79,9 @@ struct thermal_trip { #define THERMAL_TRIP_FLAG_RW (THERMAL_TRIP_FLAG_RW_TEMP | \ THERMAL_TRIP_FLAG_RW_HYST) +#define THERMAL_TRIP_PRIV_TO_INT(_val_) (uintptr_t)(_val_) +#define THERMAL_INT_TO_TRIP_PRIV(_val_) (void *)(uintptr_t)(_val_) + struct thermal_zone_device; struct thermal_zone_device_ops { -- cgit v1.2.3-58-ga151 From b755367602d70deade956cbe0b8a3f5a12f569dc Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 3 Jul 2024 13:54:45 +0800 Subject: thermal: intel: hfi: Give HFI instances package scope The Intel Software Developer's Manual defines the scope of HFI (registers and memory buffer) as a package. Use package scope(*) in the software representation of an HFI instance. Using die scope in HFI instances has the effect of creating multiple conflicting instances for the same package: each instance allocates its own memory buffer and configures the same package-level registers. Specifically, only one of the allocated memory buffers can be set in the MSR_IA32_HW_FEEDBACK_PTR register. CPUs get incorrect HFI data from the table. The problem does not affect current HFI-capable platforms because they all have single-die processors. (*) We used die scope for HFI instances because there had been processors with packages enumerated as dies. None of those systems supported HFI, though. If such a system emerged, it would need to be quirked. Co-developed-by: Chen Yu Signed-off-by: Chen Yu Signed-off-by: Zhang Rui Reviewed-by: Ricardo Neri Link: https://patch.msgid.link/20240703055445.125362-1-rui.zhang@intel.com [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_hfi.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c index a180a98bb9f1..5b18a46a10b0 100644 --- a/drivers/thermal/intel/intel_hfi.c +++ b/drivers/thermal/intel/intel_hfi.c @@ -401,10 +401,10 @@ static void hfi_disable(void) * intel_hfi_online() - Enable HFI on @cpu * @cpu: CPU in which the HFI will be enabled * - * Enable the HFI to be used in @cpu. The HFI is enabled at the die/package - * level. The first CPU in the die/package to come online does the full HFI + * Enable the HFI to be used in @cpu. The HFI is enabled at the package + * level. The first CPU in the package to come online does the full HFI * initialization. Subsequent CPUs will just link themselves to the HFI - * instance of their die/package. + * instance of their package. * * This function is called before enabling the thermal vector in the local APIC * in order to ensure that @cpu has an associated HFI instance when it receives @@ -414,31 +414,31 @@ void intel_hfi_online(unsigned int cpu) { struct hfi_instance *hfi_instance; struct hfi_cpu_info *info; - u16 die_id; + u16 pkg_id; /* Nothing to do if hfi_instances are missing. */ if (!hfi_instances) return; /* - * Link @cpu to the HFI instance of its package/die. It does not + * Link @cpu to the HFI instance of its package. It does not * matter whether the instance has been initialized. */ info = &per_cpu(hfi_cpu_info, cpu); - die_id = topology_logical_die_id(cpu); + pkg_id = topology_logical_package_id(cpu); hfi_instance = info->hfi_instance; if (!hfi_instance) { - if (die_id >= max_hfi_instances) + if (pkg_id >= max_hfi_instances) return; - hfi_instance = &hfi_instances[die_id]; + hfi_instance = &hfi_instances[pkg_id]; info->hfi_instance = hfi_instance; } init_hfi_cpu_index(info); /* - * Now check if the HFI instance of the package/die of @cpu has been + * Now check if the HFI instance of the package of @cpu has been * initialized (by checking its header). In such case, all we have to * do is to add @cpu to this instance's cpumask and enable the instance * if needed. @@ -504,7 +504,7 @@ free_hw_table: * * On some processors, hardware remembers previous programming settings even * after being reprogrammed. Thus, keep HFI enabled even if all CPUs in the - * die/package of @cpu are offline. See note in intel_hfi_online(). + * package of @cpu are offline. See note in intel_hfi_online(). */ void intel_hfi_offline(unsigned int cpu) { @@ -674,9 +674,13 @@ void __init intel_hfi_init(void) if (hfi_parse_features()) return; - /* There is one HFI instance per die/package. */ - max_hfi_instances = topology_max_packages() * - topology_max_dies_per_package(); + /* + * Note: HFI resources are managed at the physical package scope. + * There could be platforms that enumerate packages as Linux dies. + * Special handling would be needed if this happens on an HFI-capable + * platform. + */ + max_hfi_instances = topology_max_packages(); /* * This allocation may fail. CPU hotplug callbacks must check -- cgit v1.2.3-58-ga151 From 81caa5d519a2e5573e0763630a503def7cb480a5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 2 Jul 2024 16:43:36 +0200 Subject: thermal: imx: Drop critical trip check from imx_set_trip_temp() Because the IMX thermal driver does not flag its critical trip as writable, imx_set_trip_temp() will never be invoked for it and so the critical trip check can be dropped from there. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/2272035.iZASKD2KPV@rjwysocki.net --- drivers/thermal/imx_thermal.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 83eaae5ca3b8..c90f28ee4698 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -335,21 +335,12 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) { 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.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; -- cgit v1.2.3-58-ga151 From 0728c810873e1a94e8b767f9809af940c9307d60 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 2 Jul 2024 16:42:33 +0200 Subject: thermal: trip: Pass trip pointer to .set_trip_temp() thermal zone callback Out of several drivers implementing the .set_trip_temp() thermal zone operation, three don't actually use the trip ID argument passed to it, two call __thermal_zone_get_trip() to get a struct thermal_trip corresponding to the given trip ID, and the other use the trip ID as an index into their own data structures with the assumption that it will always match the ordering of entries in the trips table passed to the core during thermal zone registration, which is fragile and not really guaranteed. Even though the trip IDs used by the core are in fact their indices in the trips table passed to it by the thermal zone creator, that is purely a matter of convenience and should not be relied on for correctness. For this reason, modify trip_point_temp_store() to pass a (const) trip pointer to .set_trip_temp() and adjust the drivers implementing it accordingly. This helps to simplify the drivers invoking __thermal_zone_get_trip() from their .set_trip_temp() callback functions because they will not need to do it now and the other drivers can store their internal trip indices in the priv field in struct thermal_trip and their .set_trip_temp() callback functions can get those indices from there. The intel_quark_dts thermal driver can instead use the trip type to determine the requisite trip index. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/8392906.T7Z3S40VBb@rjwysocki.net [ rjw: Add missing colon and 2 empty code lines ] [ rjw: Add missing change in imx_thermal.c and adjust the changelog ] [ rjw: Drop an unused local variable ] Signed-off-by: Rafael J. Wysocki --- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 2 +- drivers/thermal/imx_thermal.c | 4 ++-- .../intel/int340x_thermal/int340x_thermal_zone.c | 8 ++++--- .../int340x_thermal/processor_thermal_device_pci.c | 3 ++- drivers/thermal/intel/intel_quark_dts_thermal.c | 28 +++++++++++++++++----- drivers/thermal/intel/intel_soc_dts_iosf.c | 15 +++++++----- drivers/thermal/intel/x86_pkg_temp_thermal.c | 9 ++++--- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 10 +++----- drivers/thermal/tegra/soctherm.c | 15 ++++-------- drivers/thermal/thermal_sysfs.c | 2 +- include/linux/thermal.h | 3 ++- 11 files changed, 58 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 61a4638d1be2..f8b08f98daa0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -638,7 +638,7 @@ out: } static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device, - int trip, int temp) + const struct thermal_trip *trip, int temp) { struct iwl_mvm *mvm = thermal_zone_device_priv(device); int ret; diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c90f28ee4698..6ad97309bc0a 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -331,8 +331,8 @@ static int imx_change_mode(struct thermal_zone_device *tz, return 0; } -static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id, - int temp) +static int imx_set_trip_temp(struct thermal_zone_device *tz, + const struct thermal_trip *trip, int temp) { struct imx_thermal_data *data = thermal_zone_device_priv(tz); int ret; diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index cd28a5582a60..31ed338eb83c 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -39,13 +39,14 @@ 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) + const struct thermal_trip *trip, int temp) { struct int34x_thermal_zone *d = thermal_zone_device_priv(zone); - char name[] = {'P', 'A', 'T', '0' + trip, '\0'}; + unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv); + char name[] = {'P', 'A', 'T', '0' + trip_index, '\0'}; acpi_status status; - if (trip > 9) + if (trip_index > 9) return -EINVAL; status = acpi_execute_simple_method(d->adev->handle, name, @@ -144,6 +145,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, zone_trips[i].type = THERMAL_TRIP_PASSIVE; zone_trips[i].temperature = THERMAL_TEMP_INVALID; zone_trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP; + zone_trips[i].priv = THERMAL_INT_TO_TRIP_PRIV(i); } trip_cnt = int340x_thermal_read_trips(adev, zone_trips, trip_cnt); 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 4a1bfebb1b8e..4f41fe543340 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -194,7 +194,8 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) return 0; } -static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) +static int sys_set_trip_temp(struct thermal_zone_device *tzd, + const struct thermal_trip *trip, int temp) { struct proc_thermal_pci *pci_info = thermal_zone_device_priv(tzd); int tjmax, _temp; diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c index ec6ad26027bc..47296a14db3c 100644 --- a/drivers/thermal/intel/intel_quark_dts_thermal.c +++ b/drivers/thermal/intel/intel_quark_dts_thermal.c @@ -195,7 +195,7 @@ static int get_trip_temp(int trip) } static int update_trip_temp(struct soc_sensor_entry *aux_entry, - int trip, int temp) + int trip_index, int temp) { u32 out; u32 temp_out; @@ -230,9 +230,9 @@ static int update_trip_temp(struct soc_sensor_entry *aux_entry, */ temp_out = temp + QRK_DTS_TEMP_BASE; out = (store_ptps & ~(QRK_DTS_MASK_TP_THRES << - (trip * QRK_DTS_SHIFT_TP))); + (trip_index * QRK_DTS_SHIFT_TP))); out |= (temp_out & QRK_DTS_MASK_TP_THRES) << - (trip * QRK_DTS_SHIFT_TP); + (trip_index * QRK_DTS_SHIFT_TP); ret = iosf_mbi_write(QRK_MBI_UNIT_RMU, MBI_REG_WRITE, QRK_DTS_REG_OFFSET_PTPS, out); @@ -242,10 +242,26 @@ failed: return ret; } -static inline int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, - int temp) +static inline int sys_set_trip_temp(struct thermal_zone_device *tzd, + const struct thermal_trip *trip, + int temp) { - return update_trip_temp(thermal_zone_device_priv(tzd), trip, temp); + unsigned int trip_index; + + switch (trip->type) { + case THERMAL_TRIP_HOT: + trip_index = QRK_DTS_ID_TP_HOT; + break; + + case THERMAL_TRIP_CRITICAL: + trip_index = QRK_DTS_ID_TP_CRITICAL; + break; + + default: + return -EINVAL; + } + + return update_trip_temp(thermal_zone_device_priv(tzd), trip_index, 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 7adf942665d4..43a29551ba17 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -129,18 +129,20 @@ err_restore_ptps: return status; } -static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, +static int sys_set_trip_temp(struct thermal_zone_device *tzd, + const struct thermal_trip *trip, int temp) { struct intel_soc_dts_sensor_entry *dts = thermal_zone_device_priv(tzd); struct intel_soc_dts_sensors *sensors = dts->sensors; + unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv); int status; if (temp > sensors->tj_max) return -EINVAL; mutex_lock(&sensors->dts_update_lock); - status = update_trip_temp(sensors, trip, temp); + status = update_trip_temp(sensors, trip_index, temp); mutex_unlock(&sensors->dts_update_lock); return status; @@ -293,11 +295,12 @@ static void dts_trips_reset(struct intel_soc_dts_sensors *sensors, int dts_index } static void set_trip(struct thermal_trip *trip, enum thermal_trip_type type, - u8 flags, int temp) + u8 flags, int temp, unsigned int index) { trip->type = type; trip->flags = flags; trip->temperature = temp; + trip->priv = THERMAL_INT_TO_TRIP_PRIV(index); } struct intel_soc_dts_sensors * @@ -332,7 +335,7 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type, sensors->soc_dts[i].sensors = sensors; set_trip(&trips[i][0], THERMAL_TRIP_PASSIVE, - THERMAL_TRIP_FLAG_RW_TEMP, 0); + THERMAL_TRIP_FLAG_RW_TEMP, 0, 0); ret = update_trip_temp(sensors, 0, 0); if (ret) @@ -340,10 +343,10 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type, if (critical_trip) { temp = sensors->tj_max - crit_offset; - set_trip(&trips[i][1], THERMAL_TRIP_CRITICAL, 0, temp); + set_trip(&trips[i][1], THERMAL_TRIP_CRITICAL, 0, temp, 1); } else { set_trip(&trips[i][1], THERMAL_TRIP_PASSIVE, - THERMAL_TRIP_FLAG_RW_TEMP, 0); + THERMAL_TRIP_FLAG_RW_TEMP, 0, 1); temp = 0; } diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index c0ca8e3ff2e7..65b33b56a9be 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -119,9 +119,11 @@ 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) +sys_set_trip_temp(struct thermal_zone_device *tzd, + const struct thermal_trip *trip, int temp) { struct zone_device *zonedev = thermal_zone_device_priv(tzd); + unsigned int trip_index = THERMAL_TRIP_PRIV_TO_INT(trip->priv); u32 l, h, mask, shift, intr; int tj_max, val, ret; @@ -132,7 +134,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) val = (tj_max - temp)/1000; - if (trip >= MAX_NUMBER_OF_TRIPS || val < 0 || val > 0x7f) + if (trip_index >= MAX_NUMBER_OF_TRIPS || val < 0 || val > 0x7f) return -EINVAL; ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, @@ -140,7 +142,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) if (ret < 0) return ret; - if (trip) { + if (trip_index) { mask = THERM_MASK_THRESHOLD1; shift = THERM_SHIFT_THRESHOLD1; intr = THERM_INT_THRESHOLD1_ENABLE; @@ -296,6 +298,7 @@ static int pkg_temp_thermal_trips_init(int cpu, int tj_max, trips[i].type = THERMAL_TRIP_PASSIVE; trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP; + trips[i].priv = THERMAL_INT_TO_TRIP_PRIV(i); pr_debug("%s: cpu=%d, trip=%d, temp=%d\n", __func__, cpu, i, trips[i].temperature); diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 3cd74f6cac8f..96daad28b0c0 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -261,17 +261,13 @@ skip: return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); } -static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) +static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, + const struct thermal_trip *trip, int temp) { struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); - struct thermal_trip trip; int ret; - ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip); - if (ret) - return ret; - - if (trip.type != THERMAL_TRIP_CRITICAL) + if (trip->type != THERMAL_TRIP_CRITICAL) return 0; mutex_lock(&chip->lock); diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c index e7fe8683bfc5..d3dfc34c62c6 100644 --- a/drivers/thermal/tegra/soctherm.c +++ b/drivers/thermal/tegra/soctherm.c @@ -582,23 +582,18 @@ static int tsensor_group_thermtrip_get(struct tegra_soctherm *ts, int id) return temp; } -static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) +static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, + const struct thermal_trip *trip, int temp) { 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; struct device *dev = zone->dev; - int ret; if (!tz) return -EINVAL; - ret = __thermal_zone_get_trip(tz, trip_id, &trip); - if (ret) - return ret; - - if (trip.type == THERMAL_TRIP_CRITICAL) { + if (trip->type == THERMAL_TRIP_CRITICAL) { /* * If thermtrips property is set in DT, * doesn't need to program critical type trip to HW, @@ -609,7 +604,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip else return 0; - } else if (trip.type == THERMAL_TRIP_HOT) { + } else if (trip->type == THERMAL_TRIP_HOT) { int i; for (i = 0; i < THROTTLE_SIZE; i++) { @@ -620,7 +615,7 @@ static int tegra_thermctl_set_trip_temp(struct thermal_zone_device *tz, int trip continue; cdev = ts->throt_cfgs[i].cdev; - if (get_thermal_instance(tz, cdev, trip_id)) + if (thermal_trip_is_bound_to_cdev(tz, trip, cdev)) stc = find_throttle_cfg_by_name(ts, cdev->type); else continue; diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 434b577950be..72b302bf914e 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -113,7 +113,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, if (temp != trip->temperature) { if (tz->ops.set_trip_temp) { - ret = tz->ops.set_trip_temp(tz, trip_id, temp); + ret = tz->ops.set_trip_temp(tz, trip, temp); if (ret) goto unlock; } diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 3bd1b361ec34..cdd9c722cda2 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -93,7 +93,8 @@ struct thermal_zone_device_ops { int (*set_trips) (struct thermal_zone_device *, int, int); int (*change_mode) (struct thermal_zone_device *, enum thermal_device_mode); - int (*set_trip_temp) (struct thermal_zone_device *, int, int); + int (*set_trip_temp) (struct thermal_zone_device *, + const struct thermal_trip *, int); int (*get_crit_temp) (struct thermal_zone_device *, int *); int (*set_emul_temp) (struct thermal_zone_device *, int); int (*get_trend) (struct thermal_zone_device *, -- cgit v1.2.3-58-ga151 From 5b674baa596e624fde8bf62b9a3d8a26eef399b2 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 2 Jul 2024 16:44:27 +0200 Subject: thermal: trip: Fold __thermal_zone_get_trip() into its caller Because __thermal_zone_get_trip() is only called by thermal_zone_get_trip() now, fold the former into the latter. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/22339769.EfDdHjke4D@rjwysocki.net --- drivers/thermal/thermal_trip.c | 18 ++++-------------- include/linux/thermal.h | 2 -- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 2a876d3b93aa..c0b679b846b3 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -114,27 +114,17 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz) dev_err(&tz->device, "Failed to set trips: %d\n", ret); } -int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, - struct thermal_trip *trip) -{ - if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip) - return -EINVAL; - - *trip = tz->trips[trip_id].trip; - return 0; -} -EXPORT_SYMBOL_GPL(__thermal_zone_get_trip); - int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip) { - int ret; + if (!tz || !trip || trip_id < 0 || trip_id >= tz->num_trips) + return -EINVAL; mutex_lock(&tz->lock); - ret = __thermal_zone_get_trip(tz, trip_id, trip); + *trip = tz->trips[trip_id].trip; mutex_unlock(&tz->lock); - return ret; + return 0; } EXPORT_SYMBOL_GPL(thermal_zone_get_trip); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index cdd9c722cda2..25fbf960b474 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -202,8 +202,6 @@ static inline void devm_thermal_of_zone_unregister(struct device *dev, } #endif -int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, - struct thermal_trip *trip); int thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip); int for_each_thermal_trip(struct thermal_zone_device *tz, -- cgit v1.2.3-58-ga151 From 3669716401921c4c545ac2998d7c67f9727ee056 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 11 Jul 2024 14:39:02 +0200 Subject: thermal: core: Add sanity checks for polling_delay and passive_delay If polling_delay is nonzero and passive_delay is greater than polling_delay, the thermal zone temperature will be updated less often when tz->passive is nonzero, which is not as expected. Make the thermal zone registration fail with -EINVAL in that case as this is a clear thermal zone configuration mistake. If polling_delay is nonzero and passive_delay is 0, which is regarded as a valid thermal zone configuration, the thermal zone will use polling except when tz->passive is nonzero. However, the expected behavior in that case is to continue temperature polling with the same delay value regardless of tz->passive, so set passive_delay to the polling_delay value then. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Link: https://patch.msgid.link/5802156.DvuYhMxLoT@rjwysocki.net --- drivers/thermal/thermal_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 7139f729a83d..24e0520340f6 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1390,6 +1390,14 @@ thermal_zone_device_register_with_trips(const char *type, if (num_trips > 0 && !trips) return ERR_PTR(-EINVAL); + if (polling_delay) { + if (passive_delay > polling_delay) + return ERR_PTR(-EINVAL); + + if (!passive_delay) + passive_delay = polling_delay; + } + if (!thermal_class) return ERR_PTR(-ENODEV); -- cgit v1.2.3-58-ga151 From 9d617949d49099d549175979e6454ce64461eaa2 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Mon, 6 May 2024 17:40:10 +0200 Subject: thermal/drivers/renesas: Group all renesas thermal drivers together MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all Renesas thermal drivers to a vendor specific directory. All drivers are moved verbatim apart from the updated include path for thermal_hwmon.h. Signed-off-by: Niklas Söderlund Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240506154011.344324-2-niklas.soderlund+renesas@ragnatech.se --- MAINTAINERS | 4 +- drivers/thermal/Kconfig | 28 +- drivers/thermal/Makefile | 4 +- drivers/thermal/rcar_gen3_thermal.c | 616 ---------------------------- drivers/thermal/rcar_thermal.c | 588 -------------------------- drivers/thermal/renesas/Kconfig | 27 ++ drivers/thermal/renesas/Makefile | 5 + drivers/thermal/renesas/rcar_gen3_thermal.c | 616 ++++++++++++++++++++++++++++ drivers/thermal/renesas/rcar_thermal.c | 588 ++++++++++++++++++++++++++ drivers/thermal/renesas/rzg2l_thermal.c | 249 +++++++++++ drivers/thermal/rzg2l_thermal.c | 249 ----------- 11 files changed, 1490 insertions(+), 1484 deletions(-) delete mode 100644 drivers/thermal/rcar_gen3_thermal.c delete mode 100644 drivers/thermal/rcar_thermal.c create mode 100644 drivers/thermal/renesas/Kconfig create mode 100644 drivers/thermal/renesas/Makefile create mode 100644 drivers/thermal/renesas/rcar_gen3_thermal.c create mode 100644 drivers/thermal/renesas/rcar_thermal.c create mode 100644 drivers/thermal/renesas/rzg2l_thermal.c delete mode 100644 drivers/thermal/rzg2l_thermal.c diff --git a/MAINTAINERS b/MAINTAINERS index 3c4fdf74a3f9..03090276a416 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19076,8 +19076,8 @@ L: linux-renesas-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml F: Documentation/devicetree/bindings/thermal/rcar-thermal.yaml -F: drivers/thermal/rcar_gen3_thermal.c -F: drivers/thermal/rcar_thermal.c +F: drivers/thermal/renesas/rcar_gen3_thermal.c +F: drivers/thermal/renesas/rcar_thermal.c RENESAS RIIC DRIVER M: Chris Brandt diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 204ed89a3ec9..ed16897584b4 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -343,32 +343,6 @@ config ROCKCHIP_THERMAL trip point. Cpufreq is used as the cooling device and will throttle CPUs when the Temperature crosses the passive trip point. -config RCAR_THERMAL - tristate "Renesas R-Car thermal driver" - depends on ARCH_RENESAS || COMPILE_TEST - depends on HAS_IOMEM - help - Enable this to plug the R-Car thermal sensor driver into the Linux - thermal framework. - -config RCAR_GEN3_THERMAL - tristate "Renesas R-Car Gen3 and RZ/G2 thermal driver" - depends on ARCH_RENESAS || COMPILE_TEST - depends on HAS_IOMEM - depends on OF - help - Enable this to plug the R-Car Gen3 or RZ/G2 thermal sensor driver into - the Linux thermal framework. - -config RZG2L_THERMAL - tristate "Renesas RZ/G2L thermal driver" - depends on ARCH_RENESAS || COMPILE_TEST - depends on HAS_IOMEM - depends on OF - help - Enable this to plug the RZ/G2L thermal sensor driver into the Linux - thermal framework. - config KIRKWOOD_THERMAL tristate "Temperature sensor on Marvell Kirkwood SoCs" depends on MACH_KIRKWOOD || COMPILE_TEST @@ -459,6 +433,8 @@ depends on (ARCH_STI || ARCH_STM32) && OF source "drivers/thermal/st/Kconfig" endmenu +source "drivers/thermal/renesas/Kconfig" + source "drivers/thermal/tegra/Kconfig" config GENERIC_ADC_THERMAL diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 5cdf7d68687f..ce7a4752ef52 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -38,9 +38,7 @@ obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_SUN8I_THERMAL) += sun8i_thermal.o obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o -obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o -obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o -obj-$(CONFIG_RZG2L_THERMAL) += rzg2l_thermal.o +obj-y += renesas/ obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o obj-y += samsung/ obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c deleted file mode 100644 index 02494fa142c3..000000000000 --- a/drivers/thermal/rcar_gen3_thermal.c +++ /dev/null @@ -1,616 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * R-Car Gen3 THS thermal sensor driver - * Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen. - * - * Copyright (C) 2016 Renesas Electronics Corporation. - * Copyright (C) 2016 Sang Engineering - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "thermal_hwmon.h" - -/* Register offsets */ -#define REG_GEN3_IRQSTR 0x04 -#define REG_GEN3_IRQMSK 0x08 -#define REG_GEN3_IRQCTL 0x0C -#define REG_GEN3_IRQEN 0x10 -#define REG_GEN3_IRQTEMP1 0x14 -#define REG_GEN3_IRQTEMP2 0x18 -#define REG_GEN3_IRQTEMP3 0x1C -#define REG_GEN3_THCTR 0x20 -#define REG_GEN3_TEMP 0x28 -#define REG_GEN3_THCODE1 0x50 -#define REG_GEN3_THCODE2 0x54 -#define REG_GEN3_THCODE3 0x58 -#define REG_GEN3_PTAT1 0x5c -#define REG_GEN3_PTAT2 0x60 -#define REG_GEN3_PTAT3 0x64 -#define REG_GEN3_THSCP 0x68 -#define REG_GEN4_THSFMON00 0x180 -#define REG_GEN4_THSFMON01 0x184 -#define REG_GEN4_THSFMON02 0x188 -#define REG_GEN4_THSFMON15 0x1BC -#define REG_GEN4_THSFMON16 0x1C0 -#define REG_GEN4_THSFMON17 0x1C4 - -/* IRQ{STR,MSK,EN} bits */ -#define IRQ_TEMP1 BIT(0) -#define IRQ_TEMP2 BIT(1) -#define IRQ_TEMP3 BIT(2) -#define IRQ_TEMPD1 BIT(3) -#define IRQ_TEMPD2 BIT(4) -#define IRQ_TEMPD3 BIT(5) - -/* THCTR bits */ -#define THCTR_PONM BIT(6) -#define THCTR_THSST BIT(0) - -/* THSCP bits */ -#define THSCP_COR_PARA_VLD (BIT(15) | BIT(14)) - -#define CTEMP_MASK 0xFFF - -#define MCELSIUS(temp) ((temp) * 1000) -#define GEN3_FUSE_MASK 0xFFF -#define GEN4_FUSE_MASK 0xFFF - -#define TSC_MAX_NUM 5 - -struct rcar_gen3_thermal_priv; - -struct rcar_thermal_info { - int scale; - int adj_below; - int adj_above; - void (*read_fuses)(struct rcar_gen3_thermal_priv *priv); -}; - -struct equation_set_coef { - int a; - int b; -}; - -struct rcar_gen3_thermal_tsc { - struct rcar_gen3_thermal_priv *priv; - void __iomem *base; - struct thermal_zone_device *zone; - /* Different coefficients are used depending on a threshold. */ - struct { - struct equation_set_coef below; - struct equation_set_coef above; - } coef; - int thcode[3]; -}; - -struct rcar_gen3_thermal_priv { - struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; - struct thermal_zone_device_ops ops; - unsigned int num_tscs; - int ptat[3]; - int tj_t; - const struct rcar_thermal_info *info; -}; - -static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc, - u32 reg) -{ - return ioread32(tsc->base + reg); -} - -static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc, - u32 reg, u32 data) -{ - iowrite32(data, tsc->base + reg); -} - -/* - * Linear approximation for temperature - * - * [temp] = ((thadj - [reg]) * a) / b + adj - * [reg] = thadj - ([temp] - adj) * b / a - * - * The constants a and b are calculated using two triplets of int values PTAT - * and THCODE. PTAT and THCODE can either be read from hardware or use hard - * coded values from the driver. The formula to calculate a and b are taken from - * the datasheet. Different calculations are needed for a and b depending on - * if the input variables ([temp] or [reg]) are above or below a threshold. The - * threshold is also calculated from PTAT and THCODE using formulas from the - * datasheet. - * - * The constant thadj is one of the THCODE values, which one to use depends on - * the threshold and input value. - * - * The constants adj is taken verbatim from the datasheet. Two values exists, - * which one to use depends on the input value and the calculated threshold. - * Furthermore different SoC models supported by the driver have different sets - * of values. The values for each model are stored in the device match data. - */ - -static void rcar_gen3_thermal_shared_coefs(struct rcar_gen3_thermal_priv *priv) -{ - priv->tj_t = - DIV_ROUND_CLOSEST((priv->ptat[1] - priv->ptat[2]) * priv->info->scale, - priv->ptat[0] - priv->ptat[2]) - + priv->info->adj_below; -} -static void rcar_gen3_thermal_tsc_coefs(struct rcar_gen3_thermal_priv *priv, - struct rcar_gen3_thermal_tsc *tsc) -{ - tsc->coef.below.a = priv->info->scale * (priv->ptat[2] - priv->ptat[1]); - tsc->coef.above.a = priv->info->scale * (priv->ptat[0] - priv->ptat[1]); - - tsc->coef.below.b = (priv->ptat[2] - priv->ptat[0]) * (tsc->thcode[2] - tsc->thcode[1]); - tsc->coef.above.b = (priv->ptat[0] - priv->ptat[2]) * (tsc->thcode[1] - tsc->thcode[0]); -} - -static int rcar_gen3_thermal_get_temp(struct thermal_zone_device *tz, int *temp) -{ - struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); - struct rcar_gen3_thermal_priv *priv = tsc->priv; - const struct equation_set_coef *coef; - int adj, decicelsius, reg, thcode; - - /* Read register and convert to mili Celsius */ - reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; - - if (reg < tsc->thcode[1]) { - adj = priv->info->adj_below; - coef = &tsc->coef.below; - thcode = tsc->thcode[2]; - } else { - adj = priv->info->adj_above; - coef = &tsc->coef.above; - thcode = tsc->thcode[0]; - } - - /* - * The dividend can't be grown as it might overflow, instead shorten the - * divisor to convert to decidegree Celsius. If we convert after the - * division precision is lost as we will scale up from whole degrees - * Celsius. - */ - decicelsius = DIV_ROUND_CLOSEST(coef->a * (thcode - reg), coef->b / 10); - - /* Guaranteed operating range is -40C to 125C. */ - - /* Reporting is done in millidegree Celsius */ - *temp = decicelsius * 100 + adj * 1000; - - return 0; -} - -static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc, - int mcelsius) -{ - struct rcar_gen3_thermal_priv *priv = tsc->priv; - const struct equation_set_coef *coef; - int adj, celsius, thcode; - - celsius = DIV_ROUND_CLOSEST(mcelsius, 1000); - if (celsius < priv->tj_t) { - coef = &tsc->coef.below; - adj = priv->info->adj_below; - thcode = tsc->thcode[2]; - } else { - coef = &tsc->coef.above; - adj = priv->info->adj_above; - thcode = tsc->thcode[0]; - } - - return thcode - DIV_ROUND_CLOSEST((celsius - adj) * coef->b, coef->a); -} - -static int rcar_gen3_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) -{ - struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); - u32 irqmsk = 0; - - if (low != -INT_MAX) { - irqmsk |= IRQ_TEMPD1; - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1, - rcar_gen3_thermal_mcelsius_to_temp(tsc, low)); - } - - if (high != INT_MAX) { - irqmsk |= IRQ_TEMP2; - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2, - rcar_gen3_thermal_mcelsius_to_temp(tsc, high)); - } - - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, irqmsk); - - return 0; -} - -static const struct thermal_zone_device_ops rcar_gen3_tz_of_ops = { - .get_temp = rcar_gen3_thermal_get_temp, - .set_trips = rcar_gen3_thermal_set_trips, -}; - -static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data) -{ - struct rcar_gen3_thermal_priv *priv = data; - unsigned int i; - u32 status; - - for (i = 0; i < priv->num_tscs; i++) { - status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR); - rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0); - if (status && priv->tscs[i]->zone) - thermal_zone_device_update(priv->tscs[i]->zone, - THERMAL_EVENT_UNSPECIFIED); - } - - return IRQ_HANDLED; -} - -static void rcar_gen3_thermal_read_fuses_gen3(struct rcar_gen3_thermal_priv *priv) -{ - unsigned int i; - - /* - * Set the pseudo calibration points with fused values. - * PTAT is shared between all TSCs but only fused for the first - * TSC while THCODEs are fused for each TSC. - */ - priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) & - GEN3_FUSE_MASK; - priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) & - GEN3_FUSE_MASK; - priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) & - GEN3_FUSE_MASK; - - for (i = 0; i < priv->num_tscs; i++) { - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - - tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) & - GEN3_FUSE_MASK; - tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) & - GEN3_FUSE_MASK; - tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) & - GEN3_FUSE_MASK; - } -} - -static void rcar_gen3_thermal_read_fuses_gen4(struct rcar_gen3_thermal_priv *priv) -{ - unsigned int i; - - /* - * Set the pseudo calibration points with fused values. - * PTAT is shared between all TSCs but only fused for the first - * TSC while THCODEs are fused for each TSC. - */ - priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON16) & - GEN4_FUSE_MASK; - priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON17) & - GEN4_FUSE_MASK; - priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON15) & - GEN4_FUSE_MASK; - - for (i = 0; i < priv->num_tscs; i++) { - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - - tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON01) & - GEN4_FUSE_MASK; - tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON02) & - GEN4_FUSE_MASK; - tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON00) & - GEN4_FUSE_MASK; - } -} - -static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv) -{ - unsigned int i; - u32 thscp; - - /* If fuses are not set, fallback to pseudo values. */ - thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP); - if (!priv->info->read_fuses || - (thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) { - /* Default THCODE values in case FUSEs are not set. */ - static const int thcodes[TSC_MAX_NUM][3] = { - { 3397, 2800, 2221 }, - { 3393, 2795, 2216 }, - { 3389, 2805, 2237 }, - { 3415, 2694, 2195 }, - { 3356, 2724, 2244 }, - }; - - priv->ptat[0] = 2631; - priv->ptat[1] = 1509; - priv->ptat[2] = 435; - - for (i = 0; i < priv->num_tscs; i++) { - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - - tsc->thcode[0] = thcodes[i][0]; - tsc->thcode[1] = thcodes[i][1]; - tsc->thcode[2] = thcodes[i][2]; - } - - return false; - } - - priv->info->read_fuses(priv); - return true; -} - -static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv, - struct rcar_gen3_thermal_tsc *tsc) -{ - u32 reg_val; - - reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); - reg_val &= ~THCTR_PONM; - rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); - - usleep_range(1000, 2000); - - rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0); - 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); - - reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); - reg_val |= THCTR_THSST; - rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); - - usleep_range(1000, 2000); -} - -static const struct rcar_thermal_info rcar_m3w_thermal_info = { - .scale = 157, - .adj_below = -41, - .adj_above = 116, - .read_fuses = rcar_gen3_thermal_read_fuses_gen3, -}; - -static const struct rcar_thermal_info rcar_gen3_thermal_info = { - .scale = 167, - .adj_below = -41, - .adj_above = 126, - .read_fuses = rcar_gen3_thermal_read_fuses_gen3, -}; - -static const struct rcar_thermal_info rcar_gen4_thermal_info = { - .scale = 167, - .adj_below = -41, - .adj_above = 126, - .read_fuses = rcar_gen3_thermal_read_fuses_gen4, -}; - -static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { - { - .compatible = "renesas,r8a774a1-thermal", - .data = &rcar_m3w_thermal_info, - }, - { - .compatible = "renesas,r8a774b1-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a774e1-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a7795-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a7796-thermal", - .data = &rcar_m3w_thermal_info, - }, - { - .compatible = "renesas,r8a77961-thermal", - .data = &rcar_m3w_thermal_info, - }, - { - .compatible = "renesas,r8a77965-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a77980-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a779a0-thermal", - .data = &rcar_gen3_thermal_info, - }, - { - .compatible = "renesas,r8a779f0-thermal", - .data = &rcar_gen4_thermal_info, - }, - { - .compatible = "renesas,r8a779g0-thermal", - .data = &rcar_gen4_thermal_info, - }, - { - .compatible = "renesas,r8a779h0-thermal", - .data = &rcar_gen4_thermal_info, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); - -static void rcar_gen3_thermal_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - pm_runtime_put(dev); - pm_runtime_disable(dev); -} - -static void rcar_gen3_hwmon_action(void *data) -{ - struct thermal_zone_device *zone = data; - - thermal_remove_hwmon_sysfs(zone); -} - -static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv, - struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - unsigned int i; - char *irqname; - int ret, irq; - - for (i = 0; i < 2; i++) { - irq = platform_get_irq_optional(pdev, i); - if (irq < 0) - return irq; - - irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", - dev_name(dev), i); - if (!irqname) - return -ENOMEM; - - ret = devm_request_threaded_irq(dev, irq, NULL, - rcar_gen3_thermal_irq, - IRQF_ONESHOT, irqname, priv); - if (ret) - return ret; - } - - return 0; -} - -static int rcar_gen3_thermal_probe(struct platform_device *pdev) -{ - struct rcar_gen3_thermal_priv *priv; - struct device *dev = &pdev->dev; - struct resource *res; - struct thermal_zone_device *zone; - unsigned int i; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->ops = rcar_gen3_tz_of_ops; - - priv->info = of_device_get_match_data(dev); - platform_set_drvdata(pdev, priv); - - if (rcar_gen3_thermal_request_irqs(priv, pdev)) - priv->ops.set_trips = NULL; - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - - for (i = 0; i < TSC_MAX_NUM; i++) { - struct rcar_gen3_thermal_tsc *tsc; - - res = platform_get_resource(pdev, IORESOURCE_MEM, i); - if (!res) - break; - - tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); - if (!tsc) { - ret = -ENOMEM; - goto error_unregister; - } - - tsc->priv = priv; - tsc->base = devm_ioremap_resource(dev, res); - if (IS_ERR(tsc->base)) { - ret = PTR_ERR(tsc->base); - goto error_unregister; - } - - priv->tscs[i] = tsc; - } - - priv->num_tscs = i; - - if (!rcar_gen3_thermal_read_fuses(priv)) - dev_info(dev, "No calibration values fused, fallback to driver values\n"); - - rcar_gen3_thermal_shared_coefs(priv); - - for (i = 0; i < priv->num_tscs; i++) { - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - - rcar_gen3_thermal_init(priv, tsc); - rcar_gen3_thermal_tsc_coefs(priv, tsc); - - zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops); - if (IS_ERR(zone)) { - dev_err(dev, "Sensor %u: Can't register thermal zone\n", i); - ret = PTR_ERR(zone); - goto error_unregister; - } - tsc->zone = zone; - - ret = thermal_add_hwmon_sysfs(tsc->zone); - if (ret) - goto error_unregister; - - ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone); - if (ret) - goto error_unregister; - - ret = thermal_zone_get_num_trips(tsc->zone); - if (ret < 0) - goto error_unregister; - - dev_info(dev, "Sensor %u: Loaded %d trip points\n", i, ret); - } - - if (!priv->num_tscs) { - ret = -ENODEV; - goto error_unregister; - } - - return 0; - -error_unregister: - rcar_gen3_thermal_remove(pdev); - - return ret; -} - -static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev) -{ - struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev); - unsigned int i; - - for (i = 0; i < priv->num_tscs; i++) { - struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; - - rcar_gen3_thermal_init(priv, tsc); - } - - return 0; -} - -static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, NULL, - rcar_gen3_thermal_resume); - -static struct platform_driver rcar_gen3_thermal_driver = { - .driver = { - .name = "rcar_gen3_thermal", - .pm = &rcar_gen3_thermal_pm_ops, - .of_match_table = rcar_gen3_thermal_dt_ids, - }, - .probe = rcar_gen3_thermal_probe, - .remove_new = rcar_gen3_thermal_remove, -}; -module_platform_driver(rcar_gen3_thermal_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver"); -MODULE_AUTHOR("Wolfram Sang "); diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c deleted file mode 100644 index 925183753fcb..000000000000 --- a/drivers/thermal/rcar_thermal.c +++ /dev/null @@ -1,588 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * R-Car THS/TSC thermal sensor driver - * - * Copyright (C) 2012 Renesas Solutions Corp. - * Kuninori Morimoto - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "thermal_hwmon.h" - -#define IDLE_INTERVAL 5000 - -#define COMMON_STR 0x00 -#define COMMON_ENR 0x04 -#define COMMON_INTMSK 0x0c - -#define REG_POSNEG 0x20 -#define REG_FILONOFF 0x28 -#define REG_THSCR 0x2c -#define REG_THSSR 0x30 -#define REG_INTCTRL 0x34 - -/* THSCR */ -#define CPCTL (1 << 12) - -/* THSSR */ -#define CTEMP 0x3f - -struct rcar_thermal_common { - void __iomem *base; - struct device *dev; - struct list_head head; - spinlock_t lock; -}; - -struct rcar_thermal_chip { - unsigned int use_of_thermal : 1; - unsigned int has_filonoff : 1; - unsigned int irq_per_ch : 1; - unsigned int needs_suspend_resume : 1; - unsigned int nirqs; - unsigned int ctemp_bands; -}; - -static const struct rcar_thermal_chip rcar_thermal = { - .use_of_thermal = 0, - .has_filonoff = 1, - .irq_per_ch = 0, - .needs_suspend_resume = 0, - .nirqs = 1, - .ctemp_bands = 1, -}; - -static const struct rcar_thermal_chip rcar_gen2_thermal = { - .use_of_thermal = 1, - .has_filonoff = 1, - .irq_per_ch = 0, - .needs_suspend_resume = 0, - .nirqs = 1, - .ctemp_bands = 1, -}; - -static const struct rcar_thermal_chip rcar_gen3_thermal = { - .use_of_thermal = 1, - .has_filonoff = 0, - .irq_per_ch = 1, - .needs_suspend_resume = 1, - /* - * The Gen3 chip has 3 interrupts, but this driver uses only 2 - * interrupts to detect a temperature change, rise or fall. - */ - .nirqs = 2, - .ctemp_bands = 2, -}; - -struct rcar_thermal_priv { - void __iomem *base; - struct rcar_thermal_common *common; - struct thermal_zone_device *zone; - const struct rcar_thermal_chip *chip; - struct delayed_work work; - struct mutex lock; - struct list_head list; - int id; -}; - -#define rcar_thermal_for_each_priv(pos, common) \ - list_for_each_entry(pos, &common->head, list) - -#define MCELSIUS(temp) ((temp) * 1000) -#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) - -static const struct of_device_id rcar_thermal_dt_ids[] = { - { - .compatible = "renesas,rcar-thermal", - .data = &rcar_thermal, - }, - { - .compatible = "renesas,rcar-gen2-thermal", - .data = &rcar_gen2_thermal, - }, - { - .compatible = "renesas,thermal-r8a774c0", - .data = &rcar_gen3_thermal, - }, - { - .compatible = "renesas,thermal-r8a77970", - .data = &rcar_gen3_thermal, - }, - { - .compatible = "renesas,thermal-r8a77990", - .data = &rcar_gen3_thermal, - }, - { - .compatible = "renesas,thermal-r8a77995", - .data = &rcar_gen3_thermal, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); - -/* - * basic functions - */ -#define rcar_thermal_common_read(c, r) \ - _rcar_thermal_common_read(c, COMMON_ ##r) -static u32 _rcar_thermal_common_read(struct rcar_thermal_common *common, - u32 reg) -{ - return ioread32(common->base + reg); -} - -#define rcar_thermal_common_write(c, r, d) \ - _rcar_thermal_common_write(c, COMMON_ ##r, d) -static void _rcar_thermal_common_write(struct rcar_thermal_common *common, - u32 reg, u32 data) -{ - iowrite32(data, common->base + reg); -} - -#define rcar_thermal_common_bset(c, r, m, d) \ - _rcar_thermal_common_bset(c, COMMON_ ##r, m, d) -static void _rcar_thermal_common_bset(struct rcar_thermal_common *common, - u32 reg, u32 mask, u32 data) -{ - u32 val; - - val = ioread32(common->base + reg); - val &= ~mask; - val |= (data & mask); - iowrite32(val, common->base + reg); -} - -#define rcar_thermal_read(p, r) _rcar_thermal_read(p, REG_ ##r) -static u32 _rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg) -{ - return ioread32(priv->base + reg); -} - -#define rcar_thermal_write(p, r, d) _rcar_thermal_write(p, REG_ ##r, d) -static void _rcar_thermal_write(struct rcar_thermal_priv *priv, - u32 reg, u32 data) -{ - iowrite32(data, priv->base + reg); -} - -#define rcar_thermal_bset(p, r, m, d) _rcar_thermal_bset(p, REG_ ##r, m, d) -static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg, - u32 mask, u32 data) -{ - u32 val; - - val = ioread32(priv->base + reg); - val &= ~mask; - val |= (data & mask); - iowrite32(val, priv->base + reg); -} - -/* - * zone device functions - */ -static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) -{ - struct device *dev = rcar_priv_to_dev(priv); - int old, new, ctemp = -EINVAL; - unsigned int i; - - mutex_lock(&priv->lock); - - /* - * TSC decides a value of CPTAP automatically, - * and this is the conditions which validate interrupt. - */ - rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL); - - old = ~0; - for (i = 0; i < 128; i++) { - /* - * we need to wait 300us after changing comparator offset - * to get stable temperature. - * see "Usage Notes" on datasheet - */ - usleep_range(300, 400); - - new = rcar_thermal_read(priv, THSSR) & CTEMP; - if (new == old) { - ctemp = new; - break; - } - old = new; - } - - if (ctemp < 0) { - dev_err(dev, "thermal sensor was broken\n"); - goto err_out_unlock; - } - - /* - * enable IRQ - */ - if (rcar_has_irq_support(priv)) { - if (priv->chip->has_filonoff) - rcar_thermal_write(priv, FILONOFF, 0); - - /* enable Rising/Falling edge interrupt */ - rcar_thermal_write(priv, POSNEG, 0x1); - rcar_thermal_write(priv, INTCTRL, (((ctemp - 0) << 8) | - ((ctemp - 1) << 0))); - } - -err_out_unlock: - mutex_unlock(&priv->lock); - - return ctemp; -} - -static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv, - int *temp) -{ - int ctemp; - - ctemp = rcar_thermal_update_temp(priv); - if (ctemp < 0) - return ctemp; - - /* Guaranteed operating range is -45C to 125C. */ - - if (priv->chip->ctemp_bands == 1) - *temp = MCELSIUS((ctemp * 5) - 65); - else if (ctemp < 24) - *temp = MCELSIUS(((ctemp * 55) - 720) / 10); - else - *temp = MCELSIUS((ctemp * 5) - 60); - - return 0; -} - -static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) -{ - struct rcar_thermal_priv *priv = thermal_zone_device_priv(zone); - - return rcar_thermal_get_current_temp(priv, temp); -} - -static struct thermal_zone_device_ops rcar_thermal_zone_ops = { - .get_temp = rcar_thermal_get_temp, -}; - -static struct thermal_trip trips[] = { - { .type = THERMAL_TRIP_CRITICAL, .temperature = 90000 } -}; - -/* - * interrupt - */ -#define rcar_thermal_irq_enable(p) _rcar_thermal_irq_ctrl(p, 1) -#define rcar_thermal_irq_disable(p) _rcar_thermal_irq_ctrl(p, 0) -static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) -{ - struct rcar_thermal_common *common = priv->common; - unsigned long flags; - u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */ - - if (!rcar_has_irq_support(priv)) - return; - - spin_lock_irqsave(&common->lock, flags); - - rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask); - - spin_unlock_irqrestore(&common->lock, flags); -} - -static void rcar_thermal_work(struct work_struct *work) -{ - struct rcar_thermal_priv *priv; - int ret; - - priv = container_of(work, struct rcar_thermal_priv, work.work); - - ret = rcar_thermal_update_temp(priv); - if (ret < 0) - return; - - rcar_thermal_irq_enable(priv); - - thermal_zone_device_update(priv->zone, THERMAL_EVENT_UNSPECIFIED); -} - -static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) -{ - struct device *dev = rcar_priv_to_dev(priv); - - status = (status >> rcar_id_to_shift(priv)) & 0x3; - - if (status) { - dev_dbg(dev, "thermal%d %s%s\n", - priv->id, - (status & 0x2) ? "Rising " : "", - (status & 0x1) ? "Falling" : ""); - } - - return status; -} - -static irqreturn_t rcar_thermal_irq(int irq, void *data) -{ - struct rcar_thermal_common *common = data; - struct rcar_thermal_priv *priv; - u32 status, mask; - - spin_lock(&common->lock); - - mask = rcar_thermal_common_read(common, INTMSK); - status = rcar_thermal_common_read(common, STR); - rcar_thermal_common_write(common, STR, 0x000F0F0F & mask); - - spin_unlock(&common->lock); - - status = status & ~mask; - - /* - * check the status - */ - rcar_thermal_for_each_priv(priv, common) { - if (rcar_thermal_had_changed(priv, status)) { - rcar_thermal_irq_disable(priv); - queue_delayed_work(system_freezable_wq, &priv->work, - msecs_to_jiffies(300)); - } - } - - return IRQ_HANDLED; -} - -/* - * platform functions - */ -static void rcar_thermal_remove(struct platform_device *pdev) -{ - struct rcar_thermal_common *common = platform_get_drvdata(pdev); - struct device *dev = &pdev->dev; - struct rcar_thermal_priv *priv; - - rcar_thermal_for_each_priv(priv, common) { - rcar_thermal_irq_disable(priv); - cancel_delayed_work_sync(&priv->work); - if (priv->chip->use_of_thermal) - thermal_remove_hwmon_sysfs(priv->zone); - else - thermal_zone_device_unregister(priv->zone); - } - - pm_runtime_put(dev); - pm_runtime_disable(dev); -} - -static int rcar_thermal_probe(struct platform_device *pdev) -{ - struct rcar_thermal_common *common; - struct rcar_thermal_priv *priv; - struct device *dev = &pdev->dev; - struct resource *res; - const struct rcar_thermal_chip *chip = of_device_get_match_data(dev); - int mres = 0; - int i; - int ret = -ENODEV; - int idle = IDLE_INTERVAL; - u32 enr_bits = 0; - - common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); - if (!common) - return -ENOMEM; - - platform_set_drvdata(pdev, common); - - INIT_LIST_HEAD(&common->head); - spin_lock_init(&common->lock); - common->dev = dev; - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - - for (i = 0; i < chip->nirqs; i++) { - int irq; - - ret = platform_get_irq_optional(pdev, i); - if (ret < 0 && ret != -ENXIO) - goto error_unregister; - if (ret > 0) - irq = ret; - else - break; - - if (!common->base) { - /* - * platform has IRQ support. - * Then, driver uses common registers - * rcar_has_irq_support() will be enabled - */ - res = platform_get_resource(pdev, IORESOURCE_MEM, - mres++); - common->base = devm_ioremap_resource(dev, res); - if (IS_ERR(common->base)) { - ret = PTR_ERR(common->base); - goto error_unregister; - } - - idle = 0; /* polling delay is not needed */ - } - - ret = devm_request_irq(dev, irq, rcar_thermal_irq, - IRQF_SHARED, dev_name(dev), common); - if (ret) { - dev_err(dev, "irq request failed\n "); - goto error_unregister; - } - - /* update ENR bits */ - if (chip->irq_per_ch) - enr_bits |= 1 << i; - } - - for (i = 0;; i++) { - res = platform_get_resource(pdev, IORESOURCE_MEM, mres++); - if (!res) - break; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto error_unregister; - } - - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) { - ret = PTR_ERR(priv->base); - goto error_unregister; - } - - priv->common = common; - priv->id = i; - priv->chip = chip; - mutex_init(&priv->lock); - INIT_LIST_HEAD(&priv->list); - INIT_DELAYED_WORK(&priv->work, rcar_thermal_work); - ret = rcar_thermal_update_temp(priv); - if (ret < 0) - goto error_unregister; - - if (chip->use_of_thermal) { - priv->zone = devm_thermal_of_zone_register( - dev, i, priv, - &rcar_thermal_zone_ops); - } else { - priv->zone = thermal_zone_device_register_with_trips( - "rcar_thermal", trips, ARRAY_SIZE(trips), priv, - &rcar_thermal_zone_ops, NULL, 0, - idle); - - ret = thermal_zone_device_enable(priv->zone); - if (ret) { - thermal_zone_device_unregister(priv->zone); - priv->zone = ERR_PTR(ret); - } - } - if (IS_ERR(priv->zone)) { - dev_err(dev, "can't register thermal zone\n"); - ret = PTR_ERR(priv->zone); - priv->zone = NULL; - goto error_unregister; - } - - if (chip->use_of_thermal) { - ret = thermal_add_hwmon_sysfs(priv->zone); - if (ret) - goto error_unregister; - } - - rcar_thermal_irq_enable(priv); - - list_move_tail(&priv->list, &common->head); - - /* update ENR bits */ - if (!chip->irq_per_ch) - enr_bits |= 3 << (i * 8); - } - - if (common->base && enr_bits) - rcar_thermal_common_write(common, ENR, enr_bits); - - dev_info(dev, "%d sensor probed\n", i); - - return 0; - -error_unregister: - rcar_thermal_remove(pdev); - - return ret; -} - -#ifdef CONFIG_PM_SLEEP -static int rcar_thermal_suspend(struct device *dev) -{ - struct rcar_thermal_common *common = dev_get_drvdata(dev); - struct rcar_thermal_priv *priv = list_first_entry(&common->head, - typeof(*priv), list); - - if (priv->chip->needs_suspend_resume) { - rcar_thermal_common_write(common, ENR, 0); - rcar_thermal_irq_disable(priv); - rcar_thermal_bset(priv, THSCR, CPCTL, 0); - } - - return 0; -} - -static int rcar_thermal_resume(struct device *dev) -{ - struct rcar_thermal_common *common = dev_get_drvdata(dev); - struct rcar_thermal_priv *priv = list_first_entry(&common->head, - typeof(*priv), list); - int ret; - - if (priv->chip->needs_suspend_resume) { - ret = rcar_thermal_update_temp(priv); - if (ret < 0) - return ret; - rcar_thermal_irq_enable(priv); - rcar_thermal_common_write(common, ENR, 0x03); - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend, - rcar_thermal_resume); - -static struct platform_driver rcar_thermal_driver = { - .driver = { - .name = "rcar_thermal", - .pm = &rcar_thermal_pm_ops, - .of_match_table = rcar_thermal_dt_ids, - }, - .probe = rcar_thermal_probe, - .remove_new = rcar_thermal_remove, -}; -module_platform_driver(rcar_thermal_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver"); -MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/thermal/renesas/Kconfig b/drivers/thermal/renesas/Kconfig new file mode 100644 index 000000000000..1be65a03d290 --- /dev/null +++ b/drivers/thermal/renesas/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config RCAR_THERMAL + tristate "Renesas R-Car thermal driver" + depends on ARCH_RENESAS || COMPILE_TEST + depends on HAS_IOMEM + help + Enable this to plug the R-Car thermal sensor driver into the Linux + thermal framework. + +config RCAR_GEN3_THERMAL + tristate "Renesas R-Car Gen3 and RZ/G2 thermal driver" + depends on ARCH_RENESAS || COMPILE_TEST + depends on HAS_IOMEM + depends on OF + help + Enable this to plug the R-Car Gen3 or RZ/G2 thermal sensor driver into + the Linux thermal framework. + +config RZG2L_THERMAL + tristate "Renesas RZ/G2L thermal driver" + depends on ARCH_RENESAS || COMPILE_TEST + depends on HAS_IOMEM + depends on OF + help + Enable this to plug the RZ/G2L thermal sensor driver into the Linux + thermal framework. diff --git a/drivers/thermal/renesas/Makefile b/drivers/thermal/renesas/Makefile new file mode 100644 index 000000000000..bf9cb3cb94d6 --- /dev/null +++ b/drivers/thermal/renesas/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o +obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o +obj-$(CONFIG_RZG2L_THERMAL) += rzg2l_thermal.o diff --git a/drivers/thermal/renesas/rcar_gen3_thermal.c b/drivers/thermal/renesas/rcar_gen3_thermal.c new file mode 100644 index 000000000000..5c769871753a --- /dev/null +++ b/drivers/thermal/renesas/rcar_gen3_thermal.c @@ -0,0 +1,616 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car Gen3 THS thermal sensor driver + * Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen. + * + * Copyright (C) 2016 Renesas Electronics Corporation. + * Copyright (C) 2016 Sang Engineering + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../thermal_hwmon.h" + +/* Register offsets */ +#define REG_GEN3_IRQSTR 0x04 +#define REG_GEN3_IRQMSK 0x08 +#define REG_GEN3_IRQCTL 0x0C +#define REG_GEN3_IRQEN 0x10 +#define REG_GEN3_IRQTEMP1 0x14 +#define REG_GEN3_IRQTEMP2 0x18 +#define REG_GEN3_IRQTEMP3 0x1C +#define REG_GEN3_THCTR 0x20 +#define REG_GEN3_TEMP 0x28 +#define REG_GEN3_THCODE1 0x50 +#define REG_GEN3_THCODE2 0x54 +#define REG_GEN3_THCODE3 0x58 +#define REG_GEN3_PTAT1 0x5c +#define REG_GEN3_PTAT2 0x60 +#define REG_GEN3_PTAT3 0x64 +#define REG_GEN3_THSCP 0x68 +#define REG_GEN4_THSFMON00 0x180 +#define REG_GEN4_THSFMON01 0x184 +#define REG_GEN4_THSFMON02 0x188 +#define REG_GEN4_THSFMON15 0x1BC +#define REG_GEN4_THSFMON16 0x1C0 +#define REG_GEN4_THSFMON17 0x1C4 + +/* IRQ{STR,MSK,EN} bits */ +#define IRQ_TEMP1 BIT(0) +#define IRQ_TEMP2 BIT(1) +#define IRQ_TEMP3 BIT(2) +#define IRQ_TEMPD1 BIT(3) +#define IRQ_TEMPD2 BIT(4) +#define IRQ_TEMPD3 BIT(5) + +/* THCTR bits */ +#define THCTR_PONM BIT(6) +#define THCTR_THSST BIT(0) + +/* THSCP bits */ +#define THSCP_COR_PARA_VLD (BIT(15) | BIT(14)) + +#define CTEMP_MASK 0xFFF + +#define MCELSIUS(temp) ((temp) * 1000) +#define GEN3_FUSE_MASK 0xFFF +#define GEN4_FUSE_MASK 0xFFF + +#define TSC_MAX_NUM 5 + +struct rcar_gen3_thermal_priv; + +struct rcar_thermal_info { + int scale; + int adj_below; + int adj_above; + void (*read_fuses)(struct rcar_gen3_thermal_priv *priv); +}; + +struct equation_set_coef { + int a; + int b; +}; + +struct rcar_gen3_thermal_tsc { + struct rcar_gen3_thermal_priv *priv; + void __iomem *base; + struct thermal_zone_device *zone; + /* Different coefficients are used depending on a threshold. */ + struct { + struct equation_set_coef below; + struct equation_set_coef above; + } coef; + int thcode[3]; +}; + +struct rcar_gen3_thermal_priv { + struct rcar_gen3_thermal_tsc *tscs[TSC_MAX_NUM]; + struct thermal_zone_device_ops ops; + unsigned int num_tscs; + int ptat[3]; + int tj_t; + const struct rcar_thermal_info *info; +}; + +static inline u32 rcar_gen3_thermal_read(struct rcar_gen3_thermal_tsc *tsc, + u32 reg) +{ + return ioread32(tsc->base + reg); +} + +static inline void rcar_gen3_thermal_write(struct rcar_gen3_thermal_tsc *tsc, + u32 reg, u32 data) +{ + iowrite32(data, tsc->base + reg); +} + +/* + * Linear approximation for temperature + * + * [temp] = ((thadj - [reg]) * a) / b + adj + * [reg] = thadj - ([temp] - adj) * b / a + * + * The constants a and b are calculated using two triplets of int values PTAT + * and THCODE. PTAT and THCODE can either be read from hardware or use hard + * coded values from the driver. The formula to calculate a and b are taken from + * the datasheet. Different calculations are needed for a and b depending on + * if the input variables ([temp] or [reg]) are above or below a threshold. The + * threshold is also calculated from PTAT and THCODE using formulas from the + * datasheet. + * + * The constant thadj is one of the THCODE values, which one to use depends on + * the threshold and input value. + * + * The constants adj is taken verbatim from the datasheet. Two values exists, + * which one to use depends on the input value and the calculated threshold. + * Furthermore different SoC models supported by the driver have different sets + * of values. The values for each model are stored in the device match data. + */ + +static void rcar_gen3_thermal_shared_coefs(struct rcar_gen3_thermal_priv *priv) +{ + priv->tj_t = + DIV_ROUND_CLOSEST((priv->ptat[1] - priv->ptat[2]) * priv->info->scale, + priv->ptat[0] - priv->ptat[2]) + + priv->info->adj_below; +} +static void rcar_gen3_thermal_tsc_coefs(struct rcar_gen3_thermal_priv *priv, + struct rcar_gen3_thermal_tsc *tsc) +{ + tsc->coef.below.a = priv->info->scale * (priv->ptat[2] - priv->ptat[1]); + tsc->coef.above.a = priv->info->scale * (priv->ptat[0] - priv->ptat[1]); + + tsc->coef.below.b = (priv->ptat[2] - priv->ptat[0]) * (tsc->thcode[2] - tsc->thcode[1]); + tsc->coef.above.b = (priv->ptat[0] - priv->ptat[2]) * (tsc->thcode[1] - tsc->thcode[0]); +} + +static int rcar_gen3_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); + struct rcar_gen3_thermal_priv *priv = tsc->priv; + const struct equation_set_coef *coef; + int adj, decicelsius, reg, thcode; + + /* Read register and convert to mili Celsius */ + reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; + + if (reg < tsc->thcode[1]) { + adj = priv->info->adj_below; + coef = &tsc->coef.below; + thcode = tsc->thcode[2]; + } else { + adj = priv->info->adj_above; + coef = &tsc->coef.above; + thcode = tsc->thcode[0]; + } + + /* + * The dividend can't be grown as it might overflow, instead shorten the + * divisor to convert to decidegree Celsius. If we convert after the + * division precision is lost as we will scale up from whole degrees + * Celsius. + */ + decicelsius = DIV_ROUND_CLOSEST(coef->a * (thcode - reg), coef->b / 10); + + /* Guaranteed operating range is -40C to 125C. */ + + /* Reporting is done in millidegree Celsius */ + *temp = decicelsius * 100 + adj * 1000; + + return 0; +} + +static int rcar_gen3_thermal_mcelsius_to_temp(struct rcar_gen3_thermal_tsc *tsc, + int mcelsius) +{ + struct rcar_gen3_thermal_priv *priv = tsc->priv; + const struct equation_set_coef *coef; + int adj, celsius, thcode; + + celsius = DIV_ROUND_CLOSEST(mcelsius, 1000); + if (celsius < priv->tj_t) { + coef = &tsc->coef.below; + adj = priv->info->adj_below; + thcode = tsc->thcode[2]; + } else { + coef = &tsc->coef.above; + adj = priv->info->adj_above; + thcode = tsc->thcode[0]; + } + + return thcode - DIV_ROUND_CLOSEST((celsius - adj) * coef->b, coef->a); +} + +static int rcar_gen3_thermal_set_trips(struct thermal_zone_device *tz, int low, int high) +{ + struct rcar_gen3_thermal_tsc *tsc = thermal_zone_device_priv(tz); + u32 irqmsk = 0; + + if (low != -INT_MAX) { + irqmsk |= IRQ_TEMPD1; + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP1, + rcar_gen3_thermal_mcelsius_to_temp(tsc, low)); + } + + if (high != INT_MAX) { + irqmsk |= IRQ_TEMP2; + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQTEMP2, + rcar_gen3_thermal_mcelsius_to_temp(tsc, high)); + } + + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQMSK, irqmsk); + + return 0; +} + +static const struct thermal_zone_device_ops rcar_gen3_tz_of_ops = { + .get_temp = rcar_gen3_thermal_get_temp, + .set_trips = rcar_gen3_thermal_set_trips, +}; + +static irqreturn_t rcar_gen3_thermal_irq(int irq, void *data) +{ + struct rcar_gen3_thermal_priv *priv = data; + unsigned int i; + u32 status; + + for (i = 0; i < priv->num_tscs; i++) { + status = rcar_gen3_thermal_read(priv->tscs[i], REG_GEN3_IRQSTR); + rcar_gen3_thermal_write(priv->tscs[i], REG_GEN3_IRQSTR, 0); + if (status && priv->tscs[i]->zone) + thermal_zone_device_update(priv->tscs[i]->zone, + THERMAL_EVENT_UNSPECIFIED); + } + + return IRQ_HANDLED; +} + +static void rcar_gen3_thermal_read_fuses_gen3(struct rcar_gen3_thermal_priv *priv) +{ + unsigned int i; + + /* + * Set the pseudo calibration points with fused values. + * PTAT is shared between all TSCs but only fused for the first + * TSC while THCODEs are fused for each TSC. + */ + priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) & + GEN3_FUSE_MASK; + priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) & + GEN3_FUSE_MASK; + priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) & + GEN3_FUSE_MASK; + + for (i = 0; i < priv->num_tscs; i++) { + struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; + + tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) & + GEN3_FUSE_MASK; + tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) & + GEN3_FUSE_MASK; + tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) & + GEN3_FUSE_MASK; + } +} + +static void rcar_gen3_thermal_read_fuses_gen4(struct rcar_gen3_thermal_priv *priv) +{ + unsigned int i; + + /* + * Set the pseudo calibration points with fused values. + * PTAT is shared between all TSCs but only fused for the first + * TSC while THCODEs are fused for each TSC. + */ + priv->ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON16) & + GEN4_FUSE_MASK; + priv->ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON17) & + GEN4_FUSE_MASK; + priv->ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN4_THSFMON15) & + GEN4_FUSE_MASK; + + for (i = 0; i < priv->num_tscs; i++) { + struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; + + tsc->thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON01) & + GEN4_FUSE_MASK; + tsc->thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON02) & + GEN4_FUSE_MASK; + tsc->thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN4_THSFMON00) & + GEN4_FUSE_MASK; + } +} + +static bool rcar_gen3_thermal_read_fuses(struct rcar_gen3_thermal_priv *priv) +{ + unsigned int i; + u32 thscp; + + /* If fuses are not set, fallback to pseudo values. */ + thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP); + if (!priv->info->read_fuses || + (thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD) { + /* Default THCODE values in case FUSEs are not set. */ + static const int thcodes[TSC_MAX_NUM][3] = { + { 3397, 2800, 2221 }, + { 3393, 2795, 2216 }, + { 3389, 2805, 2237 }, + { 3415, 2694, 2195 }, + { 3356, 2724, 2244 }, + }; + + priv->ptat[0] = 2631; + priv->ptat[1] = 1509; + priv->ptat[2] = 435; + + for (i = 0; i < priv->num_tscs; i++) { + struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; + + tsc->thcode[0] = thcodes[i][0]; + tsc->thcode[1] = thcodes[i][1]; + tsc->thcode[2] = thcodes[i][2]; + } + + return false; + } + + priv->info->read_fuses(priv); + return true; +} + +static void rcar_gen3_thermal_init(struct rcar_gen3_thermal_priv *priv, + struct rcar_gen3_thermal_tsc *tsc) +{ + u32 reg_val; + + reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); + reg_val &= ~THCTR_PONM; + rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); + + usleep_range(1000, 2000); + + rcar_gen3_thermal_write(tsc, REG_GEN3_IRQCTL, 0); + 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); + + reg_val = rcar_gen3_thermal_read(tsc, REG_GEN3_THCTR); + reg_val |= THCTR_THSST; + rcar_gen3_thermal_write(tsc, REG_GEN3_THCTR, reg_val); + + usleep_range(1000, 2000); +} + +static const struct rcar_thermal_info rcar_m3w_thermal_info = { + .scale = 157, + .adj_below = -41, + .adj_above = 116, + .read_fuses = rcar_gen3_thermal_read_fuses_gen3, +}; + +static const struct rcar_thermal_info rcar_gen3_thermal_info = { + .scale = 167, + .adj_below = -41, + .adj_above = 126, + .read_fuses = rcar_gen3_thermal_read_fuses_gen3, +}; + +static const struct rcar_thermal_info rcar_gen4_thermal_info = { + .scale = 167, + .adj_below = -41, + .adj_above = 126, + .read_fuses = rcar_gen3_thermal_read_fuses_gen4, +}; + +static const struct of_device_id rcar_gen3_thermal_dt_ids[] = { + { + .compatible = "renesas,r8a774a1-thermal", + .data = &rcar_m3w_thermal_info, + }, + { + .compatible = "renesas,r8a774b1-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a774e1-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a7795-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a7796-thermal", + .data = &rcar_m3w_thermal_info, + }, + { + .compatible = "renesas,r8a77961-thermal", + .data = &rcar_m3w_thermal_info, + }, + { + .compatible = "renesas,r8a77965-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a77980-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a779a0-thermal", + .data = &rcar_gen3_thermal_info, + }, + { + .compatible = "renesas,r8a779f0-thermal", + .data = &rcar_gen4_thermal_info, + }, + { + .compatible = "renesas,r8a779g0-thermal", + .data = &rcar_gen4_thermal_info, + }, + { + .compatible = "renesas,r8a779h0-thermal", + .data = &rcar_gen4_thermal_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids); + +static void rcar_gen3_thermal_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + pm_runtime_put(dev); + pm_runtime_disable(dev); +} + +static void rcar_gen3_hwmon_action(void *data) +{ + struct thermal_zone_device *zone = data; + + thermal_remove_hwmon_sysfs(zone); +} + +static int rcar_gen3_thermal_request_irqs(struct rcar_gen3_thermal_priv *priv, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + unsigned int i; + char *irqname; + int ret, irq; + + for (i = 0; i < 2; i++) { + irq = platform_get_irq_optional(pdev, i); + if (irq < 0) + return irq; + + irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", + dev_name(dev), i); + if (!irqname) + return -ENOMEM; + + ret = devm_request_threaded_irq(dev, irq, NULL, + rcar_gen3_thermal_irq, + IRQF_ONESHOT, irqname, priv); + if (ret) + return ret; + } + + return 0; +} + +static int rcar_gen3_thermal_probe(struct platform_device *pdev) +{ + struct rcar_gen3_thermal_priv *priv; + struct device *dev = &pdev->dev; + struct resource *res; + struct thermal_zone_device *zone; + unsigned int i; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->ops = rcar_gen3_tz_of_ops; + + priv->info = of_device_get_match_data(dev); + platform_set_drvdata(pdev, priv); + + if (rcar_gen3_thermal_request_irqs(priv, pdev)) + priv->ops.set_trips = NULL; + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + for (i = 0; i < TSC_MAX_NUM; i++) { + struct rcar_gen3_thermal_tsc *tsc; + + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) + break; + + tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); + if (!tsc) { + ret = -ENOMEM; + goto error_unregister; + } + + tsc->priv = priv; + tsc->base = devm_ioremap_resource(dev, res); + if (IS_ERR(tsc->base)) { + ret = PTR_ERR(tsc->base); + goto error_unregister; + } + + priv->tscs[i] = tsc; + } + + priv->num_tscs = i; + + if (!rcar_gen3_thermal_read_fuses(priv)) + dev_info(dev, "No calibration values fused, fallback to driver values\n"); + + rcar_gen3_thermal_shared_coefs(priv); + + for (i = 0; i < priv->num_tscs; i++) { + struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; + + rcar_gen3_thermal_init(priv, tsc); + rcar_gen3_thermal_tsc_coefs(priv, tsc); + + zone = devm_thermal_of_zone_register(dev, i, tsc, &priv->ops); + if (IS_ERR(zone)) { + dev_err(dev, "Sensor %u: Can't register thermal zone\n", i); + ret = PTR_ERR(zone); + goto error_unregister; + } + tsc->zone = zone; + + ret = thermal_add_hwmon_sysfs(tsc->zone); + if (ret) + goto error_unregister; + + ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone); + if (ret) + goto error_unregister; + + ret = thermal_zone_get_num_trips(tsc->zone); + if (ret < 0) + goto error_unregister; + + dev_info(dev, "Sensor %u: Loaded %d trip points\n", i, ret); + } + + if (!priv->num_tscs) { + ret = -ENODEV; + goto error_unregister; + } + + return 0; + +error_unregister: + rcar_gen3_thermal_remove(pdev); + + return ret; +} + +static int __maybe_unused rcar_gen3_thermal_resume(struct device *dev) +{ + struct rcar_gen3_thermal_priv *priv = dev_get_drvdata(dev); + unsigned int i; + + for (i = 0; i < priv->num_tscs; i++) { + struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i]; + + rcar_gen3_thermal_init(priv, tsc); + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(rcar_gen3_thermal_pm_ops, NULL, + rcar_gen3_thermal_resume); + +static struct platform_driver rcar_gen3_thermal_driver = { + .driver = { + .name = "rcar_gen3_thermal", + .pm = &rcar_gen3_thermal_pm_ops, + .of_match_table = rcar_gen3_thermal_dt_ids, + }, + .probe = rcar_gen3_thermal_probe, + .remove_new = rcar_gen3_thermal_remove, +}; +module_platform_driver(rcar_gen3_thermal_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("R-Car Gen3 THS thermal sensor driver"); +MODULE_AUTHOR("Wolfram Sang "); diff --git a/drivers/thermal/renesas/rcar_thermal.c b/drivers/thermal/renesas/rcar_thermal.c new file mode 100644 index 000000000000..1e93f60b6d74 --- /dev/null +++ b/drivers/thermal/renesas/rcar_thermal.c @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car THS/TSC thermal sensor driver + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../thermal_hwmon.h" + +#define IDLE_INTERVAL 5000 + +#define COMMON_STR 0x00 +#define COMMON_ENR 0x04 +#define COMMON_INTMSK 0x0c + +#define REG_POSNEG 0x20 +#define REG_FILONOFF 0x28 +#define REG_THSCR 0x2c +#define REG_THSSR 0x30 +#define REG_INTCTRL 0x34 + +/* THSCR */ +#define CPCTL (1 << 12) + +/* THSSR */ +#define CTEMP 0x3f + +struct rcar_thermal_common { + void __iomem *base; + struct device *dev; + struct list_head head; + spinlock_t lock; +}; + +struct rcar_thermal_chip { + unsigned int use_of_thermal : 1; + unsigned int has_filonoff : 1; + unsigned int irq_per_ch : 1; + unsigned int needs_suspend_resume : 1; + unsigned int nirqs; + unsigned int ctemp_bands; +}; + +static const struct rcar_thermal_chip rcar_thermal = { + .use_of_thermal = 0, + .has_filonoff = 1, + .irq_per_ch = 0, + .needs_suspend_resume = 0, + .nirqs = 1, + .ctemp_bands = 1, +}; + +static const struct rcar_thermal_chip rcar_gen2_thermal = { + .use_of_thermal = 1, + .has_filonoff = 1, + .irq_per_ch = 0, + .needs_suspend_resume = 0, + .nirqs = 1, + .ctemp_bands = 1, +}; + +static const struct rcar_thermal_chip rcar_gen3_thermal = { + .use_of_thermal = 1, + .has_filonoff = 0, + .irq_per_ch = 1, + .needs_suspend_resume = 1, + /* + * The Gen3 chip has 3 interrupts, but this driver uses only 2 + * interrupts to detect a temperature change, rise or fall. + */ + .nirqs = 2, + .ctemp_bands = 2, +}; + +struct rcar_thermal_priv { + void __iomem *base; + struct rcar_thermal_common *common; + struct thermal_zone_device *zone; + const struct rcar_thermal_chip *chip; + struct delayed_work work; + struct mutex lock; + struct list_head list; + int id; +}; + +#define rcar_thermal_for_each_priv(pos, common) \ + list_for_each_entry(pos, &common->head, list) + +#define MCELSIUS(temp) ((temp) * 1000) +#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) + +static const struct of_device_id rcar_thermal_dt_ids[] = { + { + .compatible = "renesas,rcar-thermal", + .data = &rcar_thermal, + }, + { + .compatible = "renesas,rcar-gen2-thermal", + .data = &rcar_gen2_thermal, + }, + { + .compatible = "renesas,thermal-r8a774c0", + .data = &rcar_gen3_thermal, + }, + { + .compatible = "renesas,thermal-r8a77970", + .data = &rcar_gen3_thermal, + }, + { + .compatible = "renesas,thermal-r8a77990", + .data = &rcar_gen3_thermal, + }, + { + .compatible = "renesas,thermal-r8a77995", + .data = &rcar_gen3_thermal, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); + +/* + * basic functions + */ +#define rcar_thermal_common_read(c, r) \ + _rcar_thermal_common_read(c, COMMON_ ##r) +static u32 _rcar_thermal_common_read(struct rcar_thermal_common *common, + u32 reg) +{ + return ioread32(common->base + reg); +} + +#define rcar_thermal_common_write(c, r, d) \ + _rcar_thermal_common_write(c, COMMON_ ##r, d) +static void _rcar_thermal_common_write(struct rcar_thermal_common *common, + u32 reg, u32 data) +{ + iowrite32(data, common->base + reg); +} + +#define rcar_thermal_common_bset(c, r, m, d) \ + _rcar_thermal_common_bset(c, COMMON_ ##r, m, d) +static void _rcar_thermal_common_bset(struct rcar_thermal_common *common, + u32 reg, u32 mask, u32 data) +{ + u32 val; + + val = ioread32(common->base + reg); + val &= ~mask; + val |= (data & mask); + iowrite32(val, common->base + reg); +} + +#define rcar_thermal_read(p, r) _rcar_thermal_read(p, REG_ ##r) +static u32 _rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg) +{ + return ioread32(priv->base + reg); +} + +#define rcar_thermal_write(p, r, d) _rcar_thermal_write(p, REG_ ##r, d) +static void _rcar_thermal_write(struct rcar_thermal_priv *priv, + u32 reg, u32 data) +{ + iowrite32(data, priv->base + reg); +} + +#define rcar_thermal_bset(p, r, m, d) _rcar_thermal_bset(p, REG_ ##r, m, d) +static void _rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg, + u32 mask, u32 data) +{ + u32 val; + + val = ioread32(priv->base + reg); + val &= ~mask; + val |= (data & mask); + iowrite32(val, priv->base + reg); +} + +/* + * zone device functions + */ +static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) +{ + struct device *dev = rcar_priv_to_dev(priv); + int old, new, ctemp = -EINVAL; + unsigned int i; + + mutex_lock(&priv->lock); + + /* + * TSC decides a value of CPTAP automatically, + * and this is the conditions which validate interrupt. + */ + rcar_thermal_bset(priv, THSCR, CPCTL, CPCTL); + + old = ~0; + for (i = 0; i < 128; i++) { + /* + * we need to wait 300us after changing comparator offset + * to get stable temperature. + * see "Usage Notes" on datasheet + */ + usleep_range(300, 400); + + new = rcar_thermal_read(priv, THSSR) & CTEMP; + if (new == old) { + ctemp = new; + break; + } + old = new; + } + + if (ctemp < 0) { + dev_err(dev, "thermal sensor was broken\n"); + goto err_out_unlock; + } + + /* + * enable IRQ + */ + if (rcar_has_irq_support(priv)) { + if (priv->chip->has_filonoff) + rcar_thermal_write(priv, FILONOFF, 0); + + /* enable Rising/Falling edge interrupt */ + rcar_thermal_write(priv, POSNEG, 0x1); + rcar_thermal_write(priv, INTCTRL, (((ctemp - 0) << 8) | + ((ctemp - 1) << 0))); + } + +err_out_unlock: + mutex_unlock(&priv->lock); + + return ctemp; +} + +static int rcar_thermal_get_current_temp(struct rcar_thermal_priv *priv, + int *temp) +{ + int ctemp; + + ctemp = rcar_thermal_update_temp(priv); + if (ctemp < 0) + return ctemp; + + /* Guaranteed operating range is -45C to 125C. */ + + if (priv->chip->ctemp_bands == 1) + *temp = MCELSIUS((ctemp * 5) - 65); + else if (ctemp < 24) + *temp = MCELSIUS(((ctemp * 55) - 720) / 10); + else + *temp = MCELSIUS((ctemp * 5) - 60); + + return 0; +} + +static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) +{ + struct rcar_thermal_priv *priv = thermal_zone_device_priv(zone); + + return rcar_thermal_get_current_temp(priv, temp); +} + +static struct thermal_zone_device_ops rcar_thermal_zone_ops = { + .get_temp = rcar_thermal_get_temp, +}; + +static struct thermal_trip trips[] = { + { .type = THERMAL_TRIP_CRITICAL, .temperature = 90000 } +}; + +/* + * interrupt + */ +#define rcar_thermal_irq_enable(p) _rcar_thermal_irq_ctrl(p, 1) +#define rcar_thermal_irq_disable(p) _rcar_thermal_irq_ctrl(p, 0) +static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) +{ + struct rcar_thermal_common *common = priv->common; + unsigned long flags; + u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */ + + if (!rcar_has_irq_support(priv)) + return; + + spin_lock_irqsave(&common->lock, flags); + + rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask); + + spin_unlock_irqrestore(&common->lock, flags); +} + +static void rcar_thermal_work(struct work_struct *work) +{ + struct rcar_thermal_priv *priv; + int ret; + + priv = container_of(work, struct rcar_thermal_priv, work.work); + + ret = rcar_thermal_update_temp(priv); + if (ret < 0) + return; + + rcar_thermal_irq_enable(priv); + + thermal_zone_device_update(priv->zone, THERMAL_EVENT_UNSPECIFIED); +} + +static u32 rcar_thermal_had_changed(struct rcar_thermal_priv *priv, u32 status) +{ + struct device *dev = rcar_priv_to_dev(priv); + + status = (status >> rcar_id_to_shift(priv)) & 0x3; + + if (status) { + dev_dbg(dev, "thermal%d %s%s\n", + priv->id, + (status & 0x2) ? "Rising " : "", + (status & 0x1) ? "Falling" : ""); + } + + return status; +} + +static irqreturn_t rcar_thermal_irq(int irq, void *data) +{ + struct rcar_thermal_common *common = data; + struct rcar_thermal_priv *priv; + u32 status, mask; + + spin_lock(&common->lock); + + mask = rcar_thermal_common_read(common, INTMSK); + status = rcar_thermal_common_read(common, STR); + rcar_thermal_common_write(common, STR, 0x000F0F0F & mask); + + spin_unlock(&common->lock); + + status = status & ~mask; + + /* + * check the status + */ + rcar_thermal_for_each_priv(priv, common) { + if (rcar_thermal_had_changed(priv, status)) { + rcar_thermal_irq_disable(priv); + queue_delayed_work(system_freezable_wq, &priv->work, + msecs_to_jiffies(300)); + } + } + + return IRQ_HANDLED; +} + +/* + * platform functions + */ +static void rcar_thermal_remove(struct platform_device *pdev) +{ + struct rcar_thermal_common *common = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct rcar_thermal_priv *priv; + + rcar_thermal_for_each_priv(priv, common) { + rcar_thermal_irq_disable(priv); + cancel_delayed_work_sync(&priv->work); + if (priv->chip->use_of_thermal) + thermal_remove_hwmon_sysfs(priv->zone); + else + thermal_zone_device_unregister(priv->zone); + } + + pm_runtime_put(dev); + pm_runtime_disable(dev); +} + +static int rcar_thermal_probe(struct platform_device *pdev) +{ + struct rcar_thermal_common *common; + struct rcar_thermal_priv *priv; + struct device *dev = &pdev->dev; + struct resource *res; + const struct rcar_thermal_chip *chip = of_device_get_match_data(dev); + int mres = 0; + int i; + int ret = -ENODEV; + int idle = IDLE_INTERVAL; + u32 enr_bits = 0; + + common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); + if (!common) + return -ENOMEM; + + platform_set_drvdata(pdev, common); + + INIT_LIST_HEAD(&common->head); + spin_lock_init(&common->lock); + common->dev = dev; + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + for (i = 0; i < chip->nirqs; i++) { + int irq; + + ret = platform_get_irq_optional(pdev, i); + if (ret < 0 && ret != -ENXIO) + goto error_unregister; + if (ret > 0) + irq = ret; + else + break; + + if (!common->base) { + /* + * platform has IRQ support. + * Then, driver uses common registers + * rcar_has_irq_support() will be enabled + */ + res = platform_get_resource(pdev, IORESOURCE_MEM, + mres++); + common->base = devm_ioremap_resource(dev, res); + if (IS_ERR(common->base)) { + ret = PTR_ERR(common->base); + goto error_unregister; + } + + idle = 0; /* polling delay is not needed */ + } + + ret = devm_request_irq(dev, irq, rcar_thermal_irq, + IRQF_SHARED, dev_name(dev), common); + if (ret) { + dev_err(dev, "irq request failed\n "); + goto error_unregister; + } + + /* update ENR bits */ + if (chip->irq_per_ch) + enr_bits |= 1 << i; + } + + for (i = 0;; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, mres++); + if (!res) + break; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto error_unregister; + } + + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) { + ret = PTR_ERR(priv->base); + goto error_unregister; + } + + priv->common = common; + priv->id = i; + priv->chip = chip; + mutex_init(&priv->lock); + INIT_LIST_HEAD(&priv->list); + INIT_DELAYED_WORK(&priv->work, rcar_thermal_work); + ret = rcar_thermal_update_temp(priv); + if (ret < 0) + goto error_unregister; + + if (chip->use_of_thermal) { + priv->zone = devm_thermal_of_zone_register( + dev, i, priv, + &rcar_thermal_zone_ops); + } else { + priv->zone = thermal_zone_device_register_with_trips( + "rcar_thermal", trips, ARRAY_SIZE(trips), priv, + &rcar_thermal_zone_ops, NULL, 0, + idle); + + ret = thermal_zone_device_enable(priv->zone); + if (ret) { + thermal_zone_device_unregister(priv->zone); + priv->zone = ERR_PTR(ret); + } + } + if (IS_ERR(priv->zone)) { + dev_err(dev, "can't register thermal zone\n"); + ret = PTR_ERR(priv->zone); + priv->zone = NULL; + goto error_unregister; + } + + if (chip->use_of_thermal) { + ret = thermal_add_hwmon_sysfs(priv->zone); + if (ret) + goto error_unregister; + } + + rcar_thermal_irq_enable(priv); + + list_move_tail(&priv->list, &common->head); + + /* update ENR bits */ + if (!chip->irq_per_ch) + enr_bits |= 3 << (i * 8); + } + + if (common->base && enr_bits) + rcar_thermal_common_write(common, ENR, enr_bits); + + dev_info(dev, "%d sensor probed\n", i); + + return 0; + +error_unregister: + rcar_thermal_remove(pdev); + + return ret; +} + +#ifdef CONFIG_PM_SLEEP +static int rcar_thermal_suspend(struct device *dev) +{ + struct rcar_thermal_common *common = dev_get_drvdata(dev); + struct rcar_thermal_priv *priv = list_first_entry(&common->head, + typeof(*priv), list); + + if (priv->chip->needs_suspend_resume) { + rcar_thermal_common_write(common, ENR, 0); + rcar_thermal_irq_disable(priv); + rcar_thermal_bset(priv, THSCR, CPCTL, 0); + } + + return 0; +} + +static int rcar_thermal_resume(struct device *dev) +{ + struct rcar_thermal_common *common = dev_get_drvdata(dev); + struct rcar_thermal_priv *priv = list_first_entry(&common->head, + typeof(*priv), list); + int ret; + + if (priv->chip->needs_suspend_resume) { + ret = rcar_thermal_update_temp(priv); + if (ret < 0) + return ret; + rcar_thermal_irq_enable(priv); + rcar_thermal_common_write(common, ENR, 0x03); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(rcar_thermal_pm_ops, rcar_thermal_suspend, + rcar_thermal_resume); + +static struct platform_driver rcar_thermal_driver = { + .driver = { + .name = "rcar_thermal", + .pm = &rcar_thermal_pm_ops, + .of_match_table = rcar_thermal_dt_ids, + }, + .probe = rcar_thermal_probe, + .remove_new = rcar_thermal_remove, +}; +module_platform_driver(rcar_thermal_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver"); +MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/thermal/renesas/rzg2l_thermal.c b/drivers/thermal/renesas/rzg2l_thermal.c new file mode 100644 index 000000000000..0e1cb9045ee6 --- /dev/null +++ b/drivers/thermal/renesas/rzg2l_thermal.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/G2L TSU Thermal Sensor Driver + * + * Copyright (C) 2021 Renesas Electronics Corporation + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../thermal_hwmon.h" + +#define CTEMP_MASK 0xFFF + +/* default calibration values, if FUSE values are missing */ +#define SW_CALIB0_VAL 3148 +#define SW_CALIB1_VAL 503 + +/* Register offsets */ +#define TSU_SM 0x00 +#define TSU_ST 0x04 +#define TSU_SAD 0x0C +#define TSU_SS 0x10 + +#define OTPTSUTRIM_REG(n) (0x18 + ((n) * 0x4)) +#define OTPTSUTRIM_EN_MASK BIT(31) +#define OTPTSUTRIM_MASK GENMASK(11, 0) + +/* Sensor Mode Register(TSU_SM) */ +#define TSU_SM_EN_TS BIT(0) +#define TSU_SM_ADC_EN_TS BIT(1) +#define TSU_SM_NORMAL_MODE (TSU_SM_EN_TS | TSU_SM_ADC_EN_TS) + +/* TSU_ST bits */ +#define TSU_ST_START BIT(0) + +#define TSU_SS_CONV_RUNNING BIT(0) + +#define TS_CODE_AVE_SCALE(x) ((x) * 1000000) +#define MCELSIUS(temp) ((temp) * MILLIDEGREE_PER_DEGREE) +#define TS_CODE_CAP_TIMES 8 /* Total number of ADC data samples */ + +#define RZG2L_THERMAL_GRAN 500 /* milli Celsius */ +#define RZG2L_TSU_SS_TIMEOUT_US 1000 + +#define CURVATURE_CORRECTION_CONST 13 + +struct rzg2l_thermal_priv { + struct device *dev; + void __iomem *base; + struct thermal_zone_device *zone; + struct reset_control *rstc; + u32 calib0, calib1; +}; + +static inline u32 rzg2l_thermal_read(struct rzg2l_thermal_priv *priv, u32 reg) +{ + return ioread32(priv->base + reg); +} + +static inline void rzg2l_thermal_write(struct rzg2l_thermal_priv *priv, u32 reg, + u32 data) +{ + iowrite32(data, priv->base + reg); +} + +static int rzg2l_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct rzg2l_thermal_priv *priv = thermal_zone_device_priv(tz); + u32 result = 0, dsensor, ts_code_ave; + int val, i; + + for (i = 0; i < TS_CODE_CAP_TIMES ; i++) { + /* + * TSU repeats measurement at 20 microseconds intervals and + * automatically updates the results of measurement. As per + * the HW manual for measuring temperature we need to read 8 + * values consecutively and then take the average. + * ts_code_ave = (ts_code[0] + ⋯ + ts_code[7]) / 8 + */ + result += rzg2l_thermal_read(priv, TSU_SAD) & CTEMP_MASK; + usleep_range(20, 30); + } + + ts_code_ave = result / TS_CODE_CAP_TIMES; + + /* + * Calculate actual sensor value by applying curvature correction formula + * dsensor = ts_code_ave / (1 + ts_code_ave * 0.000013). Here we are doing + * integer calculation by scaling all the values by 1000000. + */ + dsensor = TS_CODE_AVE_SCALE(ts_code_ave) / + (TS_CODE_AVE_SCALE(1) + (ts_code_ave * CURVATURE_CORRECTION_CONST)); + + /* + * The temperature Tj is calculated by the formula + * Tj = (dsensor − calib1) * 165/ (calib0 − calib1) − 40 + * where calib0 and calib1 are the calibration values. + */ + val = ((dsensor - priv->calib1) * (MCELSIUS(165) / + (priv->calib0 - priv->calib1))) - MCELSIUS(40); + + *temp = roundup(val, RZG2L_THERMAL_GRAN); + + return 0; +} + +static const struct thermal_zone_device_ops rzg2l_tz_of_ops = { + .get_temp = rzg2l_thermal_get_temp, +}; + +static int rzg2l_thermal_init(struct rzg2l_thermal_priv *priv) +{ + u32 reg_val; + + rzg2l_thermal_write(priv, TSU_SM, TSU_SM_NORMAL_MODE); + rzg2l_thermal_write(priv, TSU_ST, 0); + + /* + * Before setting the START bit, TSU should be in normal operating + * mode. As per the HW manual, it will take 60 µs to place the TSU + * into normal operating mode. + */ + usleep_range(60, 80); + + reg_val = rzg2l_thermal_read(priv, TSU_ST); + reg_val |= TSU_ST_START; + rzg2l_thermal_write(priv, TSU_ST, reg_val); + + return readl_poll_timeout(priv->base + TSU_SS, reg_val, + reg_val == TSU_SS_CONV_RUNNING, 50, + RZG2L_TSU_SS_TIMEOUT_US); +} + +static void rzg2l_thermal_reset_assert_pm_disable_put(struct platform_device *pdev) +{ + struct rzg2l_thermal_priv *priv = dev_get_drvdata(&pdev->dev); + + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + reset_control_assert(priv->rstc); +} + +static void rzg2l_thermal_remove(struct platform_device *pdev) +{ + struct rzg2l_thermal_priv *priv = dev_get_drvdata(&pdev->dev); + + thermal_remove_hwmon_sysfs(priv->zone); + rzg2l_thermal_reset_assert_pm_disable_put(pdev); +} + +static int rzg2l_thermal_probe(struct platform_device *pdev) +{ + struct thermal_zone_device *zone; + struct rzg2l_thermal_priv *priv; + struct device *dev = &pdev->dev; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->dev = dev; + priv->rstc = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(priv->rstc)) + return dev_err_probe(dev, PTR_ERR(priv->rstc), + "failed to get cpg reset"); + + ret = reset_control_deassert(priv->rstc); + if (ret) + return dev_err_probe(dev, ret, "failed to deassert"); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + priv->calib0 = rzg2l_thermal_read(priv, OTPTSUTRIM_REG(0)); + if (priv->calib0 & OTPTSUTRIM_EN_MASK) + priv->calib0 &= OTPTSUTRIM_MASK; + else + priv->calib0 = SW_CALIB0_VAL; + + priv->calib1 = rzg2l_thermal_read(priv, OTPTSUTRIM_REG(1)); + if (priv->calib1 & OTPTSUTRIM_EN_MASK) + priv->calib1 &= OTPTSUTRIM_MASK; + else + priv->calib1 = SW_CALIB1_VAL; + + platform_set_drvdata(pdev, priv); + ret = rzg2l_thermal_init(priv); + if (ret) { + dev_err(dev, "Failed to start TSU"); + goto err; + } + + zone = devm_thermal_of_zone_register(dev, 0, priv, + &rzg2l_tz_of_ops); + if (IS_ERR(zone)) { + dev_err(dev, "Can't register thermal zone"); + ret = PTR_ERR(zone); + goto err; + } + + priv->zone = zone; + ret = thermal_add_hwmon_sysfs(priv->zone); + if (ret) + goto err; + + dev_dbg(dev, "TSU probed with %s calibration values", + rzg2l_thermal_read(priv, OTPTSUTRIM_REG(0)) ? "hw" : "sw"); + + return 0; + +err: + rzg2l_thermal_reset_assert_pm_disable_put(pdev); + return ret; +} + +static const struct of_device_id rzg2l_thermal_dt_ids[] = { + { .compatible = "renesas,rzg2l-tsu", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rzg2l_thermal_dt_ids); + +static struct platform_driver rzg2l_thermal_driver = { + .driver = { + .name = "rzg2l_thermal", + .of_match_table = rzg2l_thermal_dt_ids, + }, + .probe = rzg2l_thermal_probe, + .remove_new = rzg2l_thermal_remove, +}; +module_platform_driver(rzg2l_thermal_driver); + +MODULE_DESCRIPTION("Renesas RZ/G2L TSU Thermal Sensor Driver"); +MODULE_AUTHOR("Biju Das "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/rzg2l_thermal.c b/drivers/thermal/rzg2l_thermal.c deleted file mode 100644 index 04efd824ac4c..000000000000 --- a/drivers/thermal/rzg2l_thermal.c +++ /dev/null @@ -1,249 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Renesas RZ/G2L TSU Thermal Sensor Driver - * - * Copyright (C) 2021 Renesas Electronics Corporation - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "thermal_hwmon.h" - -#define CTEMP_MASK 0xFFF - -/* default calibration values, if FUSE values are missing */ -#define SW_CALIB0_VAL 3148 -#define SW_CALIB1_VAL 503 - -/* Register offsets */ -#define TSU_SM 0x00 -#define TSU_ST 0x04 -#define TSU_SAD 0x0C -#define TSU_SS 0x10 - -#define OTPTSUTRIM_REG(n) (0x18 + ((n) * 0x4)) -#define OTPTSUTRIM_EN_MASK BIT(31) -#define OTPTSUTRIM_MASK GENMASK(11, 0) - -/* Sensor Mode Register(TSU_SM) */ -#define TSU_SM_EN_TS BIT(0) -#define TSU_SM_ADC_EN_TS BIT(1) -#define TSU_SM_NORMAL_MODE (TSU_SM_EN_TS | TSU_SM_ADC_EN_TS) - -/* TSU_ST bits */ -#define TSU_ST_START BIT(0) - -#define TSU_SS_CONV_RUNNING BIT(0) - -#define TS_CODE_AVE_SCALE(x) ((x) * 1000000) -#define MCELSIUS(temp) ((temp) * MILLIDEGREE_PER_DEGREE) -#define TS_CODE_CAP_TIMES 8 /* Total number of ADC data samples */ - -#define RZG2L_THERMAL_GRAN 500 /* milli Celsius */ -#define RZG2L_TSU_SS_TIMEOUT_US 1000 - -#define CURVATURE_CORRECTION_CONST 13 - -struct rzg2l_thermal_priv { - struct device *dev; - void __iomem *base; - struct thermal_zone_device *zone; - struct reset_control *rstc; - u32 calib0, calib1; -}; - -static inline u32 rzg2l_thermal_read(struct rzg2l_thermal_priv *priv, u32 reg) -{ - return ioread32(priv->base + reg); -} - -static inline void rzg2l_thermal_write(struct rzg2l_thermal_priv *priv, u32 reg, - u32 data) -{ - iowrite32(data, priv->base + reg); -} - -static int rzg2l_thermal_get_temp(struct thermal_zone_device *tz, int *temp) -{ - struct rzg2l_thermal_priv *priv = thermal_zone_device_priv(tz); - u32 result = 0, dsensor, ts_code_ave; - int val, i; - - for (i = 0; i < TS_CODE_CAP_TIMES ; i++) { - /* - * TSU repeats measurement at 20 microseconds intervals and - * automatically updates the results of measurement. As per - * the HW manual for measuring temperature we need to read 8 - * values consecutively and then take the average. - * ts_code_ave = (ts_code[0] + ⋯ + ts_code[7]) / 8 - */ - result += rzg2l_thermal_read(priv, TSU_SAD) & CTEMP_MASK; - usleep_range(20, 30); - } - - ts_code_ave = result / TS_CODE_CAP_TIMES; - - /* - * Calculate actual sensor value by applying curvature correction formula - * dsensor = ts_code_ave / (1 + ts_code_ave * 0.000013). Here we are doing - * integer calculation by scaling all the values by 1000000. - */ - dsensor = TS_CODE_AVE_SCALE(ts_code_ave) / - (TS_CODE_AVE_SCALE(1) + (ts_code_ave * CURVATURE_CORRECTION_CONST)); - - /* - * The temperature Tj is calculated by the formula - * Tj = (dsensor − calib1) * 165/ (calib0 − calib1) − 40 - * where calib0 and calib1 are the calibration values. - */ - val = ((dsensor - priv->calib1) * (MCELSIUS(165) / - (priv->calib0 - priv->calib1))) - MCELSIUS(40); - - *temp = roundup(val, RZG2L_THERMAL_GRAN); - - return 0; -} - -static const struct thermal_zone_device_ops rzg2l_tz_of_ops = { - .get_temp = rzg2l_thermal_get_temp, -}; - -static int rzg2l_thermal_init(struct rzg2l_thermal_priv *priv) -{ - u32 reg_val; - - rzg2l_thermal_write(priv, TSU_SM, TSU_SM_NORMAL_MODE); - rzg2l_thermal_write(priv, TSU_ST, 0); - - /* - * Before setting the START bit, TSU should be in normal operating - * mode. As per the HW manual, it will take 60 µs to place the TSU - * into normal operating mode. - */ - usleep_range(60, 80); - - reg_val = rzg2l_thermal_read(priv, TSU_ST); - reg_val |= TSU_ST_START; - rzg2l_thermal_write(priv, TSU_ST, reg_val); - - return readl_poll_timeout(priv->base + TSU_SS, reg_val, - reg_val == TSU_SS_CONV_RUNNING, 50, - RZG2L_TSU_SS_TIMEOUT_US); -} - -static void rzg2l_thermal_reset_assert_pm_disable_put(struct platform_device *pdev) -{ - struct rzg2l_thermal_priv *priv = dev_get_drvdata(&pdev->dev); - - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - reset_control_assert(priv->rstc); -} - -static void rzg2l_thermal_remove(struct platform_device *pdev) -{ - struct rzg2l_thermal_priv *priv = dev_get_drvdata(&pdev->dev); - - thermal_remove_hwmon_sysfs(priv->zone); - rzg2l_thermal_reset_assert_pm_disable_put(pdev); -} - -static int rzg2l_thermal_probe(struct platform_device *pdev) -{ - struct thermal_zone_device *zone; - struct rzg2l_thermal_priv *priv; - struct device *dev = &pdev->dev; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - priv->dev = dev; - priv->rstc = devm_reset_control_get_exclusive(dev, NULL); - if (IS_ERR(priv->rstc)) - return dev_err_probe(dev, PTR_ERR(priv->rstc), - "failed to get cpg reset"); - - ret = reset_control_deassert(priv->rstc); - if (ret) - return dev_err_probe(dev, ret, "failed to deassert"); - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - - priv->calib0 = rzg2l_thermal_read(priv, OTPTSUTRIM_REG(0)); - if (priv->calib0 & OTPTSUTRIM_EN_MASK) - priv->calib0 &= OTPTSUTRIM_MASK; - else - priv->calib0 = SW_CALIB0_VAL; - - priv->calib1 = rzg2l_thermal_read(priv, OTPTSUTRIM_REG(1)); - if (priv->calib1 & OTPTSUTRIM_EN_MASK) - priv->calib1 &= OTPTSUTRIM_MASK; - else - priv->calib1 = SW_CALIB1_VAL; - - platform_set_drvdata(pdev, priv); - ret = rzg2l_thermal_init(priv); - if (ret) { - dev_err(dev, "Failed to start TSU"); - goto err; - } - - zone = devm_thermal_of_zone_register(dev, 0, priv, - &rzg2l_tz_of_ops); - if (IS_ERR(zone)) { - dev_err(dev, "Can't register thermal zone"); - ret = PTR_ERR(zone); - goto err; - } - - priv->zone = zone; - ret = thermal_add_hwmon_sysfs(priv->zone); - if (ret) - goto err; - - dev_dbg(dev, "TSU probed with %s calibration values", - rzg2l_thermal_read(priv, OTPTSUTRIM_REG(0)) ? "hw" : "sw"); - - return 0; - -err: - rzg2l_thermal_reset_assert_pm_disable_put(pdev); - return ret; -} - -static const struct of_device_id rzg2l_thermal_dt_ids[] = { - { .compatible = "renesas,rzg2l-tsu", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, rzg2l_thermal_dt_ids); - -static struct platform_driver rzg2l_thermal_driver = { - .driver = { - .name = "rzg2l_thermal", - .of_match_table = rzg2l_thermal_dt_ids, - }, - .probe = rzg2l_thermal_probe, - .remove_new = rzg2l_thermal_remove, -}; -module_platform_driver(rzg2l_thermal_driver); - -MODULE_DESCRIPTION("Renesas RZ/G2L TSU Thermal Sensor Driver"); -MODULE_AUTHOR("Biju Das "); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-58-ga151 From f996e2b17a30c2919ed018d3902d1e633ae40ab2 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Mon, 6 May 2024 17:40:11 +0200 Subject: thermal/drivers/renesas/rcar: Add dependency on OF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The R-Car thermal driver depends on OF, describe this. Signed-off-by: Niklas Söderlund Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240506154011.344324-3-niklas.soderlund+renesas@ragnatech.se --- drivers/thermal/renesas/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/thermal/renesas/Kconfig b/drivers/thermal/renesas/Kconfig index 1be65a03d290..dcf5fc5ae08e 100644 --- a/drivers/thermal/renesas/Kconfig +++ b/drivers/thermal/renesas/Kconfig @@ -4,6 +4,7 @@ config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_RENESAS || COMPILE_TEST depends on HAS_IOMEM + depends on OF help Enable this to plug the R-Car thermal sensor driver into the Linux thermal framework. -- cgit v1.2.3-58-ga151 From 854a8e208c26b60708785d4ef8d5cf8ee014335a Mon Sep 17 00:00:00 2001 From: Théo Lebrun Date: Thu, 25 Apr 2024 17:32:38 +0200 Subject: thermal/drivers/k3_j72xx_bandgap: Implement suspend/resume support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This add suspend-to-ram support. The derived_table is kept-as is, so the resume is only about pm_runtime_* calls and restoring the same registers as the probe. Extract the hardware initialization procedure to a function called at both probe-time & resume-time. The probe-time loop is split in two to ensure doing the hardware initialization before registering thermal zones. That ensures our callbacks cannot be called while in bad state. The 100ms delay in the hardware initialization sequence was removed. It was initially added to be sure the thresholds are programmed before enabling the interrupt, but in fact it's not needed (tested on J7200 platform). Signed-off-by: Théo Lebrun Acked-by: Keerthy Signed-off-by: Thomas Richard Link: https://lore.kernel.org/r/20240425153238.498750-1-thomas.richard@bootlin.com Signed-off-by: Daniel Lezcano --- drivers/thermal/k3_j72xx_bandgap.c | 111 ++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 33 deletions(-) diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c index c74094a86982..9bc279ac131a 100644 --- a/drivers/thermal/k3_j72xx_bandgap.c +++ b/drivers/thermal/k3_j72xx_bandgap.c @@ -178,6 +178,7 @@ struct k3_j72xx_bandgap { void __iomem *base; void __iomem *cfg2_base; struct k3_thermal_data *ts_data[K3_VTM_MAX_NUM_TS]; + int cnt; }; /* common data structures */ @@ -338,24 +339,52 @@ static void print_look_up_table(struct device *dev, int *ref_table) dev_dbg(dev, "%d %d %d\n", i, derived_table[i], ref_table[i]); } +static void k3_j72xx_bandgap_init_hw(struct k3_j72xx_bandgap *bgp) +{ + struct k3_thermal_data *data; + int id, high_max, low_temp; + u32 val; + + for (id = 0; id < bgp->cnt; id++) { + data = bgp->ts_data[id]; + val = readl(bgp->cfg2_base + data->ctrl_offset); + val |= (K3_VTM_TMPSENS_CTRL_MAXT_OUTRG_EN | + K3_VTM_TMPSENS_CTRL_SOC | + K3_VTM_TMPSENS_CTRL_CLRZ | BIT(4)); + writel(val, bgp->cfg2_base + data->ctrl_offset); + } + + /* + * Program TSHUT thresholds + * Step 1: set the thresholds to ~123C and 105C WKUP_VTM_MISC_CTRL2 + * Step 2: WKUP_VTM_TMPSENS_CTRL_j set the MAXT_OUTRG_EN bit + * This is already taken care as per of init + * Step 3: WKUP_VTM_MISC_CTRL set the ANYMAXT_OUTRG_ALERT_EN bit + */ + high_max = k3_j72xx_bandgap_temp_to_adc_code(MAX_TEMP); + low_temp = k3_j72xx_bandgap_temp_to_adc_code(COOL_DOWN_TEMP); + + writel((low_temp << 16) | high_max, bgp->cfg2_base + K3_VTM_MISC_CTRL2_OFFSET); + writel(K3_VTM_ANYMAXT_OUTRG_ALERT_EN, bgp->cfg2_base + K3_VTM_MISC_CTRL_OFFSET); +} + struct k3_j72xx_bandgap_data { const bool has_errata_i2128; }; static int k3_j72xx_bandgap_probe(struct platform_device *pdev) { - int ret = 0, cnt, val, id; - int high_max, low_temp; - struct resource *res; + const struct k3_j72xx_bandgap_data *driver_data; + struct thermal_zone_device *ti_thermal; struct device *dev = &pdev->dev; + bool workaround_needed = false; struct k3_j72xx_bandgap *bgp; struct k3_thermal_data *data; - bool workaround_needed = false; - const struct k3_j72xx_bandgap_data *driver_data; - struct thermal_zone_device *ti_thermal; - int *ref_table; struct err_values err_vals; void __iomem *fuse_base; + int ret = 0, val, id; + struct resource *res; + int *ref_table; const s64 golden_factors[] = { -490019999999999936, @@ -422,10 +451,10 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) /* Get the sensor count in the VTM */ val = readl(bgp->base + K3_VTM_DEVINFO_PWR0_OFFSET); - cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK; - cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK); + bgp->cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK; + bgp->cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK); - data = devm_kcalloc(bgp->dev, cnt, sizeof(*data), GFP_KERNEL); + data = devm_kcalloc(bgp->dev, bgp->cnt, sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; goto err_alloc; @@ -449,8 +478,8 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) else init_table(3, ref_table, pvt_wa_factors); - /* Register the thermal sensors */ - for (id = 0; id < cnt; id++) { + /* Precompute the derived table & fill each thermal sensor struct */ + for (id = 0; id < bgp->cnt; id++) { data[id].bgp = bgp; data[id].ctrl_offset = K3_VTM_TMPSENS0_CTRL_OFFSET + id * 0x20; data[id].stat_offset = data[id].ctrl_offset + @@ -470,13 +499,13 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) else if (id == 0 && !workaround_needed) memcpy(derived_table, ref_table, TABLE_SIZE * 4); - val = readl(data[id].bgp->cfg2_base + data[id].ctrl_offset); - val |= (K3_VTM_TMPSENS_CTRL_MAXT_OUTRG_EN | - K3_VTM_TMPSENS_CTRL_SOC | - K3_VTM_TMPSENS_CTRL_CLRZ | BIT(4)); - writel(val, data[id].bgp->cfg2_base + data[id].ctrl_offset); - bgp->ts_data[id] = &data[id]; + } + + k3_j72xx_bandgap_init_hw(bgp); + + /* Register the thermal sensors */ + for (id = 0; id < bgp->cnt; id++) { ti_thermal = devm_thermal_of_zone_register(bgp->dev, id, &data[id], &k3_of_thermal_ops); if (IS_ERR(ti_thermal)) { @@ -486,21 +515,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) } } - /* - * Program TSHUT thresholds - * Step 1: set the thresholds to ~123C and 105C WKUP_VTM_MISC_CTRL2 - * Step 2: WKUP_VTM_TMPSENS_CTRL_j set the MAXT_OUTRG_EN bit - * This is already taken care as per of init - * Step 3: WKUP_VTM_MISC_CTRL set the ANYMAXT_OUTRG_ALERT_EN bit - */ - high_max = k3_j72xx_bandgap_temp_to_adc_code(MAX_TEMP); - low_temp = k3_j72xx_bandgap_temp_to_adc_code(COOL_DOWN_TEMP); - - writel((low_temp << 16) | high_max, data[0].bgp->cfg2_base + - K3_VTM_MISC_CTRL2_OFFSET); - mdelay(100); - writel(K3_VTM_ANYMAXT_OUTRG_ALERT_EN, data[0].bgp->cfg2_base + - K3_VTM_MISC_CTRL_OFFSET); + platform_set_drvdata(pdev, bgp); print_look_up_table(dev, ref_table); /* @@ -527,6 +542,35 @@ static void k3_j72xx_bandgap_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } +static int k3_j72xx_bandgap_suspend(struct device *dev) +{ + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + return 0; +} + +static int k3_j72xx_bandgap_resume(struct device *dev) +{ + struct k3_j72xx_bandgap *bgp = dev_get_drvdata(dev); + int ret; + + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); + return ret; + } + + k3_j72xx_bandgap_init_hw(bgp); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(k3_j72xx_bandgap_pm_ops, + k3_j72xx_bandgap_suspend, + k3_j72xx_bandgap_resume); + static const struct k3_j72xx_bandgap_data k3_j72xx_bandgap_j721e_data = { .has_errata_i2128 = true, }; @@ -554,6 +598,7 @@ static struct platform_driver k3_j72xx_bandgap_sensor_driver = { .driver = { .name = "k3-j72xx-soc-thermal", .of_match_table = of_k3_j72xx_bandgap_match, + .pm = pm_sleep_ptr(&k3_j72xx_bandgap_pm_ops), }, }; -- cgit v1.2.3-58-ga151 From 6b04928e83f298d99359f3ba67187a328c223357 Mon Sep 17 00:00:00 2001 From: Julien Panis Date: Mon, 3 Jun 2024 12:50:48 +0200 Subject: dt-bindings: thermal: mediatek: Fix thermal zone definition for MT8186 Fix a thermal zone name for consistency with the other SoCs: MFG contains GPU, the latter is more specific and must be used here. The naming must be fixed "atomically" so compilation does not break. As a result, the change is made in the dt-bindings and in the LVTS driver within a single commit, despite the checkpatch warning. The definition can be safely modified here because it is used only in the LVTS driver, which is modified accordingly, and has not yet been included in a released kernel. Fixes: a2ca202350f9 ("dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for MT8186") Reviewed-by: AngeloGioacchino Del Regno Acked-by: Conor Dooley Signed-off-by: Julien Panis Link: https://lore.kernel.org/r/20240603-mtk-thermal-mt818x-dtsi-v7-1-8c8e3c7a3643@baylibre.com Signed-off-by: Daniel Lezcano --- drivers/thermal/mediatek/lvts_thermal.c | 2 +- include/dt-bindings/thermal/mediatek,lvts-thermal.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 819ed0110f3e..d3a8a1a3e6a3 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -1440,7 +1440,7 @@ static const struct lvts_ctrl_data mt8186_lvts_data_ctrl[] = { .cal_offsets = { 29, 30, 31 } }, { .dt_id = MT8186_ADSP, .cal_offsets = { 34, 35, 28 } }, - { .dt_id = MT8186_MFG, + { .dt_id = MT8186_GPU, .cal_offsets = { 39, 32, 33 } } }, VALID_SENSOR_MAP(1, 1, 1, 0), diff --git a/include/dt-bindings/thermal/mediatek,lvts-thermal.h b/include/dt-bindings/thermal/mediatek,lvts-thermal.h index bf95309d2525..85d25b4d726d 100644 --- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h +++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h @@ -24,7 +24,7 @@ #define MT8186_BIG_CPU1 5 #define MT8186_NNA 6 #define MT8186_ADSP 7 -#define MT8186_MFG 8 +#define MT8186_GPU 8 #define MT8188_MCU_LITTLE_CPU0 0 #define MT8188_MCU_LITTLE_CPU1 1 -- cgit v1.2.3-58-ga151 From be3e224ec502d49cf9017304286c14418b230fe6 Mon Sep 17 00:00:00 2001 From: Julien Panis Date: Mon, 3 Jun 2024 12:50:49 +0200 Subject: dt-bindings: thermal: mediatek: Fix thermal zone definitions for MT8188 Fix thermal zone names for consistency with the other SoCs: - GPU0 must be used as the first GPU item. - SOCx deal with audio DSP, video, and infra subsystems. The naming must be fixed "atomically" so compilation does not break. As a result, the change is made in the dt-bindings and in the LVTS driver within a single commit, despite the checkpatch warning. The definitions can be safely modified here because they are used only in the LVTS driver, which is modified accordingly, and have not yet been included in a released kernel. Fixes: 78c88534e5e1 ("dt-bindings: thermal: mediatek: Add LVTS thermal controller definition for MT8188") Reviewed-by: AngeloGioacchino Del Regno Acked-by: Conor Dooley Signed-off-by: Julien Panis Link: https://lore.kernel.org/r/20240603-mtk-thermal-mt818x-dtsi-v7-2-8c8e3c7a3643@baylibre.com Signed-off-by: Daniel Lezcano --- drivers/thermal/mediatek/lvts_thermal.c | 10 +++++----- include/dt-bindings/thermal/mediatek,lvts-thermal.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index d3a8a1a3e6a3..73148bd8da1f 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -1488,11 +1488,11 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { }, { .lvts_sensor = { - { .dt_id = MT8188_AP_GPU1, + { .dt_id = MT8188_AP_GPU0, .cal_offsets = { 43, 44, 45 } }, - { .dt_id = MT8188_AP_GPU2, + { .dt_id = MT8188_AP_GPU1, .cal_offsets = { 46, 47, 48 } }, - { .dt_id = MT8188_AP_SOC1, + { .dt_id = MT8188_AP_ADSP, .cal_offsets = { 49, 50, 51 } }, }, VALID_SENSOR_MAP(1, 1, 1, 0), @@ -1500,9 +1500,9 @@ static const struct lvts_ctrl_data mt8188_lvts_ap_data_ctrl[] = { }, { .lvts_sensor = { - { .dt_id = MT8188_AP_SOC2, + { .dt_id = MT8188_AP_VDO, .cal_offsets = { 52, 53, 54 } }, - { .dt_id = MT8188_AP_SOC3, + { .dt_id = MT8188_AP_INFRA, .cal_offsets = { 55, 56, 57 } }, }, VALID_SENSOR_MAP(1, 1, 0, 0), diff --git a/include/dt-bindings/thermal/mediatek,lvts-thermal.h b/include/dt-bindings/thermal/mediatek,lvts-thermal.h index 85d25b4d726d..ddc7302a510a 100644 --- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h +++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h @@ -34,11 +34,11 @@ #define MT8188_MCU_BIG_CPU1 5 #define MT8188_AP_APU 0 -#define MT8188_AP_GPU1 1 -#define MT8188_AP_GPU2 2 -#define MT8188_AP_SOC1 3 -#define MT8188_AP_SOC2 4 -#define MT8188_AP_SOC3 5 +#define MT8188_AP_GPU0 1 +#define MT8188_AP_GPU1 2 +#define MT8188_AP_ADSP 3 +#define MT8188_AP_VDO 4 +#define MT8188_AP_INFRA 5 #define MT8188_AP_CAM1 6 #define MT8188_AP_CAM2 7 -- cgit v1.2.3-58-ga151 From bb6972fad98fbe6555653e762e5b31ff352a9e73 Mon Sep 17 00:00:00 2001 From: Abdulrasaq Lawani Date: Tue, 18 Jun 2024 22:31:35 -0400 Subject: dt-bindings: thermal: convert hisilicon-thermal.txt to dt-schema Convert the hisilicon SoCs tsensor txt bindings to dt-schema Signed-off-by: Abdulrasaq Lawani Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240618-hisilicon-thermal-dt-bindings-conversion-v4-1-7eba97fbe6d0@gmail.com Signed-off-by: Daniel Lezcano --- .../bindings/thermal/hisilicon,tsensor.yaml | 57 ++++++++++++++++++++++ .../bindings/thermal/hisilicon-thermal.txt | 32 ------------ 2 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 Documentation/devicetree/bindings/thermal/hisilicon,tsensor.yaml delete mode 100644 Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt diff --git a/Documentation/devicetree/bindings/thermal/hisilicon,tsensor.yaml b/Documentation/devicetree/bindings/thermal/hisilicon,tsensor.yaml new file mode 100644 index 000000000000..11aca2b749d7 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/hisilicon,tsensor.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/hisilicon,tsensor.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Temperature Sensor on HiSilicon SoCs + +maintainers: + - Abdulrasaq Lawani + +allOf: + - $ref: thermal-sensor.yaml + +properties: + compatible: + enum: + - hisilicon,tsensor + - hisilicon,hi3660-tsensor + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: thermal_clk + + interrupts: + maxItems: 1 + + '#thermal-sensor-cells': + const: 1 + +required: + - compatible + - reg + - interrupts + - '#thermal-sensor-cells' + +unevaluatedProperties: false + +examples: + - | + #include + #include + + temperature-sensor@f7030700 { + compatible = "hisilicon,tsensor"; + reg = <0xf7030700 0x1000>; + interrupts = ; + clocks = <&sys_ctrl HI6220_TSENSOR_CLK>; + clock-names = "thermal_clk"; + #thermal-sensor-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt b/Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt deleted file mode 100644 index 4b19d80e6558..000000000000 --- a/Documentation/devicetree/bindings/thermal/hisilicon-thermal.txt +++ /dev/null @@ -1,32 +0,0 @@ -* Temperature Sensor on hisilicon SoCs - -** Required properties : - -- compatible: "hisilicon,tsensor". -- reg: physical base address of thermal sensor and length of memory mapped - region. -- interrupt: The interrupt number to the cpu. Defines the interrupt used - by /SOCTHERM/tsensor. -- clock-names: Input clock name, should be 'thermal_clk'. -- clocks: phandles for clock specified in "clock-names" property. -- #thermal-sensor-cells: Should be 1. See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for a description. - -Example : - -for Hi6220: - tsensor: tsensor@0,f7030700 { - compatible = "hisilicon,tsensor"; - reg = <0x0 0xf7030700 0x0 0x1000>; - interrupts = <0 7 0x4>; - clocks = <&sys_ctrl HI6220_TSENSOR_CLK>; - clock-names = "thermal_clk"; - #thermal-sensor-cells = <1>; - } - -for Hi3660: - tsensor: tsensor@fff30000 { - compatible = "hisilicon,hi3660-tsensor"; - reg = <0x0 0xfff30000 0x0 0x1000>; - interrupts = ; - #thermal-sensor-cells = <1>; - }; -- cgit v1.2.3-58-ga151 From b18ce693a26526603e104d95ce91040fd73e98a7 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 28 Jun 2024 11:31:01 +0300 Subject: dt-bindings: thermal: qcom-tsens: Document the X1E80100 Temperature Sensor Document the Temperature Sensor (TSENS) on the X1E80100 Platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Abel Vesa Reviewed-by: Amit Kucheria Link: https://lore.kernel.org/r/20240628-x1e80100-bindings-thermal-qcom-tsens-v2-1-4843d4c2ba24@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index 99d9c526c0b6..ac54ed604b74 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -67,6 +67,7 @@ properties: - qcom,sm8450-tsens - qcom,sm8550-tsens - qcom,sm8650-tsens + - qcom,x1e80100-tsens - const: qcom,tsens-v2 - description: v2 of TSENS with combined interrupt -- cgit v1.2.3-58-ga151 From 97e32381d0fc6c2602a767b0c46e15eb2b75971d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 2 Jul 2024 16:52:48 +0200 Subject: dt-bindings: thermal: correct thermal zone node name limit Linux kernel uses thermal zone node name during registering thermal zones and has a hard-coded limit of 20 characters, including terminating NUL byte. The bindings expect node names to finish with '-thermal' which is eight bytes long, thus we have only 11 characters for the reset of the node name (thus 10 for the pattern after leading fixed character). Reported-by: Rob Herring Closes: https://lore.kernel.org/all/CAL_JsqKogbT_4DPd1n94xqeHaU_J8ve5K09WOyVsRX3jxxUW3w@mail.gmail.com/ Fixes: 1202a442a31f ("dt-bindings: thermal: Add yaml bindings for thermal zones") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240702145248.47184-1-krzysztof.kozlowski@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/thermal-zones.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml index 68398e7e8655..606b80965a44 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml @@ -49,7 +49,10 @@ properties: to take when the temperature crosses those thresholds. patternProperties: - "^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$": + # Node name is limited in size due to Linux kernel requirements - 19 + # characters in total (see THERMAL_NAME_LENGTH, including terminating NUL + # byte): + "^[a-zA-Z][a-zA-Z0-9\\-]{1,10}-thermal$": type: object description: Each thermal zone node contains information about how frequently it -- cgit v1.2.3-58-ga151 From a5d4afb92eca216b27f662d77e91f2d464345c6e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 20 Jun 2024 17:23:03 +0800 Subject: thermal/drivers/mediatek/lvts_thermal: Provide default calibration data On some pre-production hardware, the SoCs do not contain calibration data for the thermal sensors. The downstream drivers provide default values that sort of work, instead of having the thermal sensors not work at all. Port the default values to the upstream driver. These values are from the ChromeOS kernels, which sadly do not cover the MT7988. Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20240620092306.2352606-1-wenst@chromium.org Signed-off-by: Daniel Lezcano --- drivers/thermal/mediatek/lvts_thermal.c | 34 +++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c index 73148bd8da1f..1997e91bb3be 100644 --- a/drivers/thermal/mediatek/lvts_thermal.c +++ b/drivers/thermal/mediatek/lvts_thermal.c @@ -128,6 +128,7 @@ struct lvts_data { int temp_factor; int temp_offset; int gt_calib_bit_offset; + unsigned int def_calibration; }; struct lvts_sensor { @@ -689,6 +690,10 @@ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl size_t calib_len) { int i; + u32 gt; + + /* A zero value for gt means that device has invalid efuse data */ + gt = (((u32 *)efuse_calibration)[0] >> lvts_ctrl->lvts_data->gt_calib_bit_offset) & 0xff; lvts_for_each_valid_sensor(i, lvts_ctrl_data) { const struct lvts_sensor_data *sensor = @@ -699,10 +704,17 @@ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl sensor->cal_offsets[2] >= calib_len) return -EINVAL; - lvts_ctrl->calibration[i] = - (efuse_calibration[sensor->cal_offsets[0]] << 0) + - (efuse_calibration[sensor->cal_offsets[1]] << 8) + - (efuse_calibration[sensor->cal_offsets[2]] << 16); + if (gt) { + lvts_ctrl->calibration[i] = + (efuse_calibration[sensor->cal_offsets[0]] << 0) + + (efuse_calibration[sensor->cal_offsets[1]] << 8) + + (efuse_calibration[sensor->cal_offsets[2]] << 16); + } else if (lvts_ctrl->lvts_data->def_calibration) { + lvts_ctrl->calibration[i] = lvts_ctrl->lvts_data->def_calibration; + } else { + dev_err(dev, "efuse contains invalid calibration data and no default given.\n"); + return -ENODATA; + } } return 0; @@ -770,14 +782,13 @@ static int lvts_golden_temp_init(struct device *dev, u8 *calib, gt = (((u32 *)calib)[0] >> lvts_data->gt_calib_bit_offset) & 0xff; /* A zero value for gt means that device has invalid efuse data */ - if (!gt) - return -ENODATA; - - if (gt < LVTS_GOLDEN_TEMP_MAX) + if (gt && gt < LVTS_GOLDEN_TEMP_MAX) golden_temp = gt; golden_temp_offset = golden_temp * 500 + lvts_data->temp_offset; + dev_info(dev, "%sgolden temp=%d\n", gt ? "" : "fake ", golden_temp); + return 0; } @@ -1701,6 +1712,7 @@ static const struct lvts_data mt8186_lvts_data = { .temp_factor = LVTS_COEFF_A_MT7988, .temp_offset = LVTS_COEFF_B_MT7988, .gt_calib_bit_offset = 24, + .def_calibration = 19000, }; static const struct lvts_data mt8188_lvts_mcu_data = { @@ -1709,6 +1721,7 @@ static const struct lvts_data mt8188_lvts_mcu_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 20, + .def_calibration = 35000, }; static const struct lvts_data mt8188_lvts_ap_data = { @@ -1717,6 +1730,7 @@ static const struct lvts_data mt8188_lvts_ap_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 20, + .def_calibration = 35000, }; static const struct lvts_data mt8192_lvts_mcu_data = { @@ -1725,6 +1739,7 @@ static const struct lvts_data mt8192_lvts_mcu_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 24, + .def_calibration = 35000, }; static const struct lvts_data mt8192_lvts_ap_data = { @@ -1733,6 +1748,7 @@ static const struct lvts_data mt8192_lvts_ap_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 24, + .def_calibration = 35000, }; static const struct lvts_data mt8195_lvts_mcu_data = { @@ -1741,6 +1757,7 @@ static const struct lvts_data mt8195_lvts_mcu_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 24, + .def_calibration = 35000, }; static const struct lvts_data mt8195_lvts_ap_data = { @@ -1749,6 +1766,7 @@ static const struct lvts_data mt8195_lvts_ap_data = { .temp_factor = LVTS_COEFF_A_MT8195, .temp_offset = LVTS_COEFF_B_MT8195, .gt_calib_bit_offset = 24, + .def_calibration = 35000, }; static const struct of_device_id lvts_of_match[] = { -- cgit v1.2.3-58-ga151 From f5a890927ec47c11427ed1f11192a9b4a7be3d34 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:20 +0200 Subject: dt-bindings: thermal: samsung,exynos: specify cells All Samsung Exynos SoCs Thermal Management Units have only one sensor, so make '#thermal-sensor-cells' fixed at 0. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-1-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml index 1344df708e2d..29a08b0729ee 100644 --- a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml @@ -61,7 +61,8 @@ properties: TRIMINFO at 0x10068000 contains data for TMU channel 2 minItems: 1 - '#thermal-sensor-cells': true + '#thermal-sensor-cells': + const: 0 vtmu-supply: description: The regulator node supplying voltage to TMU. -- cgit v1.2.3-58-ga151 From da1f72fbe7a8b562a0cb0a9b771347c78ef4a612 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:21 +0200 Subject: dt-bindings: thermal: amlogic: reference thermal-sensor schema Device is a thermal sensor and all in-tree DTS provide '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it, bring the common definition of '#thermal-sensor-cells' property and require it. Reviewed-by: Neil Armstrong Reviewed-by: Guillaume LA ROQUE Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-2-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml index 01fccdfc4178..e52fc40e215d 100644 --- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml @@ -11,6 +11,8 @@ maintainers: description: Binding for Amlogic Thermal +$ref: thermal-sensor.yaml# + properties: compatible: oneOf: @@ -44,7 +46,7 @@ required: - clocks - amlogic,ao-secure -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From e8eca74902eba1df568eda0b1b88781439a58bd8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:22 +0200 Subject: dt-bindings: thermal: allwinner,sun8i-a83t-ths: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Vasily Khoruzhick Acked-by: Chen-Yu Tsai Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-3-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml index 6b3aea6d73b0..dad8de900495 100644 --- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml +++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml @@ -10,6 +10,8 @@ maintainers: - Vasily Khoruzhick - Yangtao Li +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -55,7 +57,6 @@ properties: maxItems: 1 description: phandle to device controlling temperate offset SYS_CFG register - # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details "#thermal-sensor-cells": enum: - 0 @@ -135,9 +136,8 @@ required: - compatible - reg - interrupts - - '#thermal-sensor-cells' -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 0ae2a1a6146f1ae6936919deb3150a24d1bdc118 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:23 +0200 Subject: dt-bindings: thermal: brcm,avs-ro: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Florian Fainelli Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-4-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml b/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml index 89a2c32c0ab2..0271a0bc1843 100644 --- a/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml @@ -19,19 +19,19 @@ description: |+ Refer to the bindings described in Documentation/devicetree/bindings/mfd/syscon.yaml +$ref: thermal-sensor.yaml# + properties: compatible: const: brcm,bcm2711-thermal - # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details "#thermal-sensor-cells": const: 0 required: - compatible - - '#thermal-sensor-cells' -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 2410427cc87bf843e6871730f18b10dcbb91e992 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:24 +0200 Subject: dt-bindings: thermal: generic-adc: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-5-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml index f1fc3b0d8608..12e6418dc24d 100644 --- a/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml @@ -15,6 +15,8 @@ description: sensor resistor. The voltage read across the sensor is mapped to temperature using voltage-temperature lookup table. +$ref: thermal-sensor.yaml# + properties: compatible: const: generic-adc-thermal @@ -44,11 +46,10 @@ properties: required: - compatible - - '#thermal-sensor-cells' - io-channels - io-channel-names -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 57fa7d668770780932acf83c2dcf4e15741efd1a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:25 +0200 Subject: dt-bindings: thermal: imx8mm: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-6-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml index d2c1e4573c32..e7ddaa6c966e 100644 --- a/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/imx8mm-thermal.yaml @@ -16,6 +16,8 @@ description: | for i.MX8MM which has ONLY 1 sensor, v2 is for i.MX8MP which has 2 sensors. +$ref: thermal-sensor.yaml# + properties: compatible: oneOf: @@ -51,9 +53,8 @@ required: - compatible - reg - clocks - - '#thermal-sensor-cells' -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From b6f4d62c53e6e2eb4560a5a20315bee2adfe7b6d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:26 +0200 Subject: dt-bindings: thermal: nvidia,tegra186-bpmp: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-7-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../bindings/thermal/nvidia,tegra186-bpmp-thermal.yaml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.yaml b/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.yaml index c91fd07e4061..978b9e6ab8a3 100644 --- a/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra186-bpmp-thermal.yaml @@ -20,11 +20,7 @@ description: | node. See ../firmware/nvidia,tegra186-bpmp.yaml for details of the BPMP binding. - This node represents a thermal sensor. See - - Documentation/devicetree/bindings/thermal/thermal-sensor.yaml - - for details of the core thermal binding. +$ref: thermal-sensor.yaml# properties: compatible: @@ -33,10 +29,6 @@ properties: - nvidia,tegra194-bpmp-thermal '#thermal-sensor-cells': - $ref: /schemas/types.yaml#/definitions/uint32 - description: Number of cells needed in the phandle specifier to - identify a given sensor. Must be 1 and the single cell specifies - the sensor index. const: 1 -additionalProperties: false +unevaluatedProperties: false -- cgit v1.2.3-58-ga151 From b760aeec3d2b50d8680f4b52d851de7dd4fa8127 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:27 +0200 Subject: dt-bindings: thermal: nvidia,tegra30-tsensor: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-8-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml b/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml index a35da257b070..972d608ddf95 100644 --- a/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml +++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml @@ -27,6 +27,8 @@ description: | TSENSOR has two channels which monitor two different spots of the SoC. +$ref: thermal-sensor.yaml# + properties: compatible: const: nvidia,tegra30-tsensor @@ -56,9 +58,8 @@ required: - clocks - resets - interrupts - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From df300226f6f630daf96be0a82f3f61f2cf2898dd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:28 +0200 Subject: dt-bindings: thermal: qcom-spmi-adc-tm-hc: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Dmitry Baryshkov Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-9-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml index 7541e27704ca..bfad8130a042 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm-hc.yaml @@ -8,6 +8,8 @@ title: Qualcomm's SPMI PMIC ADC HC Thermal Monitoring maintainers: - Dmitry Baryshkov +$ref: thermal-sensor.yaml# + properties: compatible: const: qcom,spmi-adc-tm-hc @@ -20,9 +22,6 @@ properties: "#thermal-sensor-cells": const: 1 - description: - Number of cells required to uniquely identify the thermal sensors. Since - we have multiple sensors this is set to 1 "#address-cells": const: 1 @@ -106,9 +105,8 @@ required: - interrupts - "#address-cells" - "#size-cells" - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From c1bca276d8100b141a1244e8e357b0bbfbc2bed3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:29 +0200 Subject: dt-bindings: thermal: qcom-spmi-adc-tm5: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Dmitry Baryshkov Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-10-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml index d9d2657287cb..4470a5942fb2 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml @@ -8,6 +8,8 @@ title: Qualcomm's SPMI PMIC ADC Thermal Monitoring maintainers: - Dmitry Baryshkov +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -23,9 +25,6 @@ properties: "#thermal-sensor-cells": const: 1 - description: - Number of cells required to uniquely identify the thermal sensors. Since - we have multiple sensors this is set to 1 "#address-cells": const: 1 @@ -159,9 +158,8 @@ required: - interrupts - "#address-cells" - "#size-cells" - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 80c3fda5de2cf5ff0680626da70da0f9a8eac351 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:30 +0200 Subject: dt-bindings: thermal: qcom-tsens: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Dmitry Baryshkov Reviewed-by: Amit Kucheria Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-11-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index ac54ed604b74..f32f29d7a970 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -218,18 +218,16 @@ properties: "#thermal-sensor-cells": const: 1 - description: - Number of cells required to uniquely identify the thermal sensors. Since - we have multiple sensors this is set to 1 required: - compatible - interrupts - interrupt-names - - "#thermal-sensor-cells" - "#qcom,sensors" allOf: + - $ref: thermal-sensor.yaml# + - if: properties: compatible: @@ -293,7 +291,7 @@ allOf: required: - reg -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 7410853a1d0065572b5097f114e210870bd2f0cb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:32 +0200 Subject: dt-bindings: thermal: rcar-gen3: reference thermal-sensor schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Niklas Söderlund Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-13-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml index 6a81cb6e11bc..d92e882c9e8d 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml @@ -15,6 +15,8 @@ description: maintainers: - Niklas Söderlund +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -57,7 +59,6 @@ required: - clocks - power-domains - resets - - "#thermal-sensor-cells" if: properties: @@ -96,7 +97,7 @@ else: required: - interrupts -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 9abcf4ac35908ee6db36354e4545cc88600b56b3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:33 +0200 Subject: dt-bindings: thermal: rockchip: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Heiko Stuebner Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-14-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml index 55f8ec0bec01..b717ea8261ca 100644 --- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.yaml @@ -9,6 +9,8 @@ title: Temperature Sensor ADC (TSADC) on Rockchip SoCs maintainers: - Heiko Stuebner +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -76,9 +78,8 @@ required: - clocks - clock-names - resets - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From bf1163bb009885e89eda82bb48b0e638c2860a28 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:34 +0200 Subject: dt-bindings: thermal: rzg2l: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Biju Das Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-15-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml index 03f4b926e53c..2f96c0fe0f75 100644 --- a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml @@ -13,6 +13,8 @@ description: maintainers: - Biju Das +$ref: thermal-sensor.yaml# + properties: compatible: items: @@ -43,9 +45,8 @@ required: - clocks - power-domains - resets - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 28b317510582fad1d1a64775250e57a886826897 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:35 +0200 Subject: dt-bindings: thermal: socionext,uniphier: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-16-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/thermal/socionext,uniphier-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml b/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml index 6f975821fa5e..8210b7079721 100644 --- a/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/socionext,uniphier-thermal.yaml @@ -14,6 +14,8 @@ description: | maintainers: - Kunihiko Hayashi +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -38,9 +40,8 @@ properties: required: - compatible - interrupts - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From f9b2d6b840d50d23086b9638dee7e622f3db6638 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:36 +0200 Subject: dt-bindings: thermal: sprd: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Reviewed-by: Baolin Wang Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-17-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/sprd-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml b/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml index 76aaa004c8ac..f65076fc68f9 100644 --- a/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml @@ -11,6 +11,8 @@ maintainers: - Baolin Wang - Chunyan Zhang +$ref: thermal-sensor.yaml# + properties: compatible: const: sprd,ums512-thermal @@ -77,11 +79,10 @@ required: - clock-names - nvmem-cells - nvmem-cell-names - - "#thermal-sensor-cells" - "#address-cells" - "#size-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 17cdc4717dabe9a84fe81bcd310ea8035fca475a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:37 +0200 Subject: dt-bindings: thermal: st,stm32: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-18-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/st,stm32-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/st,stm32-thermal.yaml b/Documentation/devicetree/bindings/thermal/st,stm32-thermal.yaml index ab043084f667..1c01a80a0cdd 100644 --- a/Documentation/devicetree/bindings/thermal/st,stm32-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/st,stm32-thermal.yaml @@ -9,6 +9,8 @@ title: STMicroelectronics STM32 digital thermal sensor (DTS) maintainers: - Pascal Paillet +$ref: thermal-sensor.yaml# + properties: compatible: const: st,stm32-thermal @@ -30,14 +32,13 @@ properties: const: 0 required: - - "#thermal-sensor-cells" - compatible - reg - interrupts - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 323a6134e7d0f146e7185167025c2b1c7993f5b2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:38 +0200 Subject: dt-bindings: thermal: ti,am654: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-19-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml index 7ed0abe9290f..16801aa78bc2 100644 --- a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml @@ -9,6 +9,8 @@ title: Texas Instruments AM654 VTM (DTS) maintainers: - Keerthy +$ref: thermal-sensor.yaml# + properties: compatible: const: ti,am654-vtm @@ -26,9 +28,8 @@ required: - compatible - reg - power-domains - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From a985dceccd82850b93d392ae9c4d5748f40c3e2a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:39 +0200 Subject: dt-bindings: thermal: ti,j72xx: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-20-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml index 171b3622ed84..82b77b9795a3 100644 --- a/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/ti,j72xx-thermal.yaml @@ -22,6 +22,8 @@ description: | Temp(C) = (-9.2627e-12) * x^4 + (6.0373e-08) * x^3 + \ (-1.7058e-04) * x^2 + (3.2512e-01) * x + (-4.9003e+01) +$ref: thermal-sensor.yaml# + properties: compatible: enum: @@ -64,9 +66,8 @@ required: - compatible - reg - power-domains - - "#thermal-sensor-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From bbb4c179397c0af1ff403b2f13fff4753874bf7d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:40 +0200 Subject: dt-bindings: thermal: simplify few bindings Simplify few bindings which already reference thermal-sensor.yaml schema by dropping unneeded requiring of '#thermal-sensor-cells' and dropping assigned-clocks properties (core schema allows it if 'clocks' are there). Reviewed-by: AngeloGioacchino Del Regno Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-21-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml | 1 - Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.yaml | 1 - Documentation/devicetree/bindings/thermal/fsl,scu-thermal.yaml | 1 - Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml | 1 - Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml | 1 - .../devicetree/bindings/thermal/nvidia,tegra124-soctherm.yaml | 1 - Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml | 4 ---- Documentation/devicetree/bindings/thermal/qcom,spmi-temp-alarm.yaml | 1 - 8 files changed, 11 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml b/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml index 267a0f423504..32730211e15b 100644 --- a/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml +++ b/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml @@ -42,7 +42,6 @@ additionalProperties: false required: - compatible - reg - - "#thermal-sensor-cells" examples: - | diff --git a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.yaml b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.yaml index 2b6026d9fbcf..ddf0f20e5285 100644 --- a/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/brcm,bcm2835-thermal.yaml @@ -34,7 +34,6 @@ required: - compatible - reg - clocks - - '#thermal-sensor-cells' examples: - | diff --git a/Documentation/devicetree/bindings/thermal/fsl,scu-thermal.yaml b/Documentation/devicetree/bindings/thermal/fsl,scu-thermal.yaml index e02d04d4f71e..ceef318668bf 100644 --- a/Documentation/devicetree/bindings/thermal/fsl,scu-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/fsl,scu-thermal.yaml @@ -28,7 +28,6 @@ properties: required: - compatible - - '#thermal-sensor-cells' additionalProperties: false diff --git a/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml index ca81c8afba79..79e691b08341 100644 --- a/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml @@ -38,7 +38,6 @@ required: - compatible - reg - interrupts - - '#thermal-sensor-cells' if: properties: diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml index 331cf4e662e3..0259cd3ce9c5 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml @@ -99,7 +99,6 @@ required: - resets - nvmem-cells - nvmem-cell-names - - "#thermal-sensor-cells" additionalProperties: false diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.yaml b/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.yaml index b0237d236021..19bb1f324183 100644 --- a/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.yaml +++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra124-soctherm.yaml @@ -197,7 +197,6 @@ required: - clock-names - resets - reset-names - - "#thermal-sensor-cells" allOf: - $ref: thermal-sensor.yaml diff --git a/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml b/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml index 972d608ddf95..63a29a1f7fe6 100644 --- a/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml +++ b/Documentation/devicetree/bindings/thermal/nvidia,tegra30-tsensor.yaml @@ -48,10 +48,6 @@ properties: "#thermal-sensor-cells": const: 1 - assigned-clock-parents: true - assigned-clock-rates: true - assigned-clocks: true - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/thermal/qcom,spmi-temp-alarm.yaml b/Documentation/devicetree/bindings/thermal/qcom,spmi-temp-alarm.yaml index 5f08b6e59b8a..30b22151aa82 100644 --- a/Documentation/devicetree/bindings/thermal/qcom,spmi-temp-alarm.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom,spmi-temp-alarm.yaml @@ -42,7 +42,6 @@ required: - compatible - reg - interrupts - - '#thermal-sensor-cells' additionalProperties: false -- cgit v1.2.3-58-ga151 From f062dc5ccaf2cdca9b1d9282ddae1cdb77b9d902 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:41 +0200 Subject: dt-bindings: thermal: cleanup examples indentation Preferred indentation for DTS examples in the bindings is 4-space. It is also preferred not to have redundant/unused labels. No functional change Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-22-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- .../bindings/thermal/amlogic,thermal.yaml | 18 ++--- .../bindings/thermal/brcm,avs-ro-thermal.yaml | 18 ++--- .../devicetree/bindings/thermal/brcm,avs-tmon.yaml | 16 ++-- .../devicetree/bindings/thermal/qcom-tsens.yaml | 88 ++++++++++------------ .../bindings/thermal/rcar-gen3-thermal.yaml | 66 ++++++++-------- .../devicetree/bindings/thermal/rcar-thermal.yaml | 64 ++++++++-------- .../devicetree/bindings/thermal/rzg2l-thermal.yaml | 38 +++++----- .../devicetree/bindings/thermal/sprd-thermal.yaml | 44 +++++------ .../bindings/thermal/ti,am654-thermal.yaml | 10 +-- 9 files changed, 178 insertions(+), 184 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml index e52fc40e215d..725303e1a364 100644 --- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml @@ -50,13 +50,13 @@ unevaluatedProperties: false examples: - | - cpu_temp: temperature-sensor@ff634800 { - compatible = "amlogic,g12a-cpu-thermal", - "amlogic,g12a-thermal"; - reg = <0xff634800 0x50>; - interrupts = <0x0 0x24 0x0>; - clocks = <&clk 164>; - #thermal-sensor-cells = <0>; - amlogic,ao-secure = <&sec_AO>; - }; + temperature-sensor@ff634800 { + compatible = "amlogic,g12a-cpu-thermal", + "amlogic,g12a-thermal"; + reg = <0xff634800 0x50>; + interrupts = <0x0 0x24 0x0>; + clocks = <&clk 164>; + #thermal-sensor-cells = <0>; + amlogic,ao-secure = <&sec_AO>; + }; ... diff --git a/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml b/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml index 0271a0bc1843..29a9844e8b48 100644 --- a/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.yaml @@ -35,14 +35,14 @@ unevaluatedProperties: false examples: - | - avs-monitor@7d5d2000 { - compatible = "brcm,bcm2711-avs-monitor", - "syscon", "simple-mfd"; - reg = <0x7d5d2000 0xf00>; - - thermal: thermal { - compatible = "brcm,bcm2711-thermal"; - #thermal-sensor-cells = <0>; - }; + avs-monitor@7d5d2000 { + compatible = "brcm,bcm2711-avs-monitor", + "syscon", "simple-mfd"; + reg = <0x7d5d2000 0xf00>; + + thermal: thermal { + compatible = "brcm,bcm2711-thermal"; + #thermal-sensor-cells = <0>; }; + }; ... diff --git a/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml b/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml index 32730211e15b..081486b44382 100644 --- a/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml +++ b/Documentation/devicetree/bindings/thermal/brcm,avs-tmon.yaml @@ -45,11 +45,11 @@ required: examples: - | - thermal@f04d1500 { - compatible = "brcm,avs-tmon-bcm7445", "brcm,avs-tmon"; - reg = <0xf04d1500 0x28>; - interrupts = <0x6>; - interrupt-names = "tmon"; - interrupt-parent = <&avs_host_l2_intc>; - #thermal-sensor-cells = <0>; - }; + thermal@f04d1500 { + compatible = "brcm,avs-tmon-bcm7445", "brcm,avs-tmon"; + reg = <0xf04d1500 0x28>; + interrupts = <0x6>; + interrupt-names = "tmon"; + interrupt-parent = <&avs_host_l2_intc>; + #thermal-sensor-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index f32f29d7a970..72048c5a0412 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -296,22 +296,16 @@ unevaluatedProperties: false examples: - | #include - // Example msm9860 based SoC (ipq8064): - gcc: clock-controller { + thermal-sensor { + compatible = "qcom,ipq8064-tsens"; - /* ... */ - - tsens: thermal-sensor { - compatible = "qcom,ipq8064-tsens"; - - nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>; - nvmem-cell-names = "calib", "calib_backup"; - interrupts = ; - interrupt-names = "uplow"; + nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>; + nvmem-cell-names = "calib", "calib_backup"; + interrupts = ; + interrupt-names = "uplow"; - #qcom,sensors = <11>; - #thermal-sensor-cells = <1>; - }; + #qcom,sensors = <11>; + #thermal-sensor-cells = <1>; }; - | @@ -348,66 +342,66 @@ examples: #include // Example 1 (legacy: for pre v1 IP): tsens1: thermal-sensor@4a9000 { - compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; - reg = <0x4a9000 0x1000>, /* TM */ - <0x4a8000 0x1000>; /* SROT */ + compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; + reg = <0x4a9000 0x1000>, /* TM */ + <0x4a8000 0x1000>; /* SROT */ - nvmem-cells = <&tsens_caldata>, <&tsens_calsel>; - nvmem-cell-names = "calib", "calib_sel"; + nvmem-cells = <&tsens_caldata>, <&tsens_calsel>; + nvmem-cell-names = "calib", "calib_sel"; - interrupts = ; - interrupt-names = "uplow"; + interrupts = ; + interrupt-names = "uplow"; - #qcom,sensors = <5>; - #thermal-sensor-cells = <1>; + #qcom,sensors = <5>; + #thermal-sensor-cells = <1>; }; - | #include // Example 2 (for any platform containing v1 of the TSENS IP): tsens2: thermal-sensor@4a9000 { - compatible = "qcom,qcs404-tsens", "qcom,tsens-v1"; - reg = <0x004a9000 0x1000>, /* TM */ - <0x004a8000 0x1000>; /* SROT */ + compatible = "qcom,qcs404-tsens", "qcom,tsens-v1"; + reg = <0x004a9000 0x1000>, /* TM */ + <0x004a8000 0x1000>; /* SROT */ - nvmem-cells = <&tsens_caldata>; - nvmem-cell-names = "calib"; + nvmem-cells = <&tsens_caldata>; + nvmem-cell-names = "calib"; - interrupts = ; - interrupt-names = "uplow"; + interrupts = ; + interrupt-names = "uplow"; - #qcom,sensors = <10>; - #thermal-sensor-cells = <1>; + #qcom,sensors = <10>; + #thermal-sensor-cells = <1>; }; - | #include // Example 3 (for any platform containing v2 of the TSENS IP): tsens3: thermal-sensor@c263000 { - compatible = "qcom,sdm845-tsens", "qcom,tsens-v2"; - reg = <0xc263000 0x1ff>, - <0xc222000 0x1ff>; + compatible = "qcom,sdm845-tsens", "qcom,tsens-v2"; + reg = <0xc263000 0x1ff>, + <0xc222000 0x1ff>; - interrupts = , - ; - interrupt-names = "uplow", "critical"; + interrupts = , + ; + interrupt-names = "uplow", "critical"; - #qcom,sensors = <13>; - #thermal-sensor-cells = <1>; + #qcom,sensors = <13>; + #thermal-sensor-cells = <1>; }; - | #include // Example 4 (for any IPQ8074 based SoC-s): tsens4: thermal-sensor@4a9000 { - compatible = "qcom,ipq8074-tsens"; - reg = <0x4a9000 0x1000>, - <0x4a8000 0x1000>; + compatible = "qcom,ipq8074-tsens"; + reg = <0x4a9000 0x1000>, + <0x4a8000 0x1000>; - interrupts = ; - interrupt-names = "combined"; + interrupts = ; + interrupt-names = "combined"; - #qcom,sensors = <16>; - #thermal-sensor-cells = <1>; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; }; ... diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml index d92e882c9e8d..b6657d64cf3d 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml @@ -106,33 +106,33 @@ examples: #include tsc: thermal@e6198000 { - compatible = "renesas,r8a7795-thermal"; - reg = <0xe6198000 0x100>, - <0xe61a0000 0x100>, - <0xe61a8000 0x100>; - interrupts = , - , - ; - clocks = <&cpg CPG_MOD 522>; - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - resets = <&cpg 522>; - #thermal-sensor-cells = <1>; + compatible = "renesas,r8a7795-thermal"; + reg = <0xe6198000 0x100>, + <0xe61a0000 0x100>, + <0xe61a8000 0x100>; + interrupts = , + , + ; + clocks = <&cpg CPG_MOD 522>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 522>; + #thermal-sensor-cells = <1>; }; thermal-zones { - sensor_thermal: sensor-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsc 0>; - - trips { - sensor1_crit: sensor1-crit { - temperature = <90000>; - hysteresis = <2000>; - type = "critical"; - }; - }; + sensor_thermal: sensor-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsc 0>; + + trips { + sensor1_crit: sensor1-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; }; + }; }; - | #include @@ -140,14 +140,14 @@ examples: #include tsc_r8a779a0: thermal@e6190000 { - compatible = "renesas,r8a779a0-thermal"; - reg = <0xe6190000 0x200>, - <0xe6198000 0x200>, - <0xe61a0000 0x200>, - <0xe61a8000 0x200>, - <0xe61b0000 0x200>; - clocks = <&cpg CPG_MOD 919>; - power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; - resets = <&cpg 919>; - #thermal-sensor-cells = <1>; + compatible = "renesas,r8a779a0-thermal"; + reg = <0xe6190000 0x200>, + <0xe6198000 0x200>, + <0xe61a0000 0x200>, + <0xe61a8000 0x200>, + <0xe61b0000 0x200>; + clocks = <&cpg CPG_MOD 919>; + power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; + resets = <&cpg 919>; + #thermal-sensor-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml index 119998d10ff4..221a58d18cad 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml @@ -98,8 +98,8 @@ examples: # Example (non interrupt support) - | thermal@ffc48000 { - compatible = "renesas,thermal-r8a7779", "renesas,rcar-thermal"; - reg = <0xffc48000 0x38>; + compatible = "renesas,thermal-r8a7779", "renesas,rcar-thermal"; + reg = <0xffc48000 0x38>; }; # Example (interrupt support) @@ -109,12 +109,12 @@ examples: #include thermal@e61f0000 { - compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal"; - reg = <0xe61f0000 0x14>, <0xe61f0100 0x38>, - <0xe61f0200 0x38>, <0xe61f0300 0x38>; - interrupts = ; - clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>; - power-domains = <&pd_c5>; + compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal"; + reg = <0xe61f0000 0x14>, <0xe61f0100 0x38>, + <0xe61f0200 0x38>, <0xe61f0300 0x38>; + interrupts = ; + clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>; + power-domains = <&pd_c5>; }; # Example (with thermal-zone) @@ -124,32 +124,32 @@ examples: #include thermal: thermal@e61f0000 { - compatible = "renesas,thermal-r8a7790", - "renesas,rcar-gen2-thermal", - "renesas,rcar-thermal"; - reg = <0xe61f0000 0x10>, <0xe61f0100 0x38>; - interrupts = ; - clocks = <&cpg CPG_MOD 522>; - power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; - resets = <&cpg 522>; - #thermal-sensor-cells = <0>; + compatible = "renesas,thermal-r8a7790", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; + reg = <0xe61f0000 0x10>, <0xe61f0100 0x38>; + interrupts = ; + clocks = <&cpg CPG_MOD 522>; + power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; + resets = <&cpg 522>; + #thermal-sensor-cells = <0>; }; thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <1000>; - polling-delay = <5000>; - - thermal-sensors = <&thermal>; - - trips { - cpu-crit { - temperature = <115000>; - hysteresis = <0>; - type = "critical"; - }; - }; - cooling-maps { - }; + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; }; + cooling-maps { + }; + }; }; diff --git a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml index 2f96c0fe0f75..136589f5adee 100644 --- a/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/rzg2l-thermal.yaml @@ -53,27 +53,27 @@ examples: #include tsu: thermal@10059400 { - compatible = "renesas,r9a07g044-tsu", - "renesas,rzg2l-tsu"; - reg = <0x10059400 0x400>; - clocks = <&cpg CPG_MOD R9A07G044_TSU_PCLK>; - resets = <&cpg R9A07G044_TSU_PRESETN>; - power-domains = <&cpg>; - #thermal-sensor-cells = <1>; + compatible = "renesas,r9a07g044-tsu", + "renesas,rzg2l-tsu"; + reg = <0x10059400 0x400>; + clocks = <&cpg CPG_MOD R9A07G044_TSU_PCLK>; + resets = <&cpg R9A07G044_TSU_PRESETN>; + power-domains = <&cpg>; + #thermal-sensor-cells = <1>; }; thermal-zones { - cpu-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&tsu 0>; - - trips { - sensor_crit: sensor-crit { - temperature = <125000>; - hysteresis = <1000>; - type = "critical"; - }; - }; + cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&tsu 0>; + + trips { + sensor_crit: sensor-crit { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; }; + }; }; diff --git a/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml b/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml index f65076fc68f9..afa551f6185f 100644 --- a/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/sprd-thermal.yaml @@ -86,27 +86,27 @@ unevaluatedProperties: false examples: - | - ap_thm0: thermal@32200000 { - compatible = "sprd,ums512-thermal"; - reg = <0x32200000 0x10000>; - clock-names = "enable"; - clocks = <&aonapb_gate 32>; - #thermal-sensor-cells = <1>; - nvmem-cells = <&thm0_sign>, <&thm0_ratio>; - nvmem-cell-names = "thm_sign_cal", "thm_ratio_cal"; - #address-cells = <1>; - #size-cells = <0>; - - prometheus-sensor@0 { - reg = <0>; - nvmem-cells = <&thm0_sen0>; - nvmem-cell-names = "sen_delta_cal"; - }; - - ank-sensor@1 { - reg = <1>; - nvmem-cells = <&thm0_sen1>; - nvmem-cell-names = "sen_delta_cal"; - }; + thermal@32200000 { + compatible = "sprd,ums512-thermal"; + reg = <0x32200000 0x10000>; + clock-names = "enable"; + clocks = <&aonapb_gate 32>; + #thermal-sensor-cells = <1>; + nvmem-cells = <&thm0_sign>, <&thm0_ratio>; + nvmem-cell-names = "thm_sign_cal", "thm_ratio_cal"; + #address-cells = <1>; + #size-cells = <0>; + + prometheus-sensor@0 { + reg = <0>; + nvmem-cells = <&thm0_sen0>; + nvmem-cell-names = "sen_delta_cal"; }; + + ank-sensor@1 { + reg = <1>; + nvmem-cells = <&thm0_sen1>; + nvmem-cell-names = "sen_delta_cal"; + }; + }; ... diff --git a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml index 16801aa78bc2..c123d9070525 100644 --- a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml @@ -47,11 +47,11 @@ examples: thermal-sensors = <&vtm0 0>; trips { - mpu0_crit: mpu0_crit { - temperature = <125000>; /* milliCelsius */ - hysteresis = <2000>; /* milliCelsius */ - type = "critical"; - }; + mpu0_crit: mpu0_crit { + temperature = <125000>; /* milliCelsius */ + hysteresis = <2000>; /* milliCelsius */ + type = "critical"; + }; }; }; ... -- cgit v1.2.3-58-ga151 From fd1f85b2e7a6cdf84fb590fe17c7664b202cb9bb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Jul 2024 11:51:31 +0200 Subject: dt-bindings: thermal: qoriq: reference thermal-sensor schema Device is a thermal sensor and it requires '#thermal-sensor-cells', so reference the thermal-sensor.yaml to simplify it and bring the common definition of '#thermal-sensor-cells' property. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240705-dt-bindings-thermal-allof-v1-12-554061b52fbc@linaro.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml b/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml index d155d6799da6..1876fe9555d6 100644 --- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml @@ -9,6 +9,8 @@ title: Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs maintainers: - Anson Huang +$ref: thermal-sensor.yaml# + properties: compatible: description: | @@ -68,9 +70,8 @@ required: - interrupts - fsl,tmu-range - fsl,tmu-calibration - - '#thermal-sensor-cells' -additionalProperties: false +unevaluatedProperties: false examples: - | -- cgit v1.2.3-58-ga151 From 6f48290b1a18dba5870920188725eee6fe603ee6 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Tue, 9 Jul 2024 09:01:53 -0600 Subject: dt-bindings: thermal: Drop 'trips' node as required It is possible to have thermal zones which don't have any trip points. These zones in effect simply represent a temperature sensor without any action associated with it. While the schema has always required a 'trips' node, users have existed for a long time without it. Update the schema to match reality. Signed-off-by: Rob Herring (Arm) Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709150154.3272825-1-robh@kernel.org Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/thermal/thermal-zones.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml index 606b80965a44..0f435be1dbd8 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml @@ -232,7 +232,6 @@ patternProperties: required: - thermal-sensors - - trips additionalProperties: false -- cgit v1.2.3-58-ga151 From e90c369cc2ffcf7145a46448de101f715a1f5584 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:31 +0200 Subject: thermal/drivers/broadcom: Fix race between removal and clock disable During the probe, driver enables clocks necessary to access registers (in get_temp()) and then registers thermal zone with managed-resources (devm) interface. Removal of device is not done in reversed order, because: 1. Clock will be disabled in driver remove() callback - thermal zone is still registered and accessible to users, 2. devm interface will unregister thermal zone. This leaves short window between (1) and (2) for accessing the get_temp() callback with disabled clock. Fix this by enabling clock also via devm-interface, so entire cleanup path will be in proper, reversed order. Fixes: 8454c8c09c77 ("thermal/drivers/bcm2835: Remove buggy call to thermal_of_zone_unregister") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-1-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/broadcom/bcm2835_thermal.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 5c1cebe07580..3b1030fc4fbf 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -185,7 +185,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) return err; } - data->clk = devm_clk_get(&pdev->dev, NULL); + data->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(data->clk)) { err = PTR_ERR(data->clk); if (err != -EPROBE_DEFER) @@ -193,10 +193,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) return err; } - err = clk_prepare_enable(data->clk); - if (err) - return err; - rate = clk_get_rate(data->clk); if ((rate < 1920000) || (rate > 5000000)) dev_warn(&pdev->dev, @@ -211,7 +207,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to register the thermal device: %d\n", err); - goto err_clk; + return err; } /* @@ -236,7 +232,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Not able to read trip_temp: %d\n", err); - goto err_tz; + return err; } /* set bandgap reference voltage and enable voltage regulator */ @@ -269,17 +265,11 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) */ err = thermal_add_hwmon_sysfs(tz); if (err) - goto err_tz; + return err; bcm2835_thermal_debugfs(pdev); return 0; -err_tz: - devm_thermal_of_zone_unregister(&pdev->dev, tz); -err_clk: - clk_disable_unprepare(data->clk); - - return err; } static void bcm2835_thermal_remove(struct platform_device *pdev) @@ -287,7 +277,6 @@ static void bcm2835_thermal_remove(struct platform_device *pdev) struct bcm2835_thermal_data *data = platform_get_drvdata(pdev); debugfs_remove_recursive(data->debugfsdir); - clk_disable_unprepare(data->clk); } static struct platform_driver bcm2835_thermal_driver = { -- cgit v1.2.3-58-ga151 From fd972a17451f9cd4f6c99415b5a9dcf856d93433 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:32 +0200 Subject: thermal/drivers/broadcom: Simplify probe() with local dev variable Simplify the probe() function by using local 'dev' instead of &pdev->dev. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-2-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/broadcom/bcm2835_thermal.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 3b1030fc4fbf..38fb0c8cd55e 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -163,6 +163,7 @@ MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); static int bcm2835_thermal_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; const struct of_device_id *match; struct thermal_zone_device *tz; struct bcm2835_thermal_data *data; @@ -170,12 +171,11 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) u32 val; unsigned long rate; - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - match = of_match_device(bcm2835_thermal_of_match_table, - &pdev->dev); + match = of_match_device(bcm2835_thermal_of_match_table, dev); if (!match) return -EINVAL; @@ -185,28 +185,25 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) return err; } - data->clk = devm_clk_get_enabled(&pdev->dev, NULL); + data->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(data->clk)) { err = PTR_ERR(data->clk); if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Could not get clk: %d\n", err); + dev_err(dev, "Could not get clk: %d\n", err); return err; } rate = clk_get_rate(data->clk); if ((rate < 1920000) || (rate > 5000000)) - dev_warn(&pdev->dev, + dev_warn(dev, "Clock %pCn running at %lu Hz is outside of the recommended range: 1.92 to 5MHz\n", data->clk, rate); /* register of thermal sensor and get info from DT */ - tz = devm_thermal_of_zone_register(&pdev->dev, 0, data, - &bcm2835_thermal_ops); + tz = devm_thermal_of_zone_register(dev, 0, data, &bcm2835_thermal_ops); if (IS_ERR(tz)) { err = PTR_ERR(tz); - dev_err(&pdev->dev, - "Failed to register the thermal device: %d\n", - err); + dev_err(dev, "Failed to register the thermal device: %d\n", err); return err; } @@ -229,9 +226,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) */ err = thermal_zone_get_trip(tz, 0, &trip); if (err < 0) { - dev_err(&pdev->dev, - "Not able to read trip_temp: %d\n", - err); + dev_err(dev, "Not able to read trip_temp: %d\n", err); return err; } -- cgit v1.2.3-58-ga151 From 9d55cb3ba36e218839ca04c55e977ab6faac1707 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:33 +0200 Subject: thermal/drivers/broadcom: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-3-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/broadcom/bcm2835_thermal.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index 38fb0c8cd55e..5ad87eb3f578 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -186,12 +186,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) } data->clk = devm_clk_get_enabled(dev, NULL); - if (IS_ERR(data->clk)) { - err = PTR_ERR(data->clk); - if (err != -EPROBE_DEFER) - dev_err(dev, "Could not get clk: %d\n", err); - return err; - } + if (IS_ERR(data->clk)) + return dev_err_probe(dev, PTR_ERR(data->clk), "Could not get clk\n"); rate = clk_get_rate(data->clk); if ((rate < 1920000) || (rate > 5000000)) @@ -201,11 +197,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) /* register of thermal sensor and get info from DT */ tz = devm_thermal_of_zone_register(dev, 0, data, &bcm2835_thermal_ops); - if (IS_ERR(tz)) { - err = PTR_ERR(tz); - dev_err(dev, "Failed to register the thermal device: %d\n", err); - return err; - } + if (IS_ERR(tz)) + return dev_err_probe(dev, PTR_ERR(tz), "Failed to register the thermal device\n"); /* * right now the FW does set up the HW-block, so we are not -- cgit v1.2.3-58-ga151 From 4a6cf76edf5c8cda4def7b1578836a88b547ff69 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:34 +0200 Subject: thermal/drivers/exynos: Simplify probe() with local dev variable Simplify the probe() function by using local 'dev' instead of &pdev->dev. While touching devm_kzalloc(), use preferred sizeof(*) syntax. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Alim Akhtar Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-4-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/samsung/exynos_tmu.c | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6482513bfe66..1152871cc982 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1004,11 +1004,11 @@ static const struct thermal_zone_device_ops exynos_sensor_ops = { static int exynos_tmu_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct exynos_tmu_data *data; int ret; - data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data), - GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1020,7 +1020,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) * TODO: Add regulator as an SOC feature, so that regulator enable * is a compulsory call. */ - ret = devm_regulator_get_enable_optional(&pdev->dev, "vtmu"); + ret = devm_regulator_get_enable_optional(dev, "vtmu"); switch (ret) { case 0: case -ENODEV: @@ -1028,8 +1028,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) case -EPROBE_DEFER: return -EPROBE_DEFER; default: - dev_err(&pdev->dev, "Failed to get enabled regulator: %d\n", - ret); + dev_err(dev, "Failed to get enabled regulator: %d\n", ret); return ret; } @@ -1037,44 +1036,44 @@ static int exynos_tmu_probe(struct platform_device *pdev) if (ret) return ret; - data->clk = devm_clk_get(&pdev->dev, "tmu_apbif"); + data->clk = devm_clk_get(dev, "tmu_apbif"); if (IS_ERR(data->clk)) { - dev_err(&pdev->dev, "Failed to get clock\n"); + dev_err(dev, "Failed to get clock\n"); return PTR_ERR(data->clk); } - data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif"); + data->clk_sec = devm_clk_get(dev, "tmu_triminfo_apbif"); if (IS_ERR(data->clk_sec)) { if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) { - dev_err(&pdev->dev, "Failed to get triminfo clock\n"); + dev_err(dev, "Failed to get triminfo clock\n"); return PTR_ERR(data->clk_sec); } } else { ret = clk_prepare(data->clk_sec); if (ret) { - dev_err(&pdev->dev, "Failed to get clock\n"); + dev_err(dev, "Failed to get clock\n"); return ret; } } ret = clk_prepare(data->clk); if (ret) { - dev_err(&pdev->dev, "Failed to get clock\n"); + dev_err(dev, "Failed to get clock\n"); goto err_clk_sec; } switch (data->soc) { case SOC_ARCH_EXYNOS5433: case SOC_ARCH_EXYNOS7: - data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk"); + data->sclk = devm_clk_get(dev, "tmu_sclk"); if (IS_ERR(data->sclk)) { - dev_err(&pdev->dev, "Failed to get sclk\n"); + dev_err(dev, "Failed to get sclk\n"); ret = PTR_ERR(data->sclk); goto err_clk; } else { ret = clk_prepare_enable(data->sclk); if (ret) { - dev_err(&pdev->dev, "Failed to enable sclk\n"); + dev_err(dev, "Failed to enable sclk\n"); goto err_clk; } } @@ -1085,33 +1084,32 @@ static int exynos_tmu_probe(struct platform_device *pdev) ret = exynos_tmu_initialize(pdev); if (ret) { - dev_err(&pdev->dev, "Failed to initialize TMU\n"); + dev_err(dev, "Failed to initialize TMU\n"); goto err_sclk; } - data->tzd = devm_thermal_of_zone_register(&pdev->dev, 0, data, + data->tzd = devm_thermal_of_zone_register(dev, 0, data, &exynos_sensor_ops); if (IS_ERR(data->tzd)) { ret = PTR_ERR(data->tzd); if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to register sensor: %d\n", - ret); + dev_err(dev, "Failed to register sensor: %d\n", ret); goto err_sclk; } ret = exynos_thermal_zone_configure(pdev); if (ret) { - dev_err(&pdev->dev, "Failed to configure the thermal zone\n"); + dev_err(dev, "Failed to configure the thermal zone\n"); goto err_sclk; } - ret = devm_request_threaded_irq(&pdev->dev, data->irq, NULL, + ret = devm_request_threaded_irq(dev, data->irq, NULL, exynos_tmu_threaded_irq, IRQF_TRIGGER_RISING | IRQF_SHARED | IRQF_ONESHOT, - dev_name(&pdev->dev), data); + dev_name(dev), data); if (ret) { - dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); + dev_err(dev, "Failed to request irq: %d\n", data->irq); goto err_sclk; } -- cgit v1.2.3-58-ga151 From ca6176693f86cbff58c5eda82a2617bd9143cafb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:35 +0200 Subject: thermal/drivers/exynos: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-5-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/samsung/exynos_tmu.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1152871cc982..96cffb2c44ba 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1037,17 +1037,14 @@ static int exynos_tmu_probe(struct platform_device *pdev) return ret; data->clk = devm_clk_get(dev, "tmu_apbif"); - if (IS_ERR(data->clk)) { - dev_err(dev, "Failed to get clock\n"); - return PTR_ERR(data->clk); - } + if (IS_ERR(data->clk)) + return dev_err_probe(dev, PTR_ERR(data->clk), "Failed to get clock\n"); data->clk_sec = devm_clk_get(dev, "tmu_triminfo_apbif"); if (IS_ERR(data->clk_sec)) { - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) { - dev_err(dev, "Failed to get triminfo clock\n"); - return PTR_ERR(data->clk_sec); - } + if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) + return dev_err_probe(dev, PTR_ERR(data->clk_sec), + "Failed to get triminfo clock\n"); } else { ret = clk_prepare(data->clk_sec); if (ret) { @@ -1067,8 +1064,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS7: data->sclk = devm_clk_get(dev, "tmu_sclk"); if (IS_ERR(data->sclk)) { - dev_err(dev, "Failed to get sclk\n"); - ret = PTR_ERR(data->sclk); + ret = dev_err_probe(dev, PTR_ERR(data->sclk), "Failed to get sclk\n"); goto err_clk; } else { ret = clk_prepare_enable(data->sclk); @@ -1091,9 +1087,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tzd = devm_thermal_of_zone_register(dev, 0, data, &exynos_sensor_ops); if (IS_ERR(data->tzd)) { - ret = PTR_ERR(data->tzd); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to register sensor: %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(data->tzd), "Failed to register sensor\n"); goto err_sclk; } -- cgit v1.2.3-58-ga151 From 3e1a0680bbeddd30f1df23bffa00b906714f6da0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:36 +0200 Subject: thermal/drivers/hisi: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-6-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/hisi_thermal.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index dd751ae63608..0eb657db62e4 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -388,15 +388,10 @@ static int hi6220_thermal_probe(struct hisi_thermal_data *data) { struct platform_device *pdev = data->pdev; struct device *dev = &pdev->dev; - int ret; data->clk = devm_clk_get(dev, "thermal_clk"); - if (IS_ERR(data->clk)) { - ret = PTR_ERR(data->clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get thermal clk: %d\n", ret); - return ret; - } + if (IS_ERR(data->clk)) + return dev_err_probe(dev, PTR_ERR(data->clk), "failed to get thermal clk\n"); data->sensor = devm_kzalloc(dev, sizeof(*data->sensor), GFP_KERNEL); if (!data->sensor) -- cgit v1.2.3-58-ga151 From e9ac90242b83dde46406723bc00d1616e3083431 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:37 +0200 Subject: thermal/drivers/imx: Simplify probe() with local dev variable Simplify the probe() function by using local 'dev' instead of &pdev->dev. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-7-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/imx_thermal.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 83eaae5ca3b8..05c24be5343f 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -601,28 +601,29 @@ static inline void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data static int imx_thermal_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct imx_thermal_data *data; struct regmap *map; int measure_freq; int ret; - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - data->dev = &pdev->dev; + data->dev = dev; - map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); + map = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,tempmon"); if (IS_ERR(map)) { ret = PTR_ERR(map); - dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret); + dev_err(dev, "failed to get tempmon regmap: %d\n", ret); return ret; } data->tempmon = map; - data->socdata = of_device_get_match_data(&pdev->dev); + data->socdata = of_device_get_match_data(dev); if (!data->socdata) { - dev_err(&pdev->dev, "no device match found\n"); + dev_err(dev, "no device match found\n"); return -ENODEV; } @@ -645,15 +646,15 @@ static int imx_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - if (of_property_present(pdev->dev.of_node, "nvmem-cells")) { + if (of_property_present(dev->of_node, "nvmem-cells")) { ret = imx_init_from_nvmem_cells(pdev); if (ret) - return dev_err_probe(&pdev->dev, ret, + return dev_err_probe(dev, ret, "failed to init from nvmem\n"); } else { ret = imx_init_from_tempmon_data(pdev); if (ret) { - dev_err(&pdev->dev, "failed to init from fsl,tempmon-data\n"); + dev_err(dev, "failed to init from fsl,tempmon-data\n"); return ret; } } @@ -673,15 +674,14 @@ static int imx_thermal_probe(struct platform_device *pdev) ret = imx_thermal_register_legacy_cooling(data); if (ret) - return dev_err_probe(&pdev->dev, ret, + return dev_err_probe(dev, ret, "failed to register cpufreq cooling device\n"); - data->thermal_clk = devm_clk_get(&pdev->dev, NULL); + data->thermal_clk = devm_clk_get(dev, NULL); if (IS_ERR(data->thermal_clk)) { ret = PTR_ERR(data->thermal_clk); if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, - "failed to get thermal clk: %d\n", ret); + dev_err(dev, "failed to get thermal clk: %d\n", ret); goto legacy_cleanup; } @@ -694,7 +694,7 @@ static int imx_thermal_probe(struct platform_device *pdev) */ ret = clk_prepare_enable(data->thermal_clk); if (ret) { - dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret); + dev_err(dev, "failed to enable thermal clk: %d\n", ret); goto legacy_cleanup; } @@ -707,12 +707,12 @@ static int imx_thermal_probe(struct platform_device *pdev) IMX_POLLING_DELAY); if (IS_ERR(data->tz)) { ret = PTR_ERR(data->tz); - dev_err(&pdev->dev, - "failed to register thermal zone device %d\n", ret); + dev_err(dev, "failed to register thermal zone device %d\n", + ret); goto clk_disable; } - dev_info(&pdev->dev, "%s CPU temperature grade - max:%dC" + dev_info(dev, "%s CPU temperature grade - max:%dC" " critical:%dC passive:%dC\n", data->temp_grade, data->temp_max / 1000, trips[IMX_TRIP_CRITICAL].temperature / 1000, trips[IMX_TRIP_PASSIVE].temperature / 1000); @@ -736,7 +736,7 @@ static int imx_thermal_probe(struct platform_device *pdev) usleep_range(20, 50); /* the core was configured and enabled just before */ - pm_runtime_set_active(&pdev->dev); + pm_runtime_set_active(dev); pm_runtime_enable(data->dev); ret = pm_runtime_resume_and_get(data->dev); @@ -748,11 +748,11 @@ static int imx_thermal_probe(struct platform_device *pdev) if (ret) goto thermal_zone_unregister; - ret = devm_request_threaded_irq(&pdev->dev, data->irq, + ret = devm_request_threaded_irq(dev, data->irq, imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 0, "imx_thermal", data); if (ret < 0) { - dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); + dev_err(dev, "failed to request alarm irq: %d\n", ret); goto thermal_zone_unregister; } -- cgit v1.2.3-58-ga151 From d0b297e76b5cb06bd67577dc1b710cc13e4f4300 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:38 +0200 Subject: thermal/drivers/imx: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-8-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/imx_thermal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 05c24be5343f..432d21cbd2b3 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -679,9 +679,7 @@ static int imx_thermal_probe(struct platform_device *pdev) data->thermal_clk = devm_clk_get(dev, NULL); if (IS_ERR(data->thermal_clk)) { - ret = PTR_ERR(data->thermal_clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get thermal clk: %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(data->thermal_clk), "failed to get thermal clk\n"); goto legacy_cleanup; } -- cgit v1.2.3-58-ga151 From ecfee9176b8fd68178a9682fc7285054266012ef Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:39 +0200 Subject: thermal/drivers/qcom-spmi-adc-tm5: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-9-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 756ac6842ff9..7c9f4023babc 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -829,12 +829,9 @@ static int adc_tm5_get_dt_channel_data(struct adc_tm5_chip *adc_tm, channel->iio = devm_fwnode_iio_channel_get_by_name(adc_tm->dev, of_fwnode_handle(node), NULL); - if (IS_ERR(channel->iio)) { - ret = PTR_ERR(channel->iio); - if (ret != -EPROBE_DEFER) - dev_err(dev, "%s: error getting channel: %d\n", name, ret); - return ret; - } + if (IS_ERR(channel->iio)) + return dev_err_probe(dev, PTR_ERR(channel->iio), "%s: error getting channel\n", + name); ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); if (!ret) { -- cgit v1.2.3-58-ga151 From bc55630c657a7f81e65b6993e8113f453cdcef4b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:40 +0200 Subject: thermal/drivers/qcom-tsens: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-10-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/qcom/tsens.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index e76e23026dc8..0b4421bf4785 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -1336,11 +1336,9 @@ static int tsens_probe(struct platform_device *pdev) if (priv->ops->calibrate) { ret = priv->ops->calibrate(priv); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "%s: calibration failed\n", __func__); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "%s: calibration failed\n", + __func__); } ret = tsens_register(priv); -- cgit v1.2.3-58-ga151 From f637bfe26c23c8e4a38076da286f6a0de1291323 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:41 +0200 Subject: thermal/drivers/generic-adc: Simplify probe() with local dev variable Simplify the probe() function by using local 'dev' instead of &pdev->dev. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-11-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/thermal-generic-adc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index 1717e4a19dcb..d08bff91ac3d 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -117,44 +117,45 @@ static int gadc_thermal_read_linear_lookup_table(struct device *dev, static int gadc_thermal_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct gadc_thermal_info *gti; int ret; - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "Only DT based supported\n"); + if (!dev->of_node) { + dev_err(dev, "Only DT based supported\n"); return -ENODEV; } - gti = devm_kzalloc(&pdev->dev, sizeof(*gti), GFP_KERNEL); + gti = devm_kzalloc(dev, sizeof(*gti), GFP_KERNEL); if (!gti) return -ENOMEM; - gti->channel = devm_iio_channel_get(&pdev->dev, "sensor-channel"); + gti->channel = devm_iio_channel_get(dev, "sensor-channel"); if (IS_ERR(gti->channel)) { ret = PTR_ERR(gti->channel); if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "IIO channel not found: %d\n", ret); + dev_err(dev, "IIO channel not found: %d\n", ret); return ret; } - ret = gadc_thermal_read_linear_lookup_table(&pdev->dev, gti); + ret = gadc_thermal_read_linear_lookup_table(dev, gti); if (ret < 0) return ret; - gti->dev = &pdev->dev; + gti->dev = dev; - gti->tz_dev = devm_thermal_of_zone_register(&pdev->dev, 0, gti, + gti->tz_dev = devm_thermal_of_zone_register(dev, 0, gti, &gadc_thermal_ops); if (IS_ERR(gti->tz_dev)) { ret = PTR_ERR(gti->tz_dev); if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, + dev_err(dev, "Thermal zone sensor register failed: %d\n", ret); return ret; } - devm_thermal_add_hwmon_sysfs(&pdev->dev, gti->tz_dev); + devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev); return 0; } -- cgit v1.2.3-58-ga151 From d5c38eec5d58d5d017bb8c73b4387943d080c32f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jul 2024 14:59:42 +0200 Subject: thermal/drivers/generic-adc: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240709-thermal-probe-v1-12-241644e2b6e0@linaro.org Signed-off-by: Daniel Lezcano --- drivers/thermal/thermal-generic-adc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index d08bff91ac3d..ee3d0aa31406 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -131,12 +131,8 @@ static int gadc_thermal_probe(struct platform_device *pdev) return -ENOMEM; gti->channel = devm_iio_channel_get(dev, "sensor-channel"); - if (IS_ERR(gti->channel)) { - ret = PTR_ERR(gti->channel); - if (ret != -EPROBE_DEFER) - dev_err(dev, "IIO channel not found: %d\n", ret); - return ret; - } + if (IS_ERR(gti->channel)) + return dev_err_probe(dev, PTR_ERR(gti->channel), "IIO channel not found\n"); ret = gadc_thermal_read_linear_lookup_table(dev, gti); if (ret < 0) -- cgit v1.2.3-58-ga151 From e61cc85edbbeb71e53fbf049dc9ec763bc274479 Mon Sep 17 00:00:00 2001 From: Raphael Gallais-Pou Date: Mon, 8 Jul 2024 18:18:40 +0200 Subject: thermal/drivers/sti: Cleanup code related to stih416 "st,stih416-mpe-thermal" compatible seems to appear nowhere in the device-tree nor in the documentation. Remove compatible and related code. Signed-off-by: Raphael Gallais-Pou Link: https://lore.kernel.org/r/20240708161840.102004-1-rgallaispou@gmail.com Signed-off-by: Daniel Lezcano --- drivers/thermal/st/st_thermal_memmap.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/thermal/st/st_thermal_memmap.c b/drivers/thermal/st/st_thermal_memmap.c index 29c2269b0fb3..e427117381a4 100644 --- a/drivers/thermal/st/st_thermal_memmap.c +++ b/drivers/thermal/st/st_thermal_memmap.c @@ -142,15 +142,6 @@ static const struct st_thermal_sensor_ops st_mmap_sensor_ops = { .enable_irq = st_mmap_enable_irq, }; -/* Compatible device data stih416 mpe thermal sensor */ -static const struct st_thermal_compat_data st_416mpe_cdata = { - .reg_fields = st_mmap_thermal_regfields, - .ops = &st_mmap_sensor_ops, - .calibration_val = 14, - .temp_adjust_val = -95, - .crit_temp = 120, -}; - /* Compatible device data stih407 thermal sensor */ static const struct st_thermal_compat_data st_407_cdata = { .reg_fields = st_mmap_thermal_regfields, @@ -161,7 +152,6 @@ static const struct st_thermal_compat_data st_407_cdata = { }; static const struct of_device_id st_mmap_thermal_of_match[] = { - { .compatible = "st,stih416-mpe-thermal", .data = &st_416mpe_cdata }, { .compatible = "st,stih407-thermal", .data = &st_407_cdata }, { /* sentinel */ } }; -- cgit v1.2.3-58-ga151