mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
efc5be2ecf
Rework tsens driver. Since in the new kernel 5.4 init common do more than it should, inizialize the kernel memory directly in the driver and drop use of this function. Rework all the patch with the new variable names. Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
438 lines
13 KiB
Diff
438 lines
13 KiB
Diff
From 4e87400732c77765afae2ea89ed43837457aa604 Mon Sep 17 00:00:00 2001
|
|
From: Rajith Cherian <rajith@codeaurora.org>
|
|
Date: Wed, 1 Feb 2017 19:00:26 +0530
|
|
Subject: [PATCH] ipq8064: tsens: Support for configurable interrupts
|
|
|
|
Provide support for adding configurable high and
|
|
configurable low trip temperatures. An interrupts is
|
|
also triggerred when these trip points are hit. The
|
|
interrupts can be activated or deactivated from sysfs.
|
|
This functionality is made available only if
|
|
CONFIG_THERMAL_WRITABLE_TRIPS is defined.
|
|
|
|
Change-Id: Ib73f3f9459de4fffce7bb985a0312a88291f4934
|
|
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
|
|
---
|
|
.../devicetree/bindings/thermal/qcom-tsens.txt | 4 ++
|
|
drivers/thermal/of-thermal.c | 63 ++++++++++++++++++----
|
|
drivers/thermal/qcom/tsens.c | 43 ++++++++++++---
|
|
drivers/thermal/qcom/tsens.h | 11 ++++
|
|
drivers/thermal/thermal_core.c | 44 ++++++++++++++-
|
|
include/linux/thermal.h | 14 +++++
|
|
6 files changed, 162 insertions(+), 17 deletions(-)
|
|
|
|
--- a/drivers/thermal/of-thermal.c
|
|
+++ b/drivers/thermal/of-thermal.c
|
|
@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct th
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (!data->ops->get_temp)
|
|
+ if (!data->ops->get_temp || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EINVAL;
|
|
|
|
return data->ops->get_temp(data->sensor_data, temp);
|
|
@@ -102,7 +102,8 @@ static int of_thermal_set_trips(struct t
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (!data->ops || !data->ops->set_trips)
|
|
+ if (!data->ops || !data->ops->set_trips
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EINVAL;
|
|
|
|
return data->ops->set_trips(data->sensor_data, low, high);
|
|
@@ -188,6 +189,9 @@ static int of_thermal_set_emul_temp(stru
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
+ if (data->mode == THERMAL_DEVICE_DISABLED)
|
|
+ return -EINVAL;
|
|
+
|
|
return data->ops->set_emul_temp(data->sensor_data, temp);
|
|
}
|
|
|
|
@@ -196,7 +200,7 @@ static int of_thermal_get_trend(struct t
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (!data->ops->get_trend)
|
|
+ if (!data->ops->get_trend || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EINVAL;
|
|
|
|
return data->ops->get_trend(data->sensor_data, trip, trend);
|
|
@@ -297,7 +301,9 @@ static int of_thermal_set_mode(struct th
|
|
mutex_unlock(&tz->lock);
|
|
|
|
data->mode = mode;
|
|
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
|
|
+
|
|
+ if (mode == THERMAL_DEVICE_ENABLED)
|
|
+ thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
|
|
|
|
return 0;
|
|
}
|
|
@@ -307,7 +313,8 @@ static int of_thermal_get_trip_type(stru
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (trip >= data->ntrips || trip < 0)
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EDOM;
|
|
|
|
*type = data->trips[trip].type;
|
|
@@ -315,12 +322,39 @@ static int of_thermal_get_trip_type(stru
|
|
return 0;
|
|
}
|
|
|
|
+static int of_thermal_activate_trip_type(struct thermal_zone_device *tz,
|
|
+ int trip, enum thermal_trip_activation_mode mode)
|
|
+{
|
|
+ struct __thermal_zone *data = tz->devdata;
|
|
+
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
+ return -EDOM;
|
|
+
|
|
+ /*
|
|
+ * The configurable_hi and configurable_lo trip points can be
|
|
+ * activated and deactivated.
|
|
+ */
|
|
+
|
|
+ if (data->ops->set_trip_activate) {
|
|
+ int ret;
|
|
+
|
|
+ ret = data->ops->set_trip_activate(data->sensor_data,
|
|
+ trip, mode);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
|
|
int *temp)
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (trip >= data->ntrips || trip < 0)
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EDOM;
|
|
|
|
*temp = data->trips[trip].temperature;
|
|
@@ -333,7 +367,8 @@ static int of_thermal_set_trip_temp(stru
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (trip >= data->ntrips || trip < 0)
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EDOM;
|
|
|
|
if (data->ops->set_trip_temp) {
|
|
@@ -355,7 +390,8 @@ static int of_thermal_get_trip_hyst(stru
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (trip >= data->ntrips || trip < 0)
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EDOM;
|
|
|
|
*hyst = data->trips[trip].hysteresis;
|
|
@@ -368,7 +404,8 @@ static int of_thermal_set_trip_hyst(stru
|
|
{
|
|
struct __thermal_zone *data = tz->devdata;
|
|
|
|
- if (trip >= data->ntrips || trip < 0)
|
|
+ if (trip >= data->ntrips || trip < 0
|
|
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
|
return -EDOM;
|
|
|
|
/* thermal framework should take care of data->mask & (1 << trip) */
|
|
@@ -443,6 +480,9 @@ thermal_zone_of_add_sensor(struct device
|
|
if (ops->set_emul_temp)
|
|
tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
|
|
|
|
+ if (ops->set_trip_activate)
|
|
+ tzd->ops->set_trip_activate = of_thermal_activate_trip_type;
|
|
+
|
|
mutex_unlock(&tzd->lock);
|
|
|
|
return tzd;
|
|
@@ -762,7 +802,10 @@ static const char * const trip_types[] =
|
|
[THERMAL_TRIP_ACTIVE] = "active",
|
|
[THERMAL_TRIP_PASSIVE] = "passive",
|
|
[THERMAL_TRIP_HOT] = "hot",
|
|
- [THERMAL_TRIP_CRITICAL] = "critical",
|
|
+ [THERMAL_TRIP_CRITICAL] = "critical_high",
|
|
+ [THERMAL_TRIP_CONFIGURABLE_HI] = "configurable_hi",
|
|
+ [THERMAL_TRIP_CONFIGURABLE_LOW] = "configurable_lo",
|
|
+ [THERMAL_TRIP_CRITICAL_LOW] = "critical_low",
|
|
};
|
|
|
|
/**
|
|
--- a/drivers/thermal/qcom/tsens.c
|
|
+++ b/drivers/thermal/qcom/tsens.c
|
|
@@ -22,7 +22,7 @@ static int tsens_get_temp(void *data, in
|
|
|
|
static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
|
|
{
|
|
- const struct tsens_sensor *s = data;
|
|
+ struct tsens_sensor *s = data;
|
|
struct tsens_priv *priv = s->priv;
|
|
|
|
if (priv->ops->get_trend)
|
|
@@ -31,9 +31,10 @@ static int tsens_get_trend(void *data, i
|
|
return -ENOTSUPP;
|
|
}
|
|
|
|
-static int __maybe_unused tsens_suspend(struct device *dev)
|
|
+static int __maybe_unused tsens_suspend(void *data)
|
|
{
|
|
- struct tsens_priv *priv = dev_get_drvdata(dev);
|
|
+ struct tsens_sensor *s = data;
|
|
+ struct tsens_priv *priv = s->priv;
|
|
|
|
if (priv->ops && priv->ops->suspend)
|
|
return priv->ops->suspend(priv);
|
|
@@ -41,9 +42,10 @@ static int __maybe_unused tsens_suspend
|
|
return 0;
|
|
}
|
|
|
|
-static int __maybe_unused tsens_resume(struct device *dev)
|
|
+static int __maybe_unused tsens_resume(void *data)
|
|
{
|
|
- struct tsens_priv *priv = dev_get_drvdata(dev);
|
|
+ struct tsens_sensor *s = data;
|
|
+ struct tsens_priv *priv = s->priv;
|
|
|
|
if (priv->ops && priv->ops->resume)
|
|
return priv->ops->resume(priv);
|
|
@@ -51,6 +53,30 @@ static int __maybe_unused tsens_resume(s
|
|
return 0;
|
|
}
|
|
|
|
+static int __maybe_unused tsens_set_trip_temp(void *data, int trip, int temp)
|
|
+{
|
|
+ struct tsens_sensor *s = data;
|
|
+ struct tsens_priv *priv = s->priv;
|
|
+
|
|
+ if (priv->ops && priv->ops->set_trip_temp)
|
|
+ return priv->ops->set_trip_temp(s, trip, temp);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int __maybe_unused tsens_activate_trip_type(void *data, int trip,
|
|
+ enum thermal_trip_activation_mode mode)
|
|
+{
|
|
+ struct tsens_sensor *s = data;
|
|
+ struct tsens_priv *priv = s->priv;
|
|
+
|
|
+ if (priv->ops && priv->ops->set_trip_activate)
|
|
+ return priv->ops->set_trip_activate(s, trip, mode);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
|
|
|
|
static const struct of_device_id tsens_table[] = {
|
|
@@ -80,6 +106,8 @@ MODULE_DEVICE_TABLE(of, tsens_table);
|
|
static const struct thermal_zone_of_device_ops tsens_of_ops = {
|
|
.get_temp = tsens_get_temp,
|
|
.get_trend = tsens_get_trend,
|
|
+ .set_trip_temp = tsens_set_trip_temp,
|
|
+ .set_trip_activate = tsens_activate_trip_type,
|
|
};
|
|
|
|
static int tsens_register(struct tsens_priv *priv)
|
|
@@ -123,7 +151,7 @@ static int tsens_probe(struct platform_d
|
|
if (id)
|
|
data = id->data;
|
|
else
|
|
- data = &data_8960;
|
|
+ return -EINVAL;
|
|
|
|
num_sensors = data->num_sensors;
|
|
|
|
@@ -144,6 +172,9 @@ static int tsens_probe(struct platform_d
|
|
priv->dev = dev;
|
|
priv->num_sensors = num_sensors;
|
|
priv->ops = data->ops;
|
|
+
|
|
+ priv->tsens_irq = platform_get_irq(pdev, 0);
|
|
+
|
|
for (i = 0; i < priv->num_sensors; i++) {
|
|
if (data->hw_ids)
|
|
priv->sensor[i].hw_id = data->hw_ids[i];
|
|
--- a/drivers/thermal/qcom/tsens.h
|
|
+++ b/drivers/thermal/qcom/tsens.h
|
|
@@ -40,9 +40,12 @@ enum tsens_ver {
|
|
struct tsens_sensor {
|
|
struct tsens_priv *priv;
|
|
struct thermal_zone_device *tzd;
|
|
+ struct work_struct notify_work;
|
|
int offset;
|
|
unsigned int id;
|
|
unsigned int hw_id;
|
|
+ int calib_data;
|
|
+ int calib_data_backup;
|
|
int slope;
|
|
u32 status;
|
|
};
|
|
@@ -57,6 +60,9 @@ struct tsens_sensor {
|
|
* @suspend: Function to suspend the tsens device
|
|
* @resume: Function to resume the tsens device
|
|
* @get_trend: Function to get the thermal/temp trend
|
|
+ * @set_trip_temp: Function to set trip temp
|
|
+ * @get_trip_temp: Function to get trip temp
|
|
+ * @set_trip_activate: Function to activate trip points
|
|
*/
|
|
struct tsens_ops {
|
|
/* mandatory callbacks */
|
|
@@ -69,6 +75,9 @@ struct tsens_ops {
|
|
int (*suspend)(struct tsens_priv *priv);
|
|
int (*resume)(struct tsens_priv *priv);
|
|
int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
|
|
+ int (*set_trip_temp)(void *data, int trip, int temp);
|
|
+ int (*set_trip_activate)(void *data, int trip,
|
|
+ enum thermal_trip_activation_mode mode);
|
|
};
|
|
|
|
#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
|
|
@@ -300,6 +309,7 @@ struct tsens_context {
|
|
struct tsens_priv {
|
|
struct device *dev;
|
|
u32 num_sensors;
|
|
+ u32 tsens_irq;
|
|
struct regmap *tm_map;
|
|
struct regmap *srot_map;
|
|
u32 tm_offset;
|
|
@@ -308,6 +318,7 @@ struct tsens_priv {
|
|
const struct tsens_features *feat;
|
|
const struct reg_field *fields;
|
|
const struct tsens_ops *ops;
|
|
+ struct work_struct tsens_work;
|
|
struct tsens_sensor sensor[0];
|
|
};
|
|
|
|
--- a/drivers/thermal/thermal_sysfs.c
|
|
+++ b/drivers/thermal/thermal_sysfs.c
|
|
@@ -113,12 +113,48 @@ trip_point_type_show(struct device *dev,
|
|
return sprintf(buf, "passive\n");
|
|
case THERMAL_TRIP_ACTIVE:
|
|
return sprintf(buf, "active\n");
|
|
+ case THERMAL_TRIP_CONFIGURABLE_HI:
|
|
+ return sprintf(buf, "configurable_hi\n");
|
|
+ case THERMAL_TRIP_CONFIGURABLE_LOW:
|
|
+ return sprintf(buf, "configurable_low\n");
|
|
+ case THERMAL_TRIP_CRITICAL_LOW:
|
|
+ return sprintf(buf, "critical_low\n");
|
|
default:
|
|
return sprintf(buf, "unknown\n");
|
|
}
|
|
}
|
|
|
|
static ssize_t
|
|
+trip_point_type_activate(struct device *dev, struct device_attribute *attr,
|
|
+ const char *buf, size_t count)
|
|
+{
|
|
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
|
|
+ int trip, ret;
|
|
+ char *enabled = "enabled";
|
|
+ char *disabled = "disabled";
|
|
+
|
|
+ if (!tz->ops->set_trip_activate)
|
|
+ return -EPERM;
|
|
+
|
|
+ if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (!strncmp(buf, enabled, strlen(enabled)))
|
|
+ ret = tz->ops->set_trip_activate(tz, trip,
|
|
+ THERMAL_TRIP_ACTIVATION_ENABLED);
|
|
+ else if (!strncmp(buf, disabled, strlen(disabled)))
|
|
+ ret = tz->ops->set_trip_activate(tz, trip,
|
|
+ THERMAL_TRIP_ACTIVATION_DISABLED);
|
|
+ else
|
|
+ ret = -EINVAL;
|
|
+
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static ssize_t
|
|
trip_point_temp_store(struct device *dev, struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
@@ -559,6 +595,12 @@ static int create_trip_attrs(struct ther
|
|
tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
|
|
attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
|
|
|
|
+ if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS)) {
|
|
+ tz->trip_type_attrs[indx].attr.store
|
|
+ = trip_point_type_activate;
|
|
+ tz->trip_type_attrs[indx].attr.attr.mode |= S_IWUSR;
|
|
+ }
|
|
+
|
|
/* create trip temp attribute */
|
|
snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
|
|
"trip_point_%d_temp", indx);
|
|
--- a/include/linux/thermal.h
|
|
+++ b/include/linux/thermal.h
|
|
@@ -63,11 +63,19 @@ enum thermal_device_mode {
|
|
THERMAL_DEVICE_ENABLED,
|
|
};
|
|
|
|
+enum thermal_trip_activation_mode {
|
|
+ THERMAL_TRIP_ACTIVATION_DISABLED = 0,
|
|
+ THERMAL_TRIP_ACTIVATION_ENABLED,
|
|
+};
|
|
+
|
|
enum thermal_trip_type {
|
|
THERMAL_TRIP_ACTIVE = 0,
|
|
THERMAL_TRIP_PASSIVE,
|
|
THERMAL_TRIP_HOT,
|
|
THERMAL_TRIP_CRITICAL,
|
|
+ THERMAL_TRIP_CONFIGURABLE_HI,
|
|
+ THERMAL_TRIP_CONFIGURABLE_LOW,
|
|
+ THERMAL_TRIP_CRITICAL_LOW,
|
|
};
|
|
|
|
enum thermal_trend {
|
|
@@ -105,6 +113,8 @@ struct thermal_zone_device_ops {
|
|
enum thermal_trip_type *);
|
|
int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
|
|
int (*set_trip_temp) (struct thermal_zone_device *, int, int);
|
|
+ int (*set_trip_activate) (struct thermal_zone_device *, int,
|
|
+ enum thermal_trip_activation_mode);
|
|
int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
|
|
int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
|
|
int (*get_crit_temp) (struct thermal_zone_device *, int *);
|
|
@@ -349,6 +359,8 @@ struct thermal_genl_event {
|
|
* temperature.
|
|
* @set_trip_temp: a pointer to a function that sets the trip temperature on
|
|
* hardware.
|
|
+ * @activate_trip_type: a pointer to a function to enable/disable trip
|
|
+ * temperature interrupts
|
|
*/
|
|
struct thermal_zone_of_device_ops {
|
|
int (*get_temp)(void *, int *);
|
|
@@ -356,6 +368,8 @@ struct thermal_zone_of_device_ops {
|
|
int (*set_trips)(void *, int, int);
|
|
int (*set_emul_temp)(void *, int);
|
|
int (*set_trip_temp)(void *, int, int);
|
|
+ int (*set_trip_activate)(void *, int,
|
|
+ enum thermal_trip_activation_mode);
|
|
};
|
|
|
|
/**
|