Merge "thermal: tsens: Update TSENS driver" into msm-4.9
diff --git a/Documentation/devicetree/bindings/thermal/tsens.txt b/Documentation/devicetree/bindings/thermal/tsens.txt
index 1065456..3e59c43 100644
--- a/Documentation/devicetree/bindings/thermal/tsens.txt
+++ b/Documentation/devicetree/bindings/thermal/tsens.txt
@@ -21,34 +21,25 @@
The compatible property is used to identify the respective controller to use
for the corresponding SoC.
- reg : offset and length of the TSENS registers with associated property in reg-names
- as "tsens_physical" for TSENS TM physical address region.
+ as "tsens_srot_physical" for TSENS SROT physical address region. TSENS TM
+ physical address region as "tsens_tm_physical".
- reg-names : resource names used for the physical address of the TSENS
- registers. Should be "tsens_physical" for physical address of the TSENS.
+ registers. Should be "tsens_srot_physical" for physical address of the TSENS
+ SROT region and "tsens_tm_physical" for physical address of the TM region.
- interrupts : TSENS interrupt to notify Upper/Lower and Critical temperature threshold.
- interrupt-names: Should be "tsens-upper-lower" for temperature threshold.
Add "tsens-critical" for Critical temperature threshold notification
in addition to "tsens-upper-lower" for 8996 TSENS since
8996 supports Upper/Lower and Critical temperature threshold.
-- qcom,sensors : Total number of available Temperature sensors for TSENS.
-
-Optional properties:
-- qcom,sensor-id : If the flag is present map the TSENS sensors based on the
- remote sensors that are enabled in HW. Ensure the mapping is not
- more than the number of supported sensors.
-- qcom,client-id : If the flag is present use it to identify the SW ID mapping
- used to associate it with the controller and the physical sensor
- mapping within the controller. The physical sensor mapping within
- each controller is done using the qcom,sensor-id property. If the
- property is not present the SW ID mapping with default from 0 to
- total number of supported sensors with each controller instance.
Example:
tsens@fc4a8000 {
compatible = "qcom,msm-tsens";
- reg = <0xfc4a8000 0x2000>;,
- reg-names = "tsens_physical";
+ reg = <0xfc4a8000 0x10>,
+ <0xfc4b8000 0x1ff>;
+ reg-names = "tsens_srot_physical",
+ "tsens_tm_physical";
interrupts = <0 184 0>;
interrupt-names = "tsens-upper-lower";
- qcom,sensors = <11>;
};
diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c
index 2013e7e..432adbc 100644
--- a/drivers/thermal/msm-tsens.c
+++ b/drivers/thermal/msm-tsens.c
@@ -24,29 +24,28 @@
LIST_HEAD(tsens_device_list);
-static int tsens_get_temp(struct tsens_sensor *s, int *temp)
+static int tsens_get_temp(void *data, int *temp)
{
+ struct tsens_sensor *s = data;
struct tsens_device *tmdev = s->tmdev;
return tmdev->ops->get_temp(s, temp);
}
-static int tsens_set_trip_temp(struct tsens_sensor *s, int trip, int temp)
+static int tsens_set_trip_temp(void *data, int low_temp, int high_temp)
{
+ struct tsens_sensor *s = data;
struct tsens_device *tmdev = s->tmdev;
- if (tmdev->ops->set_trip_temp)
- return tmdev->ops->set_trip_temp(s, trip, temp);
+ if (tmdev->ops->set_trips)
+ return tmdev->ops->set_trips(s, low_temp, high_temp);
return 0;
}
static int tsens_init(struct tsens_device *tmdev)
{
- if (tmdev->ops->hw_init)
- return tmdev->ops->hw_init(tmdev);
-
- return 0;
+ return tmdev->ops->hw_init(tmdev);
}
static int tsens_register_interrupts(struct tsens_device *tmdev)
@@ -85,19 +84,16 @@ MODULE_DEVICE_TABLE(of, tsens_table);
static struct thermal_zone_of_device_ops tsens_tm_thermal_zone_ops = {
.get_temp = tsens_get_temp,
- .set_trip_temp = tsens_set_trip_temp,
+ .set_trips = tsens_set_trip_temp,
};
static int get_device_tree_data(struct platform_device *pdev,
struct tsens_device *tmdev)
{
struct device_node *of_node = pdev->dev.of_node;
- u32 *hw_id, *client_id;
- u32 rc = 0, i, tsens_num_sensors = 0;
- int tsens_len;
const struct of_device_id *id;
const struct tsens_data *data;
- struct resource *res_tsens_mem, *res_mem = NULL;
+ struct resource *res_tsens_mem;
if (!of_match_node(tsens_table, of_node)) {
pr_err("Need to read SoC specific fuse map\n");
@@ -111,16 +107,6 @@ static int get_device_tree_data(struct platform_device *pdev,
}
data = id->data;
- hw_id = devm_kzalloc(&pdev->dev,
- tsens_num_sensors * sizeof(u32), GFP_KERNEL);
- if (!hw_id)
- return -ENOMEM;
-
- client_id = devm_kzalloc(&pdev->dev,
- tsens_num_sensors * sizeof(u32), GFP_KERNEL);
- if (!client_id)
- return -ENOMEM;
-
tmdev->ops = data->ops;
tmdev->ctrl_data = data;
tmdev->pdev = pdev;
@@ -132,49 +118,32 @@ static int get_device_tree_data(struct platform_device *pdev,
/* TSENS register region */
res_tsens_mem = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "tsens_physical");
+ IORESOURCE_MEM, "tsens_srot_physical");
if (!res_tsens_mem) {
pr_err("Could not get tsens physical address resource\n");
return -EINVAL;
}
- tsens_len = res_tsens_mem->end - res_tsens_mem->start + 1;
+ tmdev->tsens_srot_addr = devm_ioremap_resource(&pdev->dev,
+ res_tsens_mem);
+ if (IS_ERR(tmdev->tsens_srot_addr)) {
+ dev_err(&pdev->dev, "Failed to IO map TSENS registers.\n");
+ return PTR_ERR(tmdev->tsens_srot_addr);
+ }
- res_mem = request_mem_region(res_tsens_mem->start,
- tsens_len, res_tsens_mem->name);
- if (!res_mem) {
- pr_err("Request tsens physical memory region failed\n");
+ /* TSENS TM register region */
+ res_tsens_mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "tsens_tm_physical");
+ if (!res_tsens_mem) {
+ pr_err("Could not get tsens physical address resource\n");
return -EINVAL;
}
- tmdev->tsens_addr = ioremap(res_mem->start, tsens_len);
- if (!tmdev->tsens_addr) {
- pr_err("Failed to IO map TSENS registers.\n");
- return -EINVAL;
- }
-
- rc = of_property_read_u32_array(of_node,
- "qcom,sensor-id", hw_id, tsens_num_sensors);
- if (rc) {
- pr_err("Default sensor id mapping\n");
- for (i = 0; i < tsens_num_sensors; i++)
- tmdev->sensor[i].hw_id = i;
- } else {
- pr_err("Use specified sensor id mapping\n");
- for (i = 0; i < tsens_num_sensors; i++)
- tmdev->sensor[i].hw_id = hw_id[i];
- }
-
- rc = of_property_read_u32_array(of_node,
- "qcom,client-id", client_id, tsens_num_sensors);
- if (rc) {
- for (i = 0; i < tsens_num_sensors; i++)
- tmdev->sensor[i].id = i;
- pr_debug("Default client id mapping\n");
- } else {
- for (i = 0; i < tsens_num_sensors; i++)
- tmdev->sensor[i].id = client_id[i];
- pr_debug("Use specified client id mapping\n");
+ tmdev->tsens_tm_addr = devm_ioremap_resource(&pdev->dev,
+ res_tsens_mem);
+ if (IS_ERR(tmdev->tsens_tm_addr)) {
+ dev_err(&pdev->dev, "Failed to IO map TSENS TM registers.\n");
+ return PTR_ERR(tmdev->tsens_tm_addr);
}
return 0;
@@ -182,20 +151,28 @@ static int get_device_tree_data(struct platform_device *pdev,
static int tsens_thermal_zone_register(struct tsens_device *tmdev)
{
- int rc = 0, i = 0;
+ int i = 0, sensor_missing = 0;
- for (i = 0; i < tmdev->num_sensors; i++) {
+ for (i = 0; i < TSENS_MAX_SENSORS; i++) {
tmdev->sensor[i].tmdev = tmdev;
- tmdev->sensor[i].tzd = devm_thermal_zone_of_sensor_register(
- &tmdev->pdev->dev, i, &tmdev->sensor[i],
- &tsens_tm_thermal_zone_ops);
+ tmdev->sensor[i].hw_id = i;
+ tmdev->sensor[i].tzd =
+ devm_thermal_zone_of_sensor_register(
+ &tmdev->pdev->dev, i,
+ &tmdev->sensor[i], &tsens_tm_thermal_zone_ops);
if (IS_ERR(tmdev->sensor[i].tzd)) {
- pr_err("Error registering sensor:%d\n", i);
+ pr_debug("Error registering sensor:%d\n", i);
+ sensor_missing++;
continue;
}
}
- return rc;
+ if (sensor_missing == TSENS_MAX_SENSORS) {
+ pr_err("No TSENS sensors to register?\n");
+ return -ENODEV;
+ }
+
+ return 0;
}
static int tsens_tm_remove(struct platform_device *pdev)
@@ -207,32 +184,19 @@ static int tsens_tm_remove(struct platform_device *pdev)
int tsens_tm_probe(struct platform_device *pdev)
{
- struct device_node *of_node = pdev->dev.of_node;
struct tsens_device *tmdev = NULL;
- u32 tsens_num_sensors = 0;
int rc;
if (!(pdev->dev.of_node))
return -ENODEV;
- rc = of_property_read_u32(of_node,
- "qcom,sensors", &tsens_num_sensors);
- if (rc || (!tsens_num_sensors)) {
- dev_err(&pdev->dev, "missing sensors\n");
- return -ENODEV;
- }
-
tmdev = devm_kzalloc(&pdev->dev,
sizeof(struct tsens_device) +
- tsens_num_sensors *
+ TSENS_MAX_SENSORS *
sizeof(struct tsens_sensor),
GFP_KERNEL);
- if (tmdev == NULL) {
- pr_err("%s: kzalloc() failed.\n", __func__);
+ if (tmdev == NULL)
return -ENOMEM;
- }
-
- tmdev->num_sensors = tsens_num_sensors;
rc = get_device_tree_data(pdev, tmdev);
if (rc) {
@@ -241,8 +205,10 @@ int tsens_tm_probe(struct platform_device *pdev)
}
rc = tsens_init(tmdev);
- if (rc)
+ if (rc) {
+ pr_err("Error initializing TSENS controller\n");
return rc;
+ }
rc = tsens_thermal_zone_register(tmdev);
if (rc) {
diff --git a/drivers/thermal/tsens.h b/drivers/thermal/tsens.h
index b9ebb65..3b9b01a 100644
--- a/drivers/thermal/tsens.h
+++ b/drivers/thermal/tsens.h
@@ -23,9 +23,9 @@
#define DEBUG_SIZE 10
#define TSENS_MAX_SENSORS 16
-#define TSENS_CONTROLLER_ID(n) ((n) + 0x1000)
+#define TSENS_CONTROLLER_ID(n) (n)
#define TSENS_CTRL_ADDR(n) (n)
-#define TSENS_TM_SN_STATUS(n) ((n) + 0x10a0)
+#define TSENS_TM_SN_STATUS(n) ((n) + 0xa0)
enum tsens_dbg_type {
TSENS_DBG_POLL,
@@ -87,7 +87,7 @@ struct tsens_sensor {
struct tsens_ops {
int (*hw_init)(struct tsens_device *);
int (*get_temp)(struct tsens_sensor *, int *);
- int (*set_trip_temp)(struct tsens_sensor *, int, int);
+ int (*set_trips)(struct tsens_sensor *, int, int);
int (*interrupts_reg)(struct tsens_device *);
int (*dbg)(struct tsens_device *, u32, u32, int *);
};
@@ -121,7 +121,8 @@ struct tsens_device {
u32 num_sensors;
struct regmap *map;
struct regmap_field *status_field;
- void *tsens_addr;
+ void __iomem *tsens_srot_addr;
+ void __iomem *tsens_tm_addr;
const struct tsens_ops *ops;
struct tsens_dbg_context tsens_dbg;
spinlock_t tsens_crit_lock;
diff --git a/drivers/thermal/tsens2xxx.c b/drivers/thermal/tsens2xxx.c
index 1f0bee9..422ed9a 100644
--- a/drivers/thermal/tsens2xxx.c
+++ b/drivers/thermal/tsens2xxx.c
@@ -18,19 +18,20 @@
#include <linux/of.h>
#include <linux/vmalloc.h>
#include "tsens.h"
+#include "thermal_core.h"
#define TSENS_DRIVER_NAME "msm-tsens"
-#define TSENS_TM_INT_EN(n) ((n) + 0x1004)
-#define TSENS_TM_CRITICAL_INT_STATUS(n) ((n) + 0x1014)
-#define TSENS_TM_CRITICAL_INT_CLEAR(n) ((n) + 0x1018)
-#define TSENS_TM_CRITICAL_INT_MASK(n) ((n) + 0x101c)
+#define TSENS_TM_INT_EN(n) ((n) + 0x4)
+#define TSENS_TM_CRITICAL_INT_STATUS(n) ((n) + 0x14)
+#define TSENS_TM_CRITICAL_INT_CLEAR(n) ((n) + 0x18)
+#define TSENS_TM_CRITICAL_INT_MASK(n) ((n) + 0x1c)
#define TSENS_TM_CRITICAL_WD_BARK BIT(31)
#define TSENS_TM_CRITICAL_CYCLE_MONITOR BIT(30)
#define TSENS_TM_CRITICAL_INT_EN BIT(2)
#define TSENS_TM_UPPER_INT_EN BIT(1)
#define TSENS_TM_LOWER_INT_EN BIT(0)
-#define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n) ((n) + 0x1020)
+#define TSENS_TM_SN_UPPER_LOWER_THRESHOLD(n) ((n) + 0x20)
#define TSENS_TM_SN_ADDR_OFFSET 0x4
#define TSENS_TM_UPPER_THRESHOLD_SET(n) ((n) << 12)
#define TSENS_TM_UPPER_THRESHOLD_VALUE_SHIFT(n) ((n) >> 12)
@@ -39,13 +40,13 @@
#define TSENS_TM_UPPER_THRESHOLD_MASK 0xfff000
#define TSENS_TM_LOWER_THRESHOLD_MASK 0xfff
#define TSENS_TM_UPPER_THRESHOLD_SHIFT 12
-#define TSENS_TM_SN_CRITICAL_THRESHOLD(n) ((n) + 0x1060)
+#define TSENS_TM_SN_CRITICAL_THRESHOLD(n) ((n) + 0x60)
#define TSENS_STATUS_ADDR_OFFSET 2
#define TSENS_TM_UPPER_INT_MASK(n) (((n) & 0xffff0000) >> 16)
#define TSENS_TM_LOWER_INT_MASK(n) ((n) & 0xffff)
-#define TSENS_TM_UPPER_LOWER_INT_STATUS(n) ((n) + 0x1008)
-#define TSENS_TM_UPPER_LOWER_INT_CLEAR(n) ((n) + 0x100c)
-#define TSENS_TM_UPPER_LOWER_INT_MASK(n) ((n) + 0x1010)
+#define TSENS_TM_UPPER_LOWER_INT_STATUS(n) ((n) + 0x8)
+#define TSENS_TM_UPPER_LOWER_INT_CLEAR(n) ((n) + 0xc)
+#define TSENS_TM_UPPER_LOWER_INT_MASK(n) ((n) + 0x10)
#define TSENS_TM_UPPER_INT_SET(n) (1 << (n + 16))
#define TSENS_TM_SN_CRITICAL_THRESHOLD_MASK 0xfff
#define TSENS_TM_SN_STATUS_VALID_BIT BIT(21)
@@ -55,6 +56,7 @@
#define TSENS_TM_SN_LAST_TEMP_MASK 0xfff
#define TSENS_TM_CODE_BIT_MASK 0xfff
#define TSENS_TM_CODE_SIGN_BIT 0x800
+#define TSENS_TM_SCALE_DECI_MILLIDEG 100
#define TSENS_EN BIT(0)
@@ -67,7 +69,7 @@ static void msm_tsens_convert_temp(int last_temp, int *temp)
last_temp |= code_mask;
}
- *temp = last_temp * 100;
+ *temp = last_temp * TSENS_TM_SCALE_DECI_MILLIDEG;
}
static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
@@ -81,7 +83,7 @@ static int tsens2xxx_get_temp(struct tsens_sensor *sensor, int *temp)
return -EINVAL;
tmdev = sensor->tmdev;
- sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr);
+ sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_tm_addr);
code = readl_relaxed_no_log(sensor_addr +
(sensor->hw_id << TSENS_STATUS_ADDR_OFFSET));
@@ -130,7 +132,6 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
{
struct tsens_device *tmdev = NULL;
unsigned int reg_cntl, mask;
- unsigned long flags;
int rc = 0;
/* clear the interrupt and unmask */
@@ -141,56 +142,57 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
if (!tmdev)
return -EINVAL;
- spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);
+
mask = (tm_sensor->hw_id);
switch (trip) {
case THERMAL_TRIP_CRITICAL:
tmdev->sensor[tm_sensor->hw_id].
thr_state.crit_th_state = mode;
reg_cntl = readl_relaxed(TSENS_TM_CRITICAL_INT_MASK
- (tmdev->tsens_addr));
+ (tmdev->tsens_tm_addr));
if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
writel_relaxed(reg_cntl | (1 << mask),
(TSENS_TM_CRITICAL_INT_MASK
- (tmdev->tsens_addr)));
+ (tmdev->tsens_tm_addr)));
else
writel_relaxed(reg_cntl & ~(1 << mask),
(TSENS_TM_CRITICAL_INT_MASK
- (tmdev->tsens_addr)));
+ (tmdev->tsens_tm_addr)));
break;
- case THERMAL_TRIP_ACTIVE:
+ case THERMAL_TRIP_CONFIGURABLE_HI:
tmdev->sensor[tm_sensor->hw_id].
thr_state.high_th_state = mode;
reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
- (tmdev->tsens_addr));
+ (tmdev->tsens_tm_addr));
if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
writel_relaxed(reg_cntl |
(TSENS_TM_UPPER_INT_SET(mask)),
(TSENS_TM_UPPER_LOWER_INT_MASK
- (tmdev->tsens_addr)));
+ (tmdev->tsens_tm_addr)));
else
writel_relaxed(reg_cntl &
~(TSENS_TM_UPPER_INT_SET(mask)),
(TSENS_TM_UPPER_LOWER_INT_MASK
- (tmdev->tsens_addr)));
+ (tmdev->tsens_tm_addr)));
break;
- case THERMAL_TRIP_PASSIVE:
+ case THERMAL_TRIP_CONFIGURABLE_LOW:
tmdev->sensor[tm_sensor->hw_id].
thr_state.low_th_state = mode;
reg_cntl = readl_relaxed(TSENS_TM_UPPER_LOWER_INT_MASK
- (tmdev->tsens_addr));
+ (tmdev->tsens_tm_addr));
if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
writel_relaxed(reg_cntl | (1 << mask),
- (TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_addr)));
+ (TSENS_TM_UPPER_LOWER_INT_MASK
+ (tmdev->tsens_tm_addr)));
else
writel_relaxed(reg_cntl & ~(1 << mask),
- (TSENS_TM_UPPER_LOWER_INT_MASK(tmdev->tsens_addr)));
+ (TSENS_TM_UPPER_LOWER_INT_MASK
+ (tmdev->tsens_tm_addr)));
break;
default:
rc = -EINVAL;
}
- spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
/* Activate and enable the respective trip threshold setting */
mb();
@@ -198,14 +200,14 @@ static int tsens_tm_activate_trip_type(struct tsens_sensor *tm_sensor,
}
static int tsens2xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
- int trip, int temp)
+ int low_temp, int high_temp)
{
unsigned int reg_cntl;
unsigned long flags;
struct tsens_device *tmdev = NULL;
int rc = 0;
- if (!tm_sensor || trip < 0)
+ if (!tm_sensor)
return -EINVAL;
tmdev = tm_sensor->tmdev;
@@ -213,56 +215,65 @@ static int tsens2xxx_set_trip_temp(struct tsens_sensor *tm_sensor,
return -EINVAL;
spin_lock_irqsave(&tmdev->tsens_upp_low_lock, flags);
- switch (trip) {
- case THERMAL_TRIP_CRITICAL:
+
+ if (high_temp != INT_MAX) {
tmdev->sensor[tm_sensor->hw_id].
- thr_state.crit_temp = temp;
- temp &= TSENS_TM_SN_CRITICAL_THRESHOLD_MASK;
- writel_relaxed(temp,
- (TSENS_TM_SN_CRITICAL_THRESHOLD(tmdev->tsens_addr) +
- (tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
- break;
- case THERMAL_TRIP_ACTIVE:
- tmdev->sensor[tm_sensor->hw_id].
- thr_state.high_temp = temp;
+ thr_state.high_temp = high_temp;
reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
- (tmdev->tsens_addr)) +
+ (tmdev->tsens_tm_addr)) +
(tm_sensor->hw_id *
TSENS_TM_SN_ADDR_OFFSET));
- temp = TSENS_TM_UPPER_THRESHOLD_SET(temp);
- temp &= TSENS_TM_UPPER_THRESHOLD_MASK;
+ high_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
+ high_temp = TSENS_TM_UPPER_THRESHOLD_SET(high_temp);
+ high_temp &= TSENS_TM_UPPER_THRESHOLD_MASK;
reg_cntl &= ~TSENS_TM_UPPER_THRESHOLD_MASK;
- writel_relaxed(reg_cntl | temp,
- (TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tmdev->tsens_addr) +
+ writel_relaxed(reg_cntl | high_temp,
+ (TSENS_TM_SN_UPPER_LOWER_THRESHOLD
+ (tmdev->tsens_tm_addr) +
(tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
- break;
- case THERMAL_TRIP_PASSIVE:
- tmdev->sensor[tm_sensor->hw_id].
- thr_state.low_temp = temp;
- reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
- (tmdev->tsens_addr)) +
- (tm_sensor->hw_id *
- TSENS_TM_SN_ADDR_OFFSET));
- temp &= TSENS_TM_LOWER_THRESHOLD_MASK;
- reg_cntl &= ~TSENS_TM_LOWER_THRESHOLD_MASK;
- writel_relaxed(reg_cntl | temp,
- (TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tmdev->tsens_addr) +
- (tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
- break;
- default:
- pr_err("Invalid trip to TSENS: %d\n", trip);
- rc = -EINVAL;
}
- spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
+ if (low_temp != INT_MIN) {
+ tmdev->sensor[tm_sensor->hw_id].
+ thr_state.low_temp = low_temp;
+ reg_cntl = readl_relaxed((TSENS_TM_SN_UPPER_LOWER_THRESHOLD
+ (tmdev->tsens_tm_addr)) +
+ (tm_sensor->hw_id *
+ TSENS_TM_SN_ADDR_OFFSET));
+ low_temp /= TSENS_TM_SCALE_DECI_MILLIDEG;
+ low_temp &= TSENS_TM_LOWER_THRESHOLD_MASK;
+ reg_cntl &= ~TSENS_TM_LOWER_THRESHOLD_MASK;
+ writel_relaxed(reg_cntl | low_temp,
+ (TSENS_TM_SN_UPPER_LOWER_THRESHOLD
+ (tmdev->tsens_tm_addr) +
+ (tm_sensor->hw_id * TSENS_TM_SN_ADDR_OFFSET)));
+ }
+
/* Set trip temperature thresholds */
mb();
- rc = tsens_tm_activate_trip_type(tm_sensor, trip,
+ if (high_temp != INT_MAX) {
+ rc = tsens_tm_activate_trip_type(tm_sensor,
+ THERMAL_TRIP_CONFIGURABLE_HI,
THERMAL_TRIP_ACTIVATION_ENABLED);
- if (rc)
- pr_err("Error during trip activation :%d\n", rc);
+ if (rc) {
+ pr_err("Error during trip high activation :%d\n", rc);
+ goto fail;
+ }
+ }
+ if (low_temp != INT_MIN) {
+ rc = tsens_tm_activate_trip_type(tm_sensor,
+ THERMAL_TRIP_CONFIGURABLE_LOW,
+ THERMAL_TRIP_ACTIVATION_ENABLED);
+ if (rc) {
+ pr_err("Error during trip low activation :%d\n", rc);
+ goto fail;
+ }
+ }
+
+fail:
+ spin_unlock_irqrestore(&tmdev->tsens_upp_low_lock, flags);
return rc;
}
@@ -277,13 +288,13 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
void __iomem *wd_critical_addr;
int wd_mask;
- sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_addr);
+ sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
sensor_int_mask_addr =
- TSENS_TM_CRITICAL_INT_MASK(tm->tsens_addr);
+ TSENS_TM_CRITICAL_INT_MASK(tm->tsens_tm_addr);
sensor_critical_addr =
- TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_addr);
+ TSENS_TM_SN_CRITICAL_THRESHOLD(tm->tsens_tm_addr);
wd_critical_addr =
- TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_addr);
+ TSENS_TM_CRITICAL_INT_STATUS(tm->tsens_tm_addr);
if (tm->ctrl_data->wd_bark) {
wd_mask = readl_relaxed(wd_critical_addr);
@@ -294,19 +305,22 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
*/
writel_relaxed(wd_mask | TSENS_TM_CRITICAL_WD_BARK,
(TSENS_TM_CRITICAL_INT_CLEAR
- (tm->tsens_addr)));
+ (tm->tsens_tm_addr)));
writel_relaxed(wd_mask & ~(TSENS_TM_CRITICAL_WD_BARK),
(TSENS_TM_CRITICAL_INT_CLEAR
- (tm->tsens_addr)));
+ (tm->tsens_tm_addr)));
tm->tsens_dbg.tsens_critical_wd_cnt++;
return IRQ_HANDLED;
}
}
- for (i = 0; i < tm->num_sensors; i++) {
+ for (i = 0; i < TSENS_MAX_SENSORS; i++) {
int int_mask, int_mask_val;
u32 addr_offset;
+ if (IS_ERR(tm->sensor[i].tzd))
+ continue;
+
spin_lock_irqsave(&tm->tsens_crit_lock, flags);
addr_offset = tm->sensor[i].hw_id *
TSENS_TM_SN_ADDR_OFFSET;
@@ -320,13 +334,14 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
/* Mask the corresponding interrupt for the sensors */
writel_relaxed(int_mask | int_mask_val,
TSENS_TM_CRITICAL_INT_MASK(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
/* Clear the corresponding sensors interrupt */
writel_relaxed(int_mask_val,
- TSENS_TM_CRITICAL_INT_CLEAR(tm->tsens_addr));
+ TSENS_TM_CRITICAL_INT_CLEAR
+ (tm->tsens_tm_addr));
writel_relaxed(0,
TSENS_TM_CRITICAL_INT_CLEAR(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
tm->sensor[i].thr_state.
crit_th_state = THERMAL_DEVICE_DISABLED;
}
@@ -342,22 +357,31 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
{
struct tsens_device *tm = data;
- unsigned int i, status, threshold;
+ unsigned int i, status, threshold, temp;
unsigned long flags;
void __iomem *sensor_status_addr;
void __iomem *sensor_int_mask_addr;
void __iomem *sensor_upper_lower_addr;
u32 addr_offset = 0;
- sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_addr);
+ sensor_status_addr = TSENS_TM_SN_STATUS(tm->tsens_tm_addr);
sensor_int_mask_addr =
- TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_addr);
+ TSENS_TM_UPPER_LOWER_INT_MASK(tm->tsens_tm_addr);
sensor_upper_lower_addr =
- TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_addr);
+ TSENS_TM_SN_UPPER_LOWER_THRESHOLD(tm->tsens_tm_addr);
- for (i = 0; i < tm->num_sensors; i++) {
+ for (i = 0; i < TSENS_MAX_SENSORS; i++) {
bool upper_thr = false, lower_thr = false;
- int int_mask, int_mask_val = 0;
+ int int_mask, int_mask_val = 0, rc;
+
+ if (IS_ERR(tm->sensor[i].tzd))
+ continue;
+
+ rc = tsens2xxx_get_temp(&tm->sensor[i], &temp);
+ if (rc) {
+ pr_debug("Error:%d reading temp sensor:%d\n", rc, i);
+ continue;
+ }
spin_lock_irqsave(&tm->tsens_upp_low_lock, flags);
addr_offset = tm->sensor[i].hw_id *
@@ -376,17 +400,28 @@ static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
/* Mask the corresponding interrupt for the sensors */
writel_relaxed(int_mask | int_mask_val,
TSENS_TM_UPPER_LOWER_INT_MASK(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
/* Clear the corresponding sensors interrupt */
writel_relaxed(int_mask_val,
TSENS_TM_UPPER_LOWER_INT_CLEAR(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
writel_relaxed(0,
TSENS_TM_UPPER_LOWER_INT_CLEAR(
- tm->tsens_addr));
- upper_thr = true;
- tm->sensor[i].thr_state.
+ tm->tsens_tm_addr));
+ if (TSENS_TM_UPPER_THRESHOLD_VALUE(threshold) >
+ (temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
+ pr_debug("Re-arm high threshold\n");
+ rc = tsens_tm_activate_trip_type(
+ &tm->sensor[i],
+ THERMAL_TRIP_CONFIGURABLE_HI,
+ THERMAL_TRIP_ACTIVATION_ENABLED);
+ if (rc)
+ pr_err("high rearm failed:%d\n", rc);
+ } else {
+ upper_thr = true;
+ tm->sensor[i].thr_state.
high_th_state = THERMAL_DEVICE_DISABLED;
+ }
}
if ((status & TSENS_TM_SN_STATUS_LOWER_STATUS) &&
@@ -397,32 +432,36 @@ static irqreturn_t tsens_tm_irq_thread(int irq, void *data)
/* Mask the corresponding interrupt for the sensors */
writel_relaxed(int_mask | int_mask_val,
TSENS_TM_UPPER_LOWER_INT_MASK(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
/* Clear the corresponding sensors interrupt */
writel_relaxed(int_mask_val,
TSENS_TM_UPPER_LOWER_INT_CLEAR(
- tm->tsens_addr));
+ tm->tsens_tm_addr));
writel_relaxed(0,
TSENS_TM_UPPER_LOWER_INT_CLEAR(
- tm->tsens_addr));
- lower_thr = true;
- tm->sensor[i].thr_state.
+ tm->tsens_tm_addr));
+ if (TSENS_TM_LOWER_THRESHOLD_VALUE(threshold)
+ < (temp/TSENS_TM_SCALE_DECI_MILLIDEG)) {
+ pr_debug("Re-arm low threshold\n");
+ rc = tsens_tm_activate_trip_type(
+ &tm->sensor[i],
+ THERMAL_TRIP_CONFIGURABLE_LOW,
+ THERMAL_TRIP_ACTIVATION_ENABLED);
+ if (rc)
+ pr_err("low rearm failed:%d\n", rc);
+ } else {
+ lower_thr = true;
+ tm->sensor[i].thr_state.
low_th_state = THERMAL_DEVICE_DISABLED;
+ }
}
spin_unlock_irqrestore(&tm->tsens_upp_low_lock, flags);
if (upper_thr || lower_thr) {
- int temp;
- enum thermal_trip_type trip =
- THERMAL_TRIP_CONFIGURABLE_LOW;
-
- if (upper_thr)
- trip = THERMAL_TRIP_CONFIGURABLE_HI;
- tsens2xxx_get_temp(&tm->sensor[i], &temp);
/* Use id for multiple controllers */
pr_debug("sensor:%d trigger temp (%d degC)\n",
- tm->sensor[i].hw_id,
- (status & TSENS_TM_SN_LAST_TEMP_MASK));
+ tm->sensor[i].hw_id, temp);
+ of_thermal_handle_trip(tm->sensor[i].tzd);
}
}
@@ -442,7 +481,7 @@ static int tsens2xxx_hw_init(struct tsens_device *tmdev)
unsigned int srot_val;
int crit_mask;
- srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_addr + 0x4);
+ srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_srot_addr + 0x4);
srot_val = readl_relaxed(srot_addr);
if (!(srot_val & TSENS_EN)) {
pr_err("TSENS device is not enabled\n");
@@ -451,18 +490,18 @@ static int tsens2xxx_hw_init(struct tsens_device *tmdev)
if (tmdev->ctrl_data->cycle_monitor) {
sensor_int_mask_addr =
- TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr);
+ TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_tm_addr);
crit_mask = readl_relaxed(sensor_int_mask_addr);
writel_relaxed(
crit_mask | tmdev->ctrl_data->cycle_compltn_monitor_val,
(TSENS_TM_CRITICAL_INT_MASK
- (tmdev->tsens_addr)));
+ (tmdev->tsens_tm_addr)));
/*Update critical cycle monitoring*/
mb();
}
writel_relaxed(TSENS_TM_CRITICAL_INT_EN |
TSENS_TM_UPPER_INT_EN | TSENS_TM_LOWER_INT_EN,
- TSENS_TM_INT_EN(tmdev->tsens_addr));
+ TSENS_TM_INT_EN(tmdev->tsens_tm_addr));
spin_lock_init(&tmdev->tsens_crit_lock);
spin_lock_init(&tmdev->tsens_upp_low_lock);
@@ -513,7 +552,7 @@ static int tsens2xxx_register_interrupts(struct tsens_device *tmdev)
static const struct tsens_ops ops_tsens2xxx = {
.hw_init = tsens2xxx_hw_init,
.get_temp = tsens2xxx_get_temp,
- .set_trip_temp = tsens2xxx_set_trip_temp,
+ .set_trips = tsens2xxx_set_trip_temp,
.interrupts_reg = tsens2xxx_register_interrupts,
.dbg = tsens2xxx_dbg,
};