thermal: core: Store zone trips table in struct thermal_zone_device
The current code expects thermal zone creators to pass a pointer to a writable trips table to thermal_zone_device_register_with_trips() and that trips table is then used by the thermal core going forward. Consequently, the callers of thermal_zone_device_register_with_trips() are required to hold on to the trips table passed to it until the given thermal zone is unregistered, at which point the trips table can be freed, but at the same time they are not expected to access that table directly. This is both error prone and confusing. To address it, turn the trips table pointer in struct thermal_zone_device into a flex array (counted by its num_trips field), allocate it during thermal zone device allocation and copy the contents of the trips table supplied by the zone creator (which can be const now) into it, which will allow the callers of thermal_zone_device_register_with_trips() to drop their trip tables right after the zone registration. This requires the imx thermal driver to be adjusted to store the new temperature in its internal trips table in imx_set_trip_temp(), because it will be separate from the core's trips table now and it has to be explicitly kept in sync with the latter. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
This commit is contained in:
parent
2c8459a568
commit
9b0a627586
5 changed files with 18 additions and 17 deletions
|
@ -354,6 +354,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
imx_set_alarm_temp(data, temp);
|
imx_set_alarm_temp(data, temp);
|
||||||
|
trips[IMX_TRIP_PASSIVE].temperature = temp;
|
||||||
|
|
||||||
pm_runtime_put(data->dev);
|
pm_runtime_put(data->dev);
|
||||||
|
|
||||||
|
|
|
@ -1227,9 +1227,6 @@ int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp)
|
||||||
if (tz->ops->get_crit_temp)
|
if (tz->ops->get_crit_temp)
|
||||||
return tz->ops->get_crit_temp(tz, temp);
|
return tz->ops->get_crit_temp(tz, temp);
|
||||||
|
|
||||||
if (!tz->trips)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mutex_lock(&tz->lock);
|
mutex_lock(&tz->lock);
|
||||||
|
|
||||||
for (i = 0; i < tz->num_trips; i++) {
|
for (i = 0; i < tz->num_trips; i++) {
|
||||||
|
@ -1272,10 +1269,13 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp);
|
||||||
* IS_ERR*() helpers.
|
* IS_ERR*() helpers.
|
||||||
*/
|
*/
|
||||||
struct thermal_zone_device *
|
struct thermal_zone_device *
|
||||||
thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask,
|
thermal_zone_device_register_with_trips(const char *type,
|
||||||
void *devdata, struct thermal_zone_device_ops *ops,
|
const struct thermal_trip *trips,
|
||||||
const struct thermal_zone_params *tzp, int passive_delay,
|
int num_trips, int mask,
|
||||||
int polling_delay)
|
void *devdata,
|
||||||
|
struct thermal_zone_device_ops *ops,
|
||||||
|
const struct thermal_zone_params *tzp,
|
||||||
|
int passive_delay, int polling_delay)
|
||||||
{
|
{
|
||||||
struct thermal_zone_device *tz;
|
struct thermal_zone_device *tz;
|
||||||
int id;
|
int id;
|
||||||
|
@ -1322,7 +1322,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
|
||||||
if (!thermal_class)
|
if (!thermal_class)
|
||||||
return ERR_PTR(-ENODEV);
|
return ERR_PTR(-ENODEV);
|
||||||
|
|
||||||
tz = kzalloc(sizeof(*tz), GFP_KERNEL);
|
tz = kzalloc(struct_size(tz, trips, num_trips), GFP_KERNEL);
|
||||||
if (!tz)
|
if (!tz)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
@ -1354,7 +1354,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
|
||||||
tz->ops = ops;
|
tz->ops = ops;
|
||||||
tz->device.class = thermal_class;
|
tz->device.class = thermal_class;
|
||||||
tz->devdata = devdata;
|
tz->devdata = devdata;
|
||||||
tz->trips = trips;
|
memcpy(tz->trips, trips, num_trips * sizeof(*trips));
|
||||||
tz->num_trips = num_trips;
|
tz->num_trips = num_trips;
|
||||||
|
|
||||||
thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
|
thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
|
||||||
|
|
|
@ -438,12 +438,10 @@ static int thermal_of_unbind(struct thermal_zone_device *tz,
|
||||||
*/
|
*/
|
||||||
static void thermal_of_zone_unregister(struct thermal_zone_device *tz)
|
static void thermal_of_zone_unregister(struct thermal_zone_device *tz)
|
||||||
{
|
{
|
||||||
struct thermal_trip *trips = tz->trips;
|
|
||||||
struct thermal_zone_device_ops *ops = tz->ops;
|
struct thermal_zone_device_ops *ops = tz->ops;
|
||||||
|
|
||||||
thermal_zone_device_disable(tz);
|
thermal_zone_device_disable(tz);
|
||||||
thermal_zone_device_unregister(tz);
|
thermal_zone_device_unregister(tz);
|
||||||
kfree(trips);
|
|
||||||
kfree(ops);
|
kfree(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,6 +524,8 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *
|
||||||
goto out_kfree_trips;
|
goto out_kfree_trips;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree(trips);
|
||||||
|
|
||||||
ret = thermal_zone_device_enable(tz);
|
ret = thermal_zone_device_enable(tz);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n",
|
pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n",
|
||||||
|
|
|
@ -122,7 +122,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||||
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id,
|
||||||
struct thermal_trip *trip)
|
struct thermal_trip *trip)
|
||||||
{
|
{
|
||||||
if (!tz || !tz->trips || trip_id < 0 || trip_id >= tz->num_trips || !trip)
|
if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*trip = tz->trips[trip_id];
|
*trip = tz->trips[trip_id];
|
||||||
|
|
|
@ -130,7 +130,6 @@ struct thermal_cooling_device {
|
||||||
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
|
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
|
||||||
* @mode: current mode of this thermal zone
|
* @mode: current mode of this thermal zone
|
||||||
* @devdata: private pointer for device private data
|
* @devdata: private pointer for device private data
|
||||||
* @trips: an array of struct thermal_trip
|
|
||||||
* @num_trips: number of trip points the thermal zone supports
|
* @num_trips: number of trip points the thermal zone supports
|
||||||
* @passive_delay_jiffies: number of jiffies to wait between polls when
|
* @passive_delay_jiffies: number of jiffies to wait between polls when
|
||||||
* performing passive cooling.
|
* performing passive cooling.
|
||||||
|
@ -160,6 +159,7 @@ struct thermal_cooling_device {
|
||||||
* @poll_queue: delayed work for polling
|
* @poll_queue: delayed work for polling
|
||||||
* @notify_event: Last notification event
|
* @notify_event: Last notification event
|
||||||
* @suspended: thermal zone suspend indicator
|
* @suspended: thermal zone suspend indicator
|
||||||
|
* @trips: array of struct thermal_trip objects
|
||||||
*/
|
*/
|
||||||
struct thermal_zone_device {
|
struct thermal_zone_device {
|
||||||
int id;
|
int id;
|
||||||
|
@ -172,7 +172,6 @@ struct thermal_zone_device {
|
||||||
struct thermal_attr *trip_hyst_attrs;
|
struct thermal_attr *trip_hyst_attrs;
|
||||||
enum thermal_device_mode mode;
|
enum thermal_device_mode mode;
|
||||||
void *devdata;
|
void *devdata;
|
||||||
struct thermal_trip *trips;
|
|
||||||
int num_trips;
|
int num_trips;
|
||||||
unsigned long passive_delay_jiffies;
|
unsigned long passive_delay_jiffies;
|
||||||
unsigned long polling_delay_jiffies;
|
unsigned long polling_delay_jiffies;
|
||||||
|
@ -193,10 +192,11 @@ struct thermal_zone_device {
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct delayed_work poll_queue;
|
struct delayed_work poll_queue;
|
||||||
enum thermal_notify_event notify_event;
|
enum thermal_notify_event notify_event;
|
||||||
|
bool suspended;
|
||||||
#ifdef CONFIG_THERMAL_DEBUGFS
|
#ifdef CONFIG_THERMAL_DEBUGFS
|
||||||
struct thermal_debugfs *debugfs;
|
struct thermal_debugfs *debugfs;
|
||||||
#endif
|
#endif
|
||||||
bool suspended;
|
struct thermal_trip trips[] __counted_by(num_trips);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,7 +315,7 @@ int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp);
|
||||||
#ifdef CONFIG_THERMAL
|
#ifdef CONFIG_THERMAL
|
||||||
struct thermal_zone_device *thermal_zone_device_register_with_trips(
|
struct thermal_zone_device *thermal_zone_device_register_with_trips(
|
||||||
const char *type,
|
const char *type,
|
||||||
struct thermal_trip *trips,
|
const struct thermal_trip *trips,
|
||||||
int num_trips, int mask,
|
int num_trips, int mask,
|
||||||
void *devdata,
|
void *devdata,
|
||||||
struct thermal_zone_device_ops *ops,
|
struct thermal_zone_device_ops *ops,
|
||||||
|
@ -375,7 +375,7 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz);
|
||||||
#else
|
#else
|
||||||
static inline struct thermal_zone_device *thermal_zone_device_register_with_trips(
|
static inline struct thermal_zone_device *thermal_zone_device_register_with_trips(
|
||||||
const char *type,
|
const char *type,
|
||||||
struct thermal_trip *trips,
|
const struct thermal_trip *trips,
|
||||||
int num_trips, int mask,
|
int num_trips, int mask,
|
||||||
void *devdata,
|
void *devdata,
|
||||||
struct thermal_zone_device_ops *ops,
|
struct thermal_zone_device_ops *ops,
|
||||||
|
|
Loading…
Add table
Reference in a new issue