0020-thermal-thermal-Add-support-for-hardware-tracked-tri.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. From 346632bc00fe71c269709702fecb474bb22e933e Mon Sep 17 00:00:00 2001
  2. From: Sascha Hauer <[email protected]>
  3. Date: Wed, 13 May 2015 10:52:39 +0200
  4. Subject: [PATCH 20/76] thermal: thermal: Add support for hardware-tracked
  5. trip points
  6. This adds support for hardware-tracked trip points to the device tree
  7. thermal sensor framework.
  8. The framework supports an arbitrary number of trip points. Whenever
  9. the current temperature is updated, the trip points immediately
  10. below and above the current temperature are found. A .set_trips
  11. callback is then called with the temperatures. If there is no trip
  12. point above or below the current temperature, the passed trip
  13. temperature will be -INT_MAX or INT_MAX respectively. In this callback,
  14. the driver should program the hardware such that it is notified
  15. when either of these trip points are triggered. When a trip point
  16. is triggered, the driver should call `thermal_zone_device_update'
  17. for the respective thermal zone. This will cause the trip points
  18. to be updated again.
  19. If .set_trips is not implemented, the framework behaves as before.
  20. This patch is based on an earlier version from Mikko Perttunen
  21. <[email protected]>
  22. Signed-off-by: Sascha Hauer <[email protected]>
  23. ---
  24. drivers/thermal/thermal_core.c | 43 ++++++++++++++++++++++++++++++++++++++++
  25. include/linux/thermal.h | 3 +++
  26. 2 files changed, 46 insertions(+)
  27. --- a/drivers/thermal/thermal_core.c
  28. +++ b/drivers/thermal/thermal_core.c
  29. @@ -456,6 +456,45 @@ int thermal_zone_get_temp(struct thermal
  30. }
  31. EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
  32. +static void thermal_zone_set_trips(struct thermal_zone_device *tz)
  33. +{
  34. + int low = -INT_MAX;
  35. + int high = INT_MAX;
  36. + int trip_temp, hysteresis;
  37. + int temp = tz->temperature;
  38. + int i;
  39. +
  40. + if (!tz->ops->set_trips)
  41. + return;
  42. +
  43. + /* No need to change trip points */
  44. + if (temp > tz->prev_low_trip && temp < tz->prev_high_trip)
  45. + return;
  46. +
  47. + for (i = 0; i < tz->trips; i++) {
  48. + int trip_low;
  49. +
  50. + tz->ops->get_trip_temp(tz, i, &trip_temp);
  51. + tz->ops->get_trip_hyst(tz, i, &hysteresis);
  52. +
  53. + trip_low = trip_temp - hysteresis;
  54. +
  55. + if (trip_low < temp && trip_low > low)
  56. + low = trip_low;
  57. +
  58. + if (trip_temp > temp && trip_temp < high)
  59. + high = trip_temp;
  60. + }
  61. +
  62. + tz->prev_low_trip = low;
  63. + tz->prev_high_trip = high;
  64. +
  65. + dev_dbg(&tz->device, "new temperature boundaries: %d < x < %d\n",
  66. + low, high);
  67. +
  68. + tz->ops->set_trips(tz, low, high);
  69. +}
  70. +
  71. void thermal_zone_device_update(struct thermal_zone_device *tz)
  72. {
  73. int temp, ret, count;
  74. @@ -489,6 +528,8 @@ void thermal_zone_device_update(struct t
  75. dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
  76. tz->last_temperature, tz->temperature);
  77. + thermal_zone_set_trips(tz);
  78. +
  79. for (count = 0; count < tz->trips; count++)
  80. handle_thermal_trip(tz, count);
  81. }
  82. @@ -1522,6 +1563,8 @@ struct thermal_zone_device *thermal_zone
  83. tz->trips = trips;
  84. tz->passive_delay = passive_delay;
  85. tz->polling_delay = polling_delay;
  86. + tz->prev_low_trip = INT_MAX;
  87. + tz->prev_high_trip = -INT_MAX;
  88. /* A new thermal zone needs to be updated anyway. */
  89. atomic_set(&tz->need_update, 1);
  90. --- a/include/linux/thermal.h
  91. +++ b/include/linux/thermal.h
  92. @@ -90,6 +90,7 @@ struct thermal_zone_device_ops {
  93. int (*unbind) (struct thermal_zone_device *,
  94. struct thermal_cooling_device *);
  95. int (*get_temp) (struct thermal_zone_device *, int *);
  96. + int (*set_trips) (struct thermal_zone_device *, int, int);
  97. int (*get_mode) (struct thermal_zone_device *,
  98. enum thermal_device_mode *);
  99. int (*set_mode) (struct thermal_zone_device *,
  100. @@ -184,6 +185,8 @@ struct thermal_zone_device {
  101. int last_temperature;
  102. int emul_temperature;
  103. int passive;
  104. + int prev_low_trip;
  105. + int prev_high_trip;
  106. unsigned int forced_passive;
  107. atomic_t need_update;
  108. const struct thermal_zone_device_ops *ops;