Commit Graph

179 Commits

Author SHA1 Message Date
Linus Torvalds 7f73ba68cf Thermal control updates for 6.8-rc1
- Add dynamic thresholds for trip point crossing detection to prevent
    trip point crossing notifications from being sent at incorrect times
    or not at all in some cases (Rafael J. Wysocki).
 
  - Fix synchronization issues related to the resume of thermal zones
    during a system-wide resume and allow thermal zones to be resumed
    concurrently (Rafael J. Wysocki).
 
  - Modify the thermal zone unregistration to wait for the given zone to
    go away completely before returning to the caller and rework the
    sysfs interface for trip points on top of that (Rafael J. Wysocki).
 
  - Fix a possible NULL pointer dereference in thermal zone registration
    error path (Rafael J. Wysocki).
 
  - Clean up the IPA thermal governor and modify it (with the help of a
    new governor callback) to avoid allocating and freeing memory every
    time its throttling callback is invoked (Lukasz Luba).
 
  - Make the IPA thermal governor handle thermal instance weight changes
    via sysfs correctly (Lukasz Luba).
 
  - Update the thermal netlink code to avoid sending messages if there
    are no recipients (Stanislaw Gruszka).
 
  - Convert Mediatek Thermal to the json-schema (Rafał Miłecki).
 
  - Fix thermal DT bindings issue on Loongson (Binbin Zhou).
 
  - Fix returning NULL instead of -ENODEV during thermal probe on
    Loogsoon (Binbin Zhou).
 
  - Add thermal DT binding for tsens on the SM8650 platform (Neil
    Armstrong).
 
  - Add reboot on the critical trip point crossing option feature (Fabio
    Estevam).
 
  - Use DEFINE_SIMPLE_DEV_PM_OPS do define PM functions for thermal
    suspend/resume on AmLogic (Uwe Kleine-König)
 
  - Add D1/T113s THS controller support to the Sun8i thermal control
    driver (Maxim Kiselev)
 
  - Fix example in the thermal DT binding for QCom SPMI (Johan Hovold).
 
  - Fix compilation warning in the tmon utility (Florian Eckert).
 
  - Add support for interrupt-based thermal configuration on Exynos along
    with a set of related cleanups (Mateusz Majewski).
 
  - Make the Intel HFI thermal driver enable an HFI instance (eg. processor
    package) from its first online CPU and disable it when the last CPU in
    it goes offline (Ricardo Neri).
 
  - Fix a kernel-doc warning and a spello in the cpuidle_cooling thermal
    driver (Randy Dunlap).
 
  - Move the .get_temp() thermal zone callback presence check to the
    thermal zone registration code (Daniel Lezcano).
 
  - Use the for_each_trip() macro for trip points table walks in a few
    places in the thermal core (Rafael J. Wysocki).
 
  - Make all trip point updates (via sysfs as well as from the platform
    firmware) trigger trip change notifications (Rafael J. Wysocki).
 
  - Drop redundant code from the thermal core and make one function in
    it take a const pointer argument (Rafael J. Wysocki).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmWb8iUSHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxKLkP/iDsuDwmhZAjbAu2iftk/8ad8Trm2VoK
 +9eZ5Eqa8lKEcJLb0RxueTnFT4ppvT/hY99HOG4FM+mCnWeH/Z32N697DhqiUg4v
 GZUpeOPzxYgsfOOTeuL5XgfrVMgBjJrJunTXmzgAd8lIhTmRbAMVmFVJ18CJO11O
 RHgqvYznYFi5cywA9/NkG2xkhFB0VDoiTuIiuMMV+pMjqF0d5ooBMkhmjvPQ5Rp9
 FjNJ7hqiTamAsDPdULAFqhIGGhKZWWFbh4+S+JPCwBW8nqvxyJpemsm20vrwctJR
 bSXWQkgkDpWEeg9yrEAOO/Uk9yGd3jiLfkvPBKbK0x/YxGZ4hOYHcbF3cOUvmPYP
 5K3ZJ61DNrzB/5S3LY54VYrWmTVRdK6Lk3HYNvfAUYFJZMZ5oMYZLCUmo4SswUdy
 UUEIY27H7L18eLhP9zCcKo4njdaVG+vXQn/rJIFOpG0k9OElzPs1X8Dp/m9pKQDR
 rDUsMXqB34NUVrIEhjAgqvwF5xHooW8gykpuJgxwBetA9w8Pls2A/mzLsDY3wgdQ
 htiANGpKTDqBQSn+HrjzYckv9/R+1tDyTJmEDNZwllA1DJfrOlpCRD2VHRpgTZEA
 Ldnq0bhyq6RQnousqxhgpYkIAoGaebs9XasRH0YtBG5gIumeWfqeVzmTcM5xdsNB
 yf6RdQy8QunS
 =QVyh
 -----END PGP SIGNATURE-----

Merge tag 'thermal-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull thermal control updates from Rafael Wysocki:
 "These add support for the D1/T113s THS controller to the sun8i driver
  and a DT-based mechanism for platforms to indicate a preference to
  reboot (instead of shutting down) on crossing a critical trip point,
  fix issues, make other improvements (in the IPA governor, the Intel
  HFI driver, the exynos driver and the thermal netlink interface among
  other places) and clean up code.

  One long-standing issue addressed here is that trip point crossing
  notifications sent to user space might be unreliable due to the
  incorrect handling of trip point hysteresis in the thermal core:
  multiple notifications might be sent for the same event or there might
  be events without any notification at all.

  Specifics:

   - Add dynamic thresholds for trip point crossing detection to prevent
     trip point crossing notifications from being sent at incorrect
     times or not at all in some cases (Rafael J. Wysocki)

   - Fix synchronization issues related to the resume of thermal zones
     during a system-wide resume and allow thermal zones to be resumed
     concurrently (Rafael J. Wysocki)

   - Modify the thermal zone unregistration to wait for the given zone
     to go away completely before returning to the caller and rework the
     sysfs interface for trip points on top of that (Rafael J. Wysocki)

   - Fix a possible NULL pointer dereference in thermal zone
     registration error path (Rafael J. Wysocki)

   - Clean up the IPA thermal governor and modify it (with the help of a
     new governor callback) to avoid allocating and freeing memory every
     time its throttling callback is invoked (Lukasz Luba)

   - Make the IPA thermal governor handle thermal instance weight
     changes via sysfs correctly (Lukasz Luba)

   - Update the thermal netlink code to avoid sending messages if there
     are no recipients (Stanislaw Gruszka)

   - Convert Mediatek Thermal to the json-schema (Rafał Miłecki)

   - Fix thermal DT bindings issue on Loongson (Binbin Zhou)

   - Fix returning NULL instead of -ENODEV during thermal probe on
     Loogsoon (Binbin Zhou)

   - Add thermal DT binding for tsens on the SM8650 platform (Neil
     Armstrong)

   - Add reboot on the critical trip point crossing option feature
     (Fabio Estevam)

   - Use DEFINE_SIMPLE_DEV_PM_OPS do define PM functions for thermal
     suspend/resume on AmLogic (Uwe Kleine-König)

   - Add D1/T113s THS controller support to the Sun8i thermal control
     driver (Maxim Kiselev)

   - Fix example in the thermal DT binding for QCom SPMI (Johan Hovold)

   - Fix compilation warning in the tmon utility (Florian Eckert)

   - Add support for interrupt-based thermal configuration on Exynos
     along with a set of related cleanups (Mateusz Majewski)

   - Make the Intel HFI thermal driver enable an HFI instance (eg.
     processor package) from its first online CPU and disable it when
     the last CPU in it goes offline (Ricardo Neri)

   - Fix a kernel-doc warning and a spello in the cpuidle_cooling
     thermal driver (Randy Dunlap)

   - Move the .get_temp() thermal zone callback presence check to the
     thermal zone registration code (Daniel Lezcano)

   - Use the for_each_trip() macro for trip points table walks in a few
     places in the thermal core (Rafael J. Wysocki)

   - Make all trip point updates (via sysfs as well as from the platform
     firmware) trigger trip change notifications (Rafael J. Wysocki)

   - Drop redundant code from the thermal core and make one function in
     it take a const pointer argument (Rafael J. Wysocki)"

* tag 'thermal-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (64 commits)
  thermal: trip: Constify thermal zone argument of thermal_zone_trip_id()
  thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline
  thermal: intel: hfi: Enable an HFI instance from its first online CPU
  thermal: intel: hfi: Refactor enabling code into helper functions
  thermal/drivers/exynos: Use set_trips ops
  thermal/drivers/exynos: Use BIT wherever possible
  thermal/drivers/exynos: Split initialization of TMU and the thermal zone
  thermal/drivers/exynos: Stop using the threshold mechanism on Exynos 4210
  thermal/drivers/exynos: Simplify regulator (de)initialization
  thermal/drivers/exynos: Handle devm_regulator_get_optional return value correctly
  thermal/drivers/exynos: Wwitch from workqueue-driven interrupt handling to threaded interrupts
  thermal/drivers/exynos: Drop id field
  thermal/drivers/exynos: Remove an unnecessary field description
  tools/thermal/tmon: Fix compilation warning for wrong format
  dt-bindings: thermal: qcom-spmi-adc-tm5/hc: Clean up examples
  dt-bindings: thermal: qcom-spmi-adc-tm5/hc: Fix example node names
  thermal/drivers/sun8i: Add D1/T113s THS controller support
  dt-bindings: thermal: sun8i: Add binding for D1/T113s THS controller
  thermal: amlogic: Use DEFINE_SIMPLE_DEV_PM_OPS for PM functions
  thermal: amlogic: Make amlogic_thermal_disable() return void
  ...
2024-01-09 16:20:17 -08:00
Lukasz Luba bfc57bd168 thermal/sysfs: Update governors when the 'weight' has changed
Support governors update when the thermal instance's weight has changed.
This allows to adjust internal state for the governor.

Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
[ rjw: Add two empty code lines aroung the locking ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-12-29 18:01:01 +01:00
Lukasz Luba a8c959402d thermal: core: Add governor callback for thermal zone change
Add a new callback to the struct thermal_governor. It can be used for
updating governors when there is a change in the thermal zone internals,
e.g. thermal cooling device is bind to the thermal zone.

That makes possible to move some heavy operations like memory allocations
related to the number of cooling instances out of the throttle() callback.

Both callback code paths (throttle() and update_tz()) are protected with
the same thermal zone lock, which guaranties the consistency.

Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-12-29 18:01:00 +01:00
Rafael J. Wysocki 4e814173a8 thermal: core: Fix thermal zone suspend-resume synchronization
There are 3 synchronization issues with thermal zone suspend-resume
during system-wide transitions:

 1. The resume code runs in a PM notifier which is invoked after user
    space has been thawed, so it can run concurrently with user space
    which can trigger a thermal zone device removal.  If that happens,
    the thermal zone resume code may use a stale pointer to the next
    list element and crash, because it does not hold thermal_list_lock
    while walking thermal_tz_list.

 2. The thermal zone resume code calls thermal_zone_device_init()
    outside the zone lock, so user space or an update triggered by
    the platform firmware may see an inconsistent state of a
    thermal zone leading to unexpected behavior.

 3. Clearing the in_suspend global variable in thermal_pm_notify()
    allows __thermal_zone_device_update() to continue for all thermal
    zones and it may as well run before the thermal_tz_list walk (or
    at any point during the list walk for that matter) and attempt to
    operate on a thermal zone that has not been resumed yet.  It may
    also race destructively with thermal_zone_device_init().

To address these issues, add thermal_list_lock locking to
thermal_pm_notify(), especially arount the thermal_tz_list,
make it call thermal_zone_device_init() back-to-back with
__thermal_zone_device_update() under the zone lock and replace
in_suspend with per-zone bool "suspend" indicators set and unset
under the given zone's lock.

Link: https://lore.kernel.org/linux-pm/20231218162348.69101-1-bo.ye@mediatek.com/
Reported-by: Bo Ye <bo.ye@mediatek.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-12-28 14:20:15 +01:00
Rafael J. Wysocki bdc22c8d52 thermal: trip: Send trip change notifications on all trip updates
The _store callbacks of the trip point temperature and hysteresis sysfs
attributes invoke thermal_notify_tz_trip_change() to send a notification
regarding the trip point change, but when trip points are updated by the
platform firmware, trip point change notifications are not sent.

To make the behavior after a trip point change more consistent,
modify all of the 3 places where trip point temperature is updated
to use a new function called thermal_zone_set_trip_temp() for this
purpose and make that function call thermal_notify_tz_trip_change().

Note that trip point hysteresis can only be updated via sysfs and
trip_point_hyst_store() calls thermal_notify_tz_trip_change() already,
so this code path need not be changed.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-12-13 12:37:01 +01:00
Rafael J. Wysocki 4649620d94 thermal: core: Make thermal_zone_device_unregister() return after freeing the zone
Make thermal_zone_device_unregister() wait until all of the references
to the given thermal zone object have been dropped and free it before
returning.

This guarantees that when thermal_zone_device_unregister() returns,
there is no leftover activity regarding the thermal zone in question
which is required by some of its callers (for instance, modular driver
code that wants to know when it is safe to let the module go away).

Subsequently, this will allow some confusing device_is_registered()
checks to be dropped from the thermal sysfs and core code.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-and-tested-by: Lukasz Luba <lukasz.luba@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-12-11 20:49:53 +01:00
Rafael J. Wysocki be0a3600aa thermal: sysfs: Rework the handling of trip point updates
Both trip_point_temp_store() and trip_point_hyst_store() use
thermal_zone_set_trip() to update a given trip point, but none of them
actually needs to change more than one field in struct thermal_trip
representing it.  However, each of them effectively calls
__thermal_zone_get_trip() twice in a row for the same trip index value,
once directly and once via thermal_zone_set_trip(), which is not
particularly efficient, and the way in which thermal_zone_set_trip()
carries out the update is not particularly straightforward.

Moreover, input processing need not be done under the thermal zone lock
in any of these functions.

Rework trip_point_temp_store() and trip_point_hyst_store() to address
the above, move the part of thermal_zone_set_trip() that is still
useful to a new function called thermal_zone_trip_updated() and drop
the rest of it.

While at it, make trip_point_hyst_store() reject negative hysteresis
values.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-12-06 21:29:52 +01:00
Rafael J. Wysocki f475079881 thermal: ACPI: Move the ACPI thermal library to drivers/acpi/
The ACPI thermal library contains functions that can be used to
retrieve trip point temperature values through the platform firmware
for various types of trip points.  Each of these functions basically
evaluates a specific ACPI object, checks if the value produced by it
is reasonable and returns it (or THERMAL_TEMP_INVALID if anything
fails).

It made sense to hold it in drivers/thermal/ so long as it was only used
by the code in that directory, but since it is also going to be used by
the ACPI thermal driver located in drivers/acpi/, move it to the latter
in order to keep the code related to evaluating ACPI objects defined in
the specification proper together.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-11-21 15:04:08 +01:00
Rafael J. Wysocki 44844db913 thermal: core: Add trip thresholds for trip crossing detection
The trip crossing detection in handle_thermal_trip() does not work
correctly in the cases when a trip point is crossed on the way up and
then the zone temperature stays above its low temperature (that is, its
temperature decreased by its hysteresis).  The trip temperature may
be passed by the zone temperature subsequently in that case, even
multiple times, but that does not count as the trip crossing as long as
the zone temperature does not fall below the trip's low temperature or,
in other words, until the trip is crossed on the way down.

|-----------low--------high------------|
             |<--------->|
             |    hyst   |
             |           |
             |          -|--> crossed on the way up
             |
         <---|-- crossed on the way down

However, handle_thermal_trip() will invoke thermal_notify_tz_trip_up()
every time the trip temperature is passed by the zone temperature on
the way up regardless of whether or not the trip has been crossed on
the way down yet.  Moreover, it will not call thermal_notify_tz_trip_down()
if the last zone temperature was between the trip's temperature and its
low temperature, so some "trip crossed on the way down" events may not
be reported.

To address this issue, introduce trip thresholds equal to either the
temperature of the given trip, or its low temperature, such that if
the trip's threshold is passed by the zone temperature on the way up,
its value will be set to the trip's low temperature and
thermal_notify_tz_trip_up() will be called, and if the trip's threshold
is passed by the zone temperature on the way down, its value will be set
to the trip's temperature (high) and thermal_notify_tz_trip_down() will
be called.  Accordingly, if the threshold is passed on the way up, it
cannot be passed on the way up again until its passed on the way down
and if it is passed on the way down, it cannot be passed on the way down
again until it is passed on the way up which guarantees correct
triggering of trip crossing notifications.

If the last temperature of the zone is invalid, the trip's threshold
will be set depending of the zone's current temperature: If that
temperature is above the trip's temperature, its threshold will be
set to its low temperature or otherwise its threshold will be set to
its (high) temperature.  Because the zone temperature is initially
set to invalid and tz->last_temperature is only updated by
update_temperature(), this is sufficient to set the correct initial
threshold values for all trips.

Link: https://lore.kernel.org/all/20220718145038.1114379-4-daniel.lezcano@linaro.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-11-20 16:59:55 +01:00
Rafael J. Wysocki 8c35b1f472 thermal: core: Pass trip pointer to governor throttle callback
Modify the governor .throttle() callback definition so that it takes a
trip pointer instead of a trip index as its second argument, adjust the
governors accordingly and update the core code invoking .throttle().

This causes the governors to become independent of the representation
of the list of trips in the thermal zone structure.

This change is not expected to alter the general functionality.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-10-20 19:26:37 +02:00
Rafael J. Wysocki 4963e34ce7 thermal: core: Drop thermal_zone_device_exec()
Because thermal_zone_device_exec() has no users any more and there are
no plans to use it anywhere, revert commit 9a99a996d1 ("thermal: core:
Introduce thermal_zone_device_exec()") that introduced it.

No functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-10-05 13:32:55 +02:00
Rafael J. Wysocki a56cc0a833 thermal: core: Add function to walk trips under zone lock
Add a wrapper around for_each_thermal_trip(), called
thermal_zone_for_each_trip(), that will invoke the former under the
thermal zone lock and pass its return value to the caller.

Two drivers will be modified subsequently to use this new function.

No functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-10-05 13:13:40 +02:00
Rafael J. Wysocki d069ed6b75 thermal: core: Allow trip pointers to be used for cooling device binding
Add new helper functions, thermal_bind_cdev_to_trip() and
thermal_unbind_cdev_from_trip(), to allow a trip pointer to be used for
binding a cooling device to a trip point and unbinding it, respectively,
and redefine the existing helpers, thermal_zone_bind_cooling_device()
and thermal_zone_unbind_cooling_device(), as wrappers around the new
ones, respectively.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-09-28 12:57:10 +02:00
Rafael J. Wysocki 9502108876 thermal: core: Drop trips_disabled bitmask
After recent changes, thermal_zone_get_trip() cannot fail, as invoked
from thermal_zone_device_register_with_trips(), so the only role of
the trips_disabled bitmask is struct thermal_zone_device is to make
handle_thermal_trip() skip trip points whose temperature was initially
zero.  However, since the unit of temperature in the thermal core is
millicelsius, zero may very well be a valid temperature value at least
in some usage scenarios and the trip temperature may as well change
later.  Thus there is no reason to permanently disable trip points
with initial temperature equal to zero.

Accordingly, drop the trips_disabled bitmask along with the code
related to it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-09-25 11:46:19 +02:00
Rafael J. Wysocki ebc7abb35b thermal: Constify the trip argument of the .get_trend() zone callback
Add 'const' to the definition of the 'trip' argument of the
.get_trend() thermal zone callback to indicate that the trip point
passed to it should not be modified by it and adjust the
callback functions implementing it, thermal_get_trend() in the
ACPI thermal driver and __ti_thermal_get_trend(), accordingly.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Michal Wilczynski <michal.wilczynski@intel.com>
2023-09-11 17:16:40 +02:00
Rafael J. Wysocki edd220b33f thermal: core: Drop thermal_zone_device_register()
There are no more users of thermal_zone_device_register(), so drop it
from the core.

Note that thermal_zone_device_register_with_trips() may be renamed to
thermal_zone_device_register() in the future, but only after a grace
period allowing all of the possible work in progress that may be using
the latter to adjust.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-09-05 21:42:18 +02:00
Rafael J. Wysocki d332db8fc1 thermal: core: Add function for registering tripless thermal zones
Multiple callers of thermal_zone_device_register() don't pass any trips
to it and they might use a shortened argument list for that, so add
a special function with fewer arguments for this purpose.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-09-05 21:42:18 +02:00
Rafael J. Wysocki 9ffa7b92bc thermal: core: Clean up headers of thermal zone registration functions
For consistency, add a missing thermal_zone_device_register_with_trips()
stub for the CONFIG_THERMAL unset case, specify argument names in all of
the thermal zone registration and unregistration function headers and
make all of them use white space consistently.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-09-05 21:42:18 +02:00
Rafael J. Wysocki 8289d810ea thermal: core: Rework .get_trend() thermal zone callback
Passing a struct thermal_trip pointer instead of a trip index to the
.get_trend() thermal zone callback allows one of its 2 implementations,
the thermal_get_trend() function in the ACPI thermal driver, to be
simplified quite a bit, and the other implementation of it in the
ti-soc-thermal driver does not even use the relevant callback argument.

For this reason, change the .get_trend() thermal zone callback
definition and adjust the related code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-08-29 20:48:35 +02:00
Rafael J. Wysocki 35d8dbbb25 thermal: core: Drop unused .get_trip_*() callbacks
After recent changes in the ACPI thermal driver and in the Intel DTS
IOSF thermal driver, all thermal zone drivers are expected to use trip
tables for initialization and none of them should implement
.get_trip_type(), .get_trip_temp() or .get_trip_hyst() callbacks, so
drop these callbacks entirely from the core.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-08-29 20:46:31 +02:00
Rafael J. Wysocki 0c2ec0f165 Merge branch 'acpi-thermal'
Merge ACPI thermal driver changes for 6.6-rc1:

 - Drop non-functional nocrt parameter from ACPI thermal (Mario
   Limonciello).

 - Clean up the ACPI thermal driver, rework the handling of firmware
   notifications in it and make it provide a table of generic trip point
   structures to the core during initialization (Rafael Wysocki).

* acpi-thermal:
  ACPI: thermal: Eliminate code duplication from acpi_thermal_notify()
  ACPI: thermal: Drop unnecessary thermal zone callbacks
  ACPI: thermal: Rework thermal_get_trend()
  ACPI: thermal: Use trip point table to register thermal zones
  thermal: core: Rework and rename __for_each_thermal_trip()
  ACPI: thermal: Introduce struct acpi_thermal_trip
  ACPI: thermal: Carry out trip point updates under zone lock
  ACPI: thermal: Clean up acpi_thermal_register_thermal_zone()
  thermal: core: Add priv pointer to struct thermal_trip
  thermal: core: Introduce thermal_zone_device_exec()
  thermal: core: Do not handle trip points with invalid temperature
  ACPI: thermal: Drop redundant local variable from acpi_thermal_resume()
  ACPI: thermal: Do not attach private data to ACPI handles
  ACPI: thermal: Drop enabled flag from struct acpi_thermal_active
  ACPI: thermal: Drop nocrt parameter
2023-08-25 20:44:26 +02:00
Rafael J. Wysocki 96b8b4365d thermal: core: Rework and rename __for_each_thermal_trip()
Rework the currently unused __for_each_thermal_trip() to pass original
pointers to struct thermal_trip objects to the callback, so it can be
used for updating trip data (e.g. temperatures), rename it to
for_each_thermal_trip() and make it available to modular drivers.

Suggested-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-08-17 11:25:22 +02:00
Rafael J. Wysocki cba440fab3 thermal: core: Add priv pointer to struct thermal_trip
Add a new field called priv to struct thermal_trip to allow thermal
drivers to store pointers to their local data associated with trip
points.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-08-17 11:24:18 +02:00
Rafael J. Wysocki 9a99a996d1 thermal: core: Introduce thermal_zone_device_exec()
Introduce a new helper function, thermal_zone_device_exec(), that can
be used by drivers to run a given callback routine under the zone lock.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-08-17 11:23:32 +02:00
Ahmad Fatoum 80ddce5f2d thermal: core: constify params in thermal_zone_device_register
Since commit 3d439b1a2a ("thermal/core: Alloc-copy-free the thermal zone
parameters structure"), thermal_zone_device_register() allocates a copy
of the tzp argument and callers need not explicitly manage its lifetime.

This means the function no longer cares about the parameter being
mutable, so constify it.

No functional change.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-07-24 09:51:31 +02:00
Daniel Lezcano 7cefbaf081 thermal: core: Encapsulate tz->device field
There are still some drivers needing to play with the thermal zone
device internals. That is not the best but until we can figure out if
the information is really needed, let's encapsulate the field used in
the thermal zone device structure, so we can move forward relocating
the thermal zone device structure definition in the thermal framework
private headers.

Some drivers are accessing tz->device, that implies they need to have
the knowledge of the thermal_zone_device structure but we want to
self-encapsulate this structure and reduce the scope of the structure
to the thermal core only.

By adding this wrapper, these drivers won't need the thermal zone
device structure definition and are no longer an obstacle to its
relocation to the private thermal core headers.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-04-27 19:20:12 +02:00
Daniel Lezcano ac614a9b4c thermal/of: Unexport unused OF functions
The functions thermal_of_zone_register() and
thermal_of_zone_unregister() are no longer needed from the drivers as
the devm_ variant is always used.

Make them static in the C file and remove their declaration from thermal.h

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20230404075138.2914680-2-daniel.lezcano@linaro.org
2023-04-07 18:36:28 +02:00
Zhang Rui ded2d383b1 thermal/core: Remove thermal_bind_params structure
Remove struct thermal_bind_params because no one is using it for thermal
binding now.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20230330104526.3196-1-rui.zhang@intel.com
2023-04-07 11:18:22 +02:00
Rafael J. Wysocki ce07727aff Merge back thermal control material for 6.4-rc1. 2023-03-27 13:46:13 +02:00
Rafael J. Wysocki 790930f442 thermal: core: Introduce thermal_cooling_device_update()
Introduce a core thermal API function, thermal_cooling_device_update(),
for updating the max_state value for a cooling device and rearranging
its statistics in sysfs after a possible change of its ->get_max_state()
callback return value.

That callback is now invoked only once, during cooling device
registration, to populate the max_state field in the cooling device
object, so if its return value changes, it needs to be invoked again
and the new return value needs to be stored as max_state.  Moreover,
the statistics presented in sysfs need to be rearranged in general,
because there may not be enough room in them to store data for all
of the possible states (in the case when max_state grows).

The new function takes care of that (and some other minor things
related to it), but some extra locking and lockdep annotations are
added in several places too to protect against crashes in the cases
when the statistics are not present or when a stale max_state value
might be used by sysfs attributes.

Note that the actual user of the new function will be added separately.

Link: https://lore.kernel.org/linux-pm/53ec1f06f61c984100868926f282647e57ecfb2d.camel@intel.com/
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Zhang Rui <rui.zhang@intel.com>
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
2023-03-22 15:20:38 +01:00
Daniel Lezcano 3034f859b9 thermal: Add a thermal zone id accessor
In order to get the thermal zone id but without directly accessing the
thermal zone device structure, add an accessor.

Use the accessor in the hwmon_scmi and acpi_thermal.

No functional change intented.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-03-03 20:45:02 +01:00
Daniel Lezcano 072e35c988 thermal/core: Add thermal_zone_device structure 'type' accessor
The thermal zone device structure is exposed via the exported
thermal.h header. This structure should stay private the thermal core
code. In order to encapsulate the structure, let's add an accessor to
get the 'type' of the thermal zone.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-03-03 20:45:02 +01:00
Daniel Lezcano a6ff3c0021 thermal/core: Add a thermal zone 'devdata' accessor
The thermal zone device structure is exposed to the different drivers
and obviously they access the internals while that should be
restricted to the core thermal code.

In order to self-encapsulate the thermal core code, we need to prevent
the drivers accessing directly the thermal zone structure and provide
accessor functions to deal with.

Provide an accessor to the 'devdata' structure and make use of it in
the different drivers.

No functional changes intended.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-03-03 20:45:02 +01:00
Rafael J. Wysocki dd3b3d160e thermal: ACPI: Make helpers retrieve temperature only
It is slightly better to make the ACPI thermal helper functions retrieve
the trip point temperature only instead of doing the full trip point
initialization, because they are also used for updating some already
registered trip points, in which case initializing a new trip just
in order to update the temperature of an existing one is somewhat
wasteful.

Modify the ACPI thermal helpers accordingly and update their users.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2023-02-02 15:26:45 +01:00
Rafael J. Wysocki 7a0e397488 thermal: ACPI: Add ACPI trip point routines
Add library routines to populate a generic thermal trip point
structure with data obtained by evaluating a specific object in the
ACPI Namespace.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Co-developed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
2023-01-24 21:13:42 +01:00
Johan Hovold e6ec64f852 thermal/drivers/qcom: Fix set_trip_temp() deadlock
The set_trip_temp() callback is used when changing the trip temperature
through sysfs. As it is called with the thermal-zone-device lock held
it must not use thermal_zone_get_trip() directly or it will deadlock.

Fixes: 78c3e2429be8 ("thermal/drivers/qcom: Use generic thermal_zone_get_trip() function")
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20221214131617.2447-2-johan+linaro@kernel.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
2023-01-06 14:14:48 +01:00
Daniel Lezcano 2e38a2a981 thermal/core: Add a generic thermal_zone_set_trip() function
The thermal zone ops defines a set_trip callback where we can invoke
the backend driver to set an interrupt for the next trip point
temperature being crossed the way up or down, or setting the low level
with the hysteresis.

The ops is only called from the thermal sysfs code where the userspace
has the ability to modify a trip point characteristic.

With the effort of encapsulating the thermal framework core code,
let's create a thermal_zone_set_trip() which is the writable side of
the thermal_zone_get_trip() and put there all the ops encapsulation.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://lore.kernel.org/r/20221003092602.1323944-4-daniel.lezcano@linaro.org
2023-01-06 14:14:47 +01:00
Daniel Lezcano 7c3d5c20dc thermal/core: Add a generic thermal_zone_get_trip() function
The thermal_zone_device_ops structure defines a set of ops family,
get_trip_temp(), get_trip_hyst(), get_trip_type(). Each of them is
returning a property of a trip point.

The result is the code is calling the ops everywhere to get a trip
point which is supposed to be defined in the backend driver. It is a
non-sense as a thermal trip can be generic and used by the backend
driver to declare its trip points.

Part of the thermal framework has been changed and all the OF thermal
drivers are using the same definition for the trip point and use a
thermal zone registration variant to pass those trip points which are
part of the thermal zone device structure.

Consequently, we can use a generic function to get the trip points
when they are stored in the thermal zone device structure.

This approach can be generalized to all the drivers and we can get rid
of the ops->get_trip_*. That will result to a much more simpler code
and make possible to rework how the thermal trip are handled in the
thermal core framework as discussed previously.

This change adds a function thermal_zone_get_trip() where we get the
thermal trip point structure which contains all the properties (type,
temp, hyst) instead of doing multiple calls to ops->get_trip_*.

That opens the door for trip point extension with more attributes. For
instance, replacing the trip points disabled bitmask with a 'disabled'
field in the structure.

Here we replace all the calls to ops->get_trip_* in the thermal core
code with a call to the thermal_zone_get_trip() function.

The thermal zone ops defines a callback to retrieve the critical
temperature. As the trip handling is being reworked, all the trip
points will be the same whatever the driver and consequently finding
the critical trip temperature will be just a loop to search for a
critical trip point type.

Provide such a generic function, so we encapsulate the ops
get_crit_temp() which can be removed when all the backend drivers are
using the generic trip points handling.

While at it, add the thermal_zone_get_num_trips() to encapsulate the
code more and reduce the grip with the thermal framework internals.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
Link: https://lore.kernel.org/r/20221003092602.1323944-2-daniel.lezcano@linaro.org
2023-01-06 14:14:47 +01:00
Viresh Kumar c408b3d1d9 thermal: Validate new state in cur_state_store()
In cur_state_store(), the new state of the cooling device is received
from user-space and is not validated by the thermal core but the same is
left for the individual drivers to take care of. Apart from duplicating
the code it leaves possibility for introducing bugs where a driver may
not do it right.

Lets make the thermal core check the new state itself and store the max
value in the cooling device structure.

Link: https://lore.kernel.org/all/Y0ltRJRjO7AkawvE@kili/
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-10-25 18:58:11 +02:00
Daniel Lezcano 5d10f480f7 thermal/of: Remove the thermal_zone_of_get_sensor_id() function
The function thermal_zone_of_get_sensor_id() is no longer used
anywhere, remove it.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20220818082316.2717095-2-daniel.lezcano@linaro.org
2022-10-04 11:21:06 +02:00
Sumeet Pawnikar 82b1ec794d thermal: core: Increase maximum number of trip points
On one of the Chrome system, if we define more than 12 trip points,
probe for thermal sensor fails with
"int3403 thermal: probe of INTC1046:03 failed with error -22"
and throws an error as
"thermal_sys: Error: Incorrect number of thermal trips".

The thermal_zone_device_register() interface needs maximum
number of trip points supported in a zone as an argument.
This number can't exceed THERMAL_MAX_TRIPS, which is currently
set to 12. To address this issue, THERMAL_MAX_TRIPS value
has to be increased.

This interface also has an argument to specify a mask of trips
which are writable. This mask is defined as an int.
This mask sets the ceiling for increasing maximum number of
supported trips. With the current implementation, maximum number
of trips can be supported is 31.

Also, THERMAL_MAX_TRIPS macro is used in one place only.
So, remove THERMAL_MAX_TRIPS macro and compare num_trips
directly with using a macro BITS_PER_TYPE(int)-1.

Signed-off-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-09-30 19:50:10 +02:00
Daniel Lezcano f59ac19b7f thermal/of: Remove old OF code
All the drivers are converted to the new OF API, remove the old OF code.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
Link: https://lore.kernel.org/r/20220804224349.1926752-34-daniel.lezcano@linexp.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-08-17 14:09:39 +02:00
Daniel Lezcano 3fd6d6e2b4 thermal/of: Rework the thermal device tree initialization
The following changes are reworking entirely the thermal device tree
initialization. The old version is kept until the different drivers
using it are converted to the new API.

The old approach creates the different actors independently. This
approach is the source of the code duplication in the thermal OF
because a thermal zone is created but a sensor is registered
after. The thermal zones are created unconditionnaly with a fake
sensor at init time, thus forcing to provide fake ops and store all
the thermal zone related information in duplicated structures. Then
the sensor is initialized and the code looks up the thermal zone name
using the device tree. Then the sensor is associated to the thermal
zone, and the sensor specific ops are called with a second level of
indirection from the thermal zone ops.

When a sensor is removed (with a module unload), the thermal zone
stays there with the fake sensor.

The cooling device associated with a thermal zone and a trip point is
stored in a list, again duplicating information, using the node name
of the device tree to match afterwards the cooling devices.

The new approach is simpler, it creates a thermal zone when the sensor
is registered and destroys it when the sensor is removed. All the
matching between the cooling device, trip points and thermal zones are
done using the device tree, as well as bindings. The ops are no longer
specific but uses the generic ones provided by the thermal framework.

When the old code won't have any users, it can be removed and the
remaining thermal OF code will be much simpler.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
Link: https://lore.kernel.org/r/20220804224349.1926752-2-daniel.lezcano@linexp.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-08-17 14:09:37 +02:00
Daniel Lezcano fae11de507 thermal/core: Add thermal_trip in thermal_zone
The thermal trip points are properties of a thermal zone and the
different sub systems should be able to save them in the thermal zone
structure instead of having their own definition.

Give the opportunity to the drivers to create a thermal zone with
thermal trips which will be accessible directly from the thermal core
framework.

As we added the thermal trip points structure in the thermal zone,
let's extend the thermal zone register function to have the thermal
trip structures as a parameter and store it in the 'trips' field of
the thermal zone structure.

The thermal zone contains the trip point, we can store them directly
when registering the thermal zone. That will allow another step
forward to remove the duplicate thermal zone structure we find in the
thermal_of code.

Cc: Alexandre Bailon <abailon@baylibre.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
Link: https://lore.kernel.org/r/20220722200007.1839356-9-daniel.lezcano@linexp.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-07-28 17:29:56 +02:00
Daniel Lezcano e5bfcd30f8 thermal/core: Rename 'trips' to 'num_trips'
In order to use thermal trips defined in the thermal structure, rename
the 'trips' field to 'num_trips' to have the 'trips' field containing the
thermal trip points.

Cc: Alexandre Bailon <abailon@baylibre.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
Link: https://lore.kernel.org/r/20220722200007.1839356-8-daniel.lezcano@linexp.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-07-28 17:29:56 +02:00
Daniel Lezcano 646274ddaf thermal/of: Move thermal_trip structure to thermal.h
The structure thermal_trip is now generic and will be usable by the
different sensor drivers in place of their own structure.

Move its definition to thermal.h to make it accessible.

Cc: Alexandre Bailon <abailon@baylibre.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linexp.org>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://lore.kernel.org/r/20220722200007.1839356-5-daniel.lezcano@linexp.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-07-28 17:29:54 +02:00
Daniel Lezcano 4102c4042a thermal/core: Remove DROP_FULL and RAISE_FULL
The trends DROP_FULL and RAISE_FULL are not used and were never used
in the past AFAICT. Remove these conditions as they seems to not be
handled anywhere.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20220629151012.3115773-2-daniel.lezcano@linaro.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-07-28 17:29:47 +02:00
Manaf Meethalavalappu Pallikunhi bf70c57751 thermal/drivers/thermal_of: Add change_mode ops support for thermal_of sensor
The sensor driver which register through thermal_of interface doesn't
have an option to get thermal zone mode change notification from
thermal core.

Add support for change_mode ops in thermal_of interface so that sensor
driver can use this ops for mode change notification.

Signed-off-by: Manaf Meethalavalappu Pallikunhi <quic_manafm@quicinc.com>
Link: https://lore.kernel.org/r/1646767586-31908-1-git-send-email-quic_manafm@quicinc.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
2022-05-19 12:11:51 +02:00
Geert Uytterhoeven 454f2ed4b3 thermal: Spelling s/scallbacks/callbacks/
Fix a misspelling of the word "callbacks".

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/ae38372996a23bb67769e2d62ca170ae9457c4df.1626261946.git.geert+renesas@glider.be
2021-08-14 15:43:28 +02:00
Arnd Bergmann fb83610762 thermal/core: Fix thermal_cooling_device_register() prototype
There are two pairs of declarations for thermal_cooling_device_register()
and thermal_of_cooling_device_register(), and only one set was changed
in a recent patch, so the other one now causes a compile-time warning:

drivers/net/wireless/mediatek/mt76/mt7915/init.c: In function 'mt7915_thermal_init':
drivers/net/wireless/mediatek/mt76/mt7915/init.c:134:48: error: passing argument 1 of 'thermal_cooling_device_register' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
  134 |         cdev = thermal_cooling_device_register(wiphy_name(wiphy), phy,
      |                                                ^~~~~~~~~~~~~~~~~
In file included from drivers/net/wireless/mediatek/mt76/mt7915/init.c:7:
include/linux/thermal.h:407:39: note: expected 'char *' but argument is of type 'const char *'
  407 | thermal_cooling_device_register(char *type, void *devdata,
      |                                 ~~~~~~^~~~

Change the dummy helper functions to have the same arguments as the
normal version.

Fixes: f991de53a8 ("thermal: make device_register's type argument const")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20210722090717.1116748-1-arnd@kernel.org
2021-08-14 15:40:26 +02:00