mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 06:33:34 +00:00
Merge back thermal core material for 6.12.
This commit is contained in:
commit
5ae98b5a9f
@ -459,14 +459,7 @@ are supposed to implement the callback. If they don't, the thermal
|
||||
framework calculated the trend by comparing the previous and the current
|
||||
temperature values.
|
||||
|
||||
4.2. get_thermal_instance
|
||||
-------------------------
|
||||
|
||||
This function returns the thermal_instance corresponding to a given
|
||||
{thermal_zone, cooling_device, trip_point} combination. Returns NULL
|
||||
if such an instance does not exist.
|
||||
|
||||
4.3. thermal_cdev_update
|
||||
4.2. thermal_cdev_update
|
||||
------------------------
|
||||
|
||||
This function serves as an arbitrator to set the state of a cooling
|
||||
|
@ -208,8 +208,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
*/
|
||||
val = readl(data->regs + BCM2835_TS_TSENSCTL);
|
||||
if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
|
||||
struct thermal_trip trip;
|
||||
int offset, slope;
|
||||
int offset, slope, crit_temp;
|
||||
|
||||
slope = thermal_zone_get_slope(tz);
|
||||
offset = thermal_zone_get_offset(tz);
|
||||
@ -217,7 +216,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
* For now we deal only with critical, otherwise
|
||||
* would need to iterate
|
||||
*/
|
||||
err = thermal_zone_get_trip(tz, 0, &trip);
|
||||
err = thermal_zone_get_crit_temp(tz, &crit_temp);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Not able to read trip_temp: %d\n", err);
|
||||
return err;
|
||||
@ -232,7 +231,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
val |= (0xFE << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
|
||||
|
||||
/* trip_adc value from info */
|
||||
val |= bcm2835_thermal_temp2adc(trip.temperature,
|
||||
val |= bcm2835_thermal_temp2adc(crit_temp,
|
||||
offset,
|
||||
slope)
|
||||
<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;
|
||||
|
@ -465,11 +465,22 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int hisi_trip_walk_cb(struct thermal_trip *trip, void *arg)
|
||||
{
|
||||
struct hisi_thermal_sensor *sensor = arg;
|
||||
|
||||
if (trip->type != THERMAL_TRIP_PASSIVE)
|
||||
return 0;
|
||||
|
||||
sensor->thres_temp = trip->temperature;
|
||||
/* Return nonzero to terminate the search. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
||||
struct hisi_thermal_sensor *sensor)
|
||||
{
|
||||
int ret, i;
|
||||
struct thermal_trip trip;
|
||||
int ret;
|
||||
|
||||
sensor->tzd = devm_thermal_of_zone_register(&pdev->dev,
|
||||
sensor->id, sensor,
|
||||
@ -482,15 +493,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < thermal_zone_get_num_trips(sensor->tzd); i++) {
|
||||
|
||||
thermal_zone_get_trip(sensor->tzd, i, &trip);
|
||||
|
||||
if (trip.type == THERMAL_TRIP_PASSIVE) {
|
||||
sensor->thres_temp = trip.temperature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
thermal_zone_for_each_trip(sensor->tzd, hisi_trip_walk_cb, sensor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -291,24 +291,6 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip)
|
||||
{
|
||||
struct thermal_trip trip;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < thermal_zone_get_num_trips(chip->tz_dev); i++) {
|
||||
|
||||
ret = thermal_zone_get_trip(chip->tz_dev, i, &trip);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL)
|
||||
return trip.temperature;
|
||||
}
|
||||
|
||||
return THERMAL_TEMP_INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function initializes the internal temp value based on only the
|
||||
* current thermal stage and threshold. Setup threshold control and
|
||||
@ -343,7 +325,9 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip)
|
||||
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
crit_temp = qpnp_tm_get_critical_trip_temp(chip);
|
||||
ret = thermal_zone_get_crit_temp(chip->tz_dev, &crit_temp);
|
||||
if (ret)
|
||||
crit_temp = THERMAL_TEMP_INVALID;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
|
@ -563,11 +563,7 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
|
||||
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);
|
||||
dev_info(dev, "Sensor %u: Loaded\n", i);
|
||||
}
|
||||
|
||||
if (!priv->num_tscs) {
|
||||
|
@ -682,24 +682,25 @@ static const struct thermal_zone_device_ops tegra_of_thermal_ops = {
|
||||
.set_trips = tegra_thermctl_set_trips,
|
||||
};
|
||||
|
||||
static int get_hot_temp(struct thermal_zone_device *tz, int *trip_id, int *temp)
|
||||
static int get_hot_trip_cb(struct thermal_trip *trip, void *arg)
|
||||
{
|
||||
int i, ret;
|
||||
struct thermal_trip trip;
|
||||
const struct thermal_trip **trip_ret = arg;
|
||||
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tz); i++) {
|
||||
if (trip->type != THERMAL_TRIP_HOT)
|
||||
return 0;
|
||||
|
||||
ret = thermal_zone_get_trip(tz, i, &trip);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
*trip_ret = trip;
|
||||
/* Return nonzero to terminate the search. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (trip.type == THERMAL_TRIP_HOT) {
|
||||
*trip_id = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static const struct thermal_trip *get_hot_trip(struct thermal_zone_device *tz)
|
||||
{
|
||||
const struct thermal_trip *trip = NULL;
|
||||
|
||||
return -EINVAL;
|
||||
thermal_zone_for_each_trip(tz, get_hot_trip_cb, &trip);
|
||||
|
||||
return trip;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -731,8 +732,9 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
|
||||
struct thermal_zone_device *tz)
|
||||
{
|
||||
struct tegra_soctherm *ts = dev_get_drvdata(dev);
|
||||
const struct thermal_trip *hot_trip;
|
||||
struct soctherm_throt_cfg *stc;
|
||||
int i, trip, temperature, ret;
|
||||
int i, temperature, ret;
|
||||
|
||||
/* Get thermtrips. If missing, try to get critical trips. */
|
||||
temperature = tsensor_group_thermtrip_get(ts, sg->id);
|
||||
@ -749,8 +751,8 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
|
||||
dev_info(dev, "thermtrip: will shut down when %s reaches %d mC\n",
|
||||
sg->name, temperature);
|
||||
|
||||
ret = get_hot_temp(tz, &trip, &temperature);
|
||||
if (ret) {
|
||||
hot_trip = get_hot_trip(tz);
|
||||
if (!hot_trip) {
|
||||
dev_info(dev, "throttrip: %s: missing hot temperature\n",
|
||||
sg->name);
|
||||
return 0;
|
||||
@ -763,7 +765,7 @@ static int tegra_soctherm_set_hwtrips(struct device *dev,
|
||||
continue;
|
||||
|
||||
cdev = ts->throt_cfgs[i].cdev;
|
||||
if (get_thermal_instance(tz, cdev, trip))
|
||||
if (thermal_trip_is_bound_to_cdev(tz, hot_trip, cdev))
|
||||
stc = find_throttle_cfg_by_name(ts, cdev->type);
|
||||
else
|
||||
continue;
|
||||
|
@ -303,33 +303,37 @@ static int tegra_tsensor_disable_hw_channel(const struct tegra_tsensor *ts,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
|
||||
int *hot_trip, int *crit_trip)
|
||||
{
|
||||
unsigned int i;
|
||||
struct trip_temps {
|
||||
int hot_trip;
|
||||
int crit_trip;
|
||||
};
|
||||
|
||||
static int tegra_tsensor_get_trips_cb(struct thermal_trip *trip, void *arg)
|
||||
{
|
||||
struct trip_temps *temps = arg;
|
||||
|
||||
if (trip->type == THERMAL_TRIP_HOT)
|
||||
temps->hot_trip = trip->temperature;
|
||||
else if (trip->type == THERMAL_TRIP_CRITICAL)
|
||||
temps->crit_trip = trip->temperature;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
|
||||
struct trip_temps *temps)
|
||||
{
|
||||
/*
|
||||
* 90C is the maximal critical temperature of all Tegra30 SoC variants,
|
||||
* use it for the default trip if unspecified in a device-tree.
|
||||
*/
|
||||
*hot_trip = 85000;
|
||||
*crit_trip = 90000;
|
||||
temps->hot_trip = 85000;
|
||||
temps->crit_trip = 90000;
|
||||
|
||||
for (i = 0; i < thermal_zone_get_num_trips(tzd); i++) {
|
||||
|
||||
struct thermal_trip trip;
|
||||
|
||||
thermal_zone_get_trip(tzd, i, &trip);
|
||||
|
||||
if (trip.type == THERMAL_TRIP_HOT)
|
||||
*hot_trip = trip.temperature;
|
||||
|
||||
if (trip.type == THERMAL_TRIP_CRITICAL)
|
||||
*crit_trip = trip.temperature;
|
||||
}
|
||||
thermal_zone_for_each_trip(tzd, tegra_tsensor_get_trips_cb, temps);
|
||||
|
||||
/* clamp hardware trips to the calibration limits */
|
||||
*hot_trip = clamp(*hot_trip, 25000, 90000);
|
||||
temps->hot_trip = clamp(temps->hot_trip, 25000, 90000);
|
||||
|
||||
/*
|
||||
* Kernel will perform a normal system shut down if it will
|
||||
@ -338,7 +342,7 @@ static void tegra_tsensor_get_hw_channel_trips(struct thermal_zone_device *tzd,
|
||||
* shut down gracefully before sending signal to the Power
|
||||
* Management controller.
|
||||
*/
|
||||
*crit_trip = clamp(*crit_trip + 5000, 25000, 90000);
|
||||
temps->crit_trip = clamp(temps->crit_trip + 5000, 25000, 90000);
|
||||
}
|
||||
|
||||
static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts,
|
||||
@ -346,7 +350,8 @@ static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts,
|
||||
{
|
||||
const struct tegra_tsensor_channel *tsc = &ts->ch[id];
|
||||
struct thermal_zone_device *tzd = tsc->tzd;
|
||||
int err, hot_trip = 0, crit_trip = 0;
|
||||
struct trip_temps temps = { 0 };
|
||||
int err;
|
||||
u32 val;
|
||||
|
||||
if (!tzd) {
|
||||
@ -357,24 +362,24 @@ static int tegra_tsensor_enable_hw_channel(const struct tegra_tsensor *ts,
|
||||
return 0;
|
||||
}
|
||||
|
||||
tegra_tsensor_get_hw_channel_trips(tzd, &hot_trip, &crit_trip);
|
||||
tegra_tsensor_get_hw_channel_trips(tzd, &temps);
|
||||
|
||||
dev_info_once(ts->dev, "ch%u: PMC emergency shutdown trip set to %dC\n",
|
||||
id, DIV_ROUND_CLOSEST(crit_trip, 1000));
|
||||
id, DIV_ROUND_CLOSEST(temps.crit_trip, 1000));
|
||||
|
||||
hot_trip = tegra_tsensor_temp_to_counter(ts, hot_trip);
|
||||
crit_trip = tegra_tsensor_temp_to_counter(ts, crit_trip);
|
||||
temps.hot_trip = tegra_tsensor_temp_to_counter(ts, temps.hot_trip);
|
||||
temps.crit_trip = tegra_tsensor_temp_to_counter(ts, temps.crit_trip);
|
||||
|
||||
/* program LEVEL2 counter threshold */
|
||||
val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG1);
|
||||
val &= ~TSENSOR_SENSOR0_CONFIG1_TH2;
|
||||
val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG1_TH2, hot_trip);
|
||||
val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG1_TH2, temps.hot_trip);
|
||||
writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG1);
|
||||
|
||||
/* program LEVEL3 counter threshold */
|
||||
val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG2);
|
||||
val &= ~TSENSOR_SENSOR0_CONFIG2_TH3;
|
||||
val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG2_TH3, crit_trip);
|
||||
val |= FIELD_PREP(TSENSOR_SENSOR0_CONFIG2_TH3, temps.crit_trip);
|
||||
writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG2);
|
||||
|
||||
/*
|
||||
|
@ -15,8 +15,20 @@
|
||||
#include "thermal_netlink.h"
|
||||
#include "thermal_debugfs.h"
|
||||
|
||||
struct thermal_attr {
|
||||
struct device_attribute attr;
|
||||
char name[THERMAL_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct thermal_trip_attrs {
|
||||
struct thermal_attr type;
|
||||
struct thermal_attr temp;
|
||||
struct thermal_attr hyst;
|
||||
};
|
||||
|
||||
struct thermal_trip_desc {
|
||||
struct thermal_trip trip;
|
||||
struct thermal_trip_attrs trip_attrs;
|
||||
struct list_head notify_list_node;
|
||||
int notify_temp;
|
||||
int threshold;
|
||||
@ -56,9 +68,6 @@ struct thermal_governor {
|
||||
* @device: &struct device for this thermal zone
|
||||
* @removal: removal completion
|
||||
* @resume: resume completion
|
||||
* @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
|
||||
* @trip_type_attrs: attributes for trip points for sysfs: trip type
|
||||
* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
|
||||
* @mode: current mode of this thermal zone
|
||||
* @devdata: private pointer for device private data
|
||||
* @num_trips: number of trip points the thermal zone supports
|
||||
@ -102,9 +111,6 @@ struct thermal_zone_device {
|
||||
struct completion removal;
|
||||
struct completion resume;
|
||||
struct attribute_group trips_attribute_group;
|
||||
struct thermal_attr *trip_temp_attrs;
|
||||
struct thermal_attr *trip_type_attrs;
|
||||
struct thermal_attr *trip_hyst_attrs;
|
||||
enum thermal_device_mode mode;
|
||||
void *devdata;
|
||||
int num_trips;
|
||||
@ -188,11 +194,6 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
|
||||
|
||||
struct thermal_zone_device *thermal_zone_get_by_id(int id);
|
||||
|
||||
struct thermal_attr {
|
||||
struct device_attribute attr;
|
||||
char name[THERMAL_NAME_LENGTH];
|
||||
};
|
||||
|
||||
static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
|
||||
{
|
||||
return cdev->ops->get_requested_power && cdev->ops->state2power &&
|
||||
@ -204,11 +205,6 @@ void __thermal_cdev_update(struct thermal_cooling_device *cdev);
|
||||
|
||||
int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip);
|
||||
|
||||
struct thermal_instance *
|
||||
get_thermal_instance(struct thermal_zone_device *tz,
|
||||
struct thermal_cooling_device *cdev,
|
||||
int trip);
|
||||
|
||||
/*
|
||||
* This structure is used to describe the behavior of
|
||||
* a certain cooling device on a certain trip point
|
||||
@ -262,11 +258,11 @@ 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);
|
||||
void thermal_zone_trip_updated(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip);
|
||||
int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
|
||||
void thermal_zone_trip_down(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip);
|
||||
void thermal_zone_set_trip_hyst(struct thermal_zone_device *tz,
|
||||
struct thermal_trip *trip, int hyst);
|
||||
|
||||
/* sysfs I/F */
|
||||
int thermal_zone_create_device_groups(struct thermal_zone_device *tz);
|
||||
|
@ -39,18 +39,18 @@ 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)
|
||||
static bool thermal_instance_present(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 true;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
|
||||
@ -62,7 +62,7 @@ bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
|
||||
mutex_lock(&tz->lock);
|
||||
mutex_lock(&cdev->lock);
|
||||
|
||||
ret = !!get_instance(tz, cdev, trip);
|
||||
ret = thermal_instance_present(tz, cdev, trip);
|
||||
|
||||
mutex_unlock(&cdev->lock);
|
||||
mutex_unlock(&tz->lock);
|
||||
@ -71,24 +71,6 @@ bool thermal_trip_is_bound_to_cdev(struct thermal_zone_device *tz,
|
||||
}
|
||||
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 *ti;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
mutex_lock(&cdev->lock);
|
||||
|
||||
ti = get_instance(tz, cdev, &tz->trips[trip_index].trip);
|
||||
|
||||
mutex_unlock(&cdev->lock);
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
return ti;
|
||||
}
|
||||
EXPORT_SYMBOL(get_thermal_instance);
|
||||
|
||||
/**
|
||||
* __thermal_zone_get_temp() - returns the temperature of a thermal zone
|
||||
* @tz: a valid pointer to a struct thermal_zone_device
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@ -78,39 +79,38 @@ mode_store(struct device *dev, struct device_attribute *attr,
|
||||
return count;
|
||||
}
|
||||
|
||||
#define thermal_trip_of_attr(_ptr_, _attr_) \
|
||||
({ \
|
||||
struct thermal_trip_desc *td; \
|
||||
\
|
||||
td = container_of(_ptr_, struct thermal_trip_desc, \
|
||||
trip_attrs._attr_.attr); \
|
||||
&td->trip; \
|
||||
})
|
||||
|
||||
static ssize_t
|
||||
trip_point_type_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip_id;
|
||||
struct thermal_trip *trip = thermal_trip_of_attr(attr, type);
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%s\n", thermal_trip_type_name(tz->trips[trip_id].trip.type));
|
||||
return sprintf(buf, "%s\n", thermal_trip_type_name(trip->type));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
trip_point_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_trip *trip = thermal_trip_of_attr(attr, temp);
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
struct thermal_trip *trip;
|
||||
int trip_id, ret;
|
||||
int temp;
|
||||
int ret, temp;
|
||||
|
||||
ret = kstrtoint(buf, 10, &temp);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
trip = &tz->trips[trip_id].trip;
|
||||
|
||||
if (temp != trip->temperature) {
|
||||
if (tz->ops.set_trip_temp) {
|
||||
ret = tz->ops.set_trip_temp(tz, trip, temp);
|
||||
@ -133,39 +133,29 @@ static ssize_t
|
||||
trip_point_temp_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip_id;
|
||||
struct thermal_trip *trip = thermal_trip_of_attr(attr, temp);
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature));
|
||||
return sprintf(buf, "%d\n", READ_ONCE(trip->temperature));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst);
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
struct thermal_trip *trip;
|
||||
int trip_id, ret;
|
||||
int hyst;
|
||||
int ret, hyst;
|
||||
|
||||
ret = kstrtoint(buf, 10, &hyst);
|
||||
if (ret || hyst < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
trip = &tz->trips[trip_id].trip;
|
||||
|
||||
if (hyst != trip->hysteresis) {
|
||||
WRITE_ONCE(trip->hysteresis, hyst);
|
||||
thermal_zone_set_trip_hyst(tz, trip, hyst);
|
||||
|
||||
thermal_zone_trip_updated(tz, trip);
|
||||
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
|
||||
}
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
@ -177,13 +167,9 @@ static ssize_t
|
||||
trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
int trip_id;
|
||||
struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst);
|
||||
|
||||
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis));
|
||||
return sprintf(buf, "%d\n", READ_ONCE(trip->hysteresis));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -382,87 +368,55 @@ static const struct attribute_group *thermal_zone_attribute_groups[] = {
|
||||
*/
|
||||
static int create_trip_attrs(struct thermal_zone_device *tz)
|
||||
{
|
||||
const struct thermal_trip_desc *td;
|
||||
struct thermal_trip_desc *td;
|
||||
struct attribute **attrs;
|
||||
|
||||
/* This function works only for zones with at least one trip */
|
||||
if (tz->num_trips <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
tz->trip_type_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_type_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_type_attrs)
|
||||
return -ENOMEM;
|
||||
|
||||
tz->trip_temp_attrs = kcalloc(tz->num_trips, sizeof(*tz->trip_temp_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_temp_attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tz->trip_hyst_attrs = kcalloc(tz->num_trips,
|
||||
sizeof(*tz->trip_hyst_attrs),
|
||||
GFP_KERNEL);
|
||||
if (!tz->trip_hyst_attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
|
||||
attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
|
||||
if (!attrs) {
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
if (!attrs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for_each_trip_desc(tz, td) {
|
||||
int indx = thermal_zone_trip_id(tz, &td->trip);
|
||||
struct thermal_trip_attrs *trip_attrs = &td->trip_attrs;
|
||||
|
||||
/* create trip type attribute */
|
||||
snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_type", indx);
|
||||
snprintf(trip_attrs->type.name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_type", i);
|
||||
|
||||
sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
|
||||
tz->trip_type_attrs[indx].attr.attr.name =
|
||||
tz->trip_type_attrs[indx].name;
|
||||
tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
|
||||
tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
|
||||
attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
|
||||
sysfs_attr_init(&trip_attrs->type.attr.attr);
|
||||
trip_attrs->type.attr.attr.name = trip_attrs->type.name;
|
||||
trip_attrs->type.attr.attr.mode = S_IRUGO;
|
||||
trip_attrs->type.attr.show = trip_point_type_show;
|
||||
attrs[i] = &trip_attrs->type.attr.attr;
|
||||
|
||||
/* create trip temp attribute */
|
||||
snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_temp", indx);
|
||||
snprintf(trip_attrs->temp.name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_temp", i);
|
||||
|
||||
sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
|
||||
tz->trip_temp_attrs[indx].attr.attr.name =
|
||||
tz->trip_temp_attrs[indx].name;
|
||||
tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
|
||||
tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
|
||||
sysfs_attr_init(&trip_attrs->temp.attr.attr);
|
||||
trip_attrs->temp.attr.attr.name = trip_attrs->temp.name;
|
||||
trip_attrs->temp.attr.attr.mode = S_IRUGO;
|
||||
trip_attrs->temp.attr.show = trip_point_temp_show;
|
||||
if (td->trip.flags & THERMAL_TRIP_FLAG_RW_TEMP) {
|
||||
tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
|
||||
tz->trip_temp_attrs[indx].attr.store =
|
||||
trip_point_temp_store;
|
||||
trip_attrs->temp.attr.attr.mode |= S_IWUSR;
|
||||
trip_attrs->temp.attr.store = trip_point_temp_store;
|
||||
}
|
||||
attrs[indx + tz->num_trips] = &tz->trip_temp_attrs[indx].attr.attr;
|
||||
attrs[i + tz->num_trips] = &trip_attrs->temp.attr.attr;
|
||||
|
||||
snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_hyst", indx);
|
||||
snprintf(trip_attrs->hyst.name, THERMAL_NAME_LENGTH,
|
||||
"trip_point_%d_hyst", i);
|
||||
|
||||
sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
|
||||
tz->trip_hyst_attrs[indx].attr.attr.name =
|
||||
tz->trip_hyst_attrs[indx].name;
|
||||
tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
|
||||
tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
|
||||
sysfs_attr_init(&trip_attrs->hyst.attr.attr);
|
||||
trip_attrs->hyst.attr.attr.name = trip_attrs->hyst.name;
|
||||
trip_attrs->hyst.attr.attr.mode = S_IRUGO;
|
||||
trip_attrs->hyst.attr.show = trip_point_hyst_show;
|
||||
if (td->trip.flags & THERMAL_TRIP_FLAG_RW_HYST) {
|
||||
tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
|
||||
tz->trip_hyst_attrs[indx].attr.store =
|
||||
trip_point_hyst_store;
|
||||
trip_attrs->hyst.attr.attr.mode |= S_IWUSR;
|
||||
trip_attrs->hyst.attr.store = trip_point_hyst_store;
|
||||
}
|
||||
attrs[indx + tz->num_trips * 2] =
|
||||
&tz->trip_hyst_attrs[indx].attr.attr;
|
||||
attrs[i + 2 * tz->num_trips] = &trip_attrs->hyst.attr.attr;
|
||||
i++;
|
||||
}
|
||||
attrs[tz->num_trips * 3] = NULL;
|
||||
|
||||
@ -479,13 +433,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
|
||||
*/
|
||||
static void destroy_trip_attrs(struct thermal_zone_device *tz)
|
||||
{
|
||||
if (!tz)
|
||||
return;
|
||||
|
||||
kfree(tz->trip_type_attrs);
|
||||
kfree(tz->trip_temp_attrs);
|
||||
kfree(tz->trip_hyst_attrs);
|
||||
kfree(tz->trips_attribute_group.attrs);
|
||||
if (tz)
|
||||
kfree(tz->trips_attribute_group.attrs);
|
||||
}
|
||||
|
||||
int thermal_zone_create_device_groups(struct thermal_zone_device *tz)
|
||||
|
@ -55,12 +55,6 @@ int thermal_zone_for_each_trip(struct thermal_zone_device *tz,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_for_each_trip);
|
||||
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz)
|
||||
{
|
||||
return tz->num_trips;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_num_trips);
|
||||
|
||||
/**
|
||||
* thermal_zone_set_trips - Computes the next trip points for the driver
|
||||
* @tz: a pointer to a thermal zone device structure
|
||||
@ -114,20 +108,6 @@ 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 || trip_id < 0 || trip_id >= tz->num_trips)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
*trip = tz->trips[trip_id].trip;
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_trip);
|
||||
|
||||
int thermal_zone_trip_id(const struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
{
|
||||
@ -138,11 +118,11 @@ int thermal_zone_trip_id(const struct thermal_zone_device *tz,
|
||||
return trip_to_trip_desc(trip) - tz->trips;
|
||||
}
|
||||
|
||||
void thermal_zone_trip_updated(struct thermal_zone_device *tz,
|
||||
const struct thermal_trip *trip)
|
||||
void thermal_zone_set_trip_hyst(struct thermal_zone_device *tz,
|
||||
struct thermal_trip *trip, int hyst)
|
||||
{
|
||||
WRITE_ONCE(trip->hysteresis, hyst);
|
||||
thermal_notify_tz_trip_change(tz, trip);
|
||||
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
|
||||
}
|
||||
|
||||
void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
|
||||
|
@ -203,15 +203,12 @@ 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 for_each_thermal_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data);
|
||||
int thermal_zone_for_each_trip(struct thermal_zone_device *tz,
|
||||
int (*cb)(struct thermal_trip *, void *),
|
||||
void *data);
|
||||
int thermal_zone_get_num_trips(struct thermal_zone_device *tz);
|
||||
void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
|
||||
struct thermal_trip *trip, int temp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user