ipq806x: fix tsens driver

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>
master
Ansuel Smith 2020-01-26 04:32:45 +01:00 committed by Petr Štetiar
parent c692d896eb
commit efc5be2ecf
5 changed files with 231 additions and 178 deletions

View File

@ -27,11 +27,13 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,2 +1,3 @@
@@ -2,5 +2,5 @@
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
-qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o
+qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o \
+ tsens-ipq8064.o
qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o \
- tsens-8960.o tsens-v2.o tsens-v1.o
+ tsens-8960.o tsens-v2.o tsens-v1.o tsens-ipq8064.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-ipq8064.c
@@ -0,0 +1,551 @@
@ -187,17 +189,17 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ return code;
+}
+
+static int suspend_ipq8064(struct tsens_device *tmdev)
+static int suspend_ipq8064(struct tsens_priv *priv)
+{
+ int ret;
+ unsigned int mask;
+ struct regmap *map = tmdev->map;
+ struct regmap *map = priv->tm_map;
+
+ ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
+ ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control);
+ ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control);
+ if (ret)
+ return ret;
+
@ -210,10 +212,10 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ return 0;
+}
+
+static int resume_ipq8064(struct tsens_device *tmdev)
+static int resume_ipq8064(struct tsens_priv *priv)
+{
+ int ret;
+ struct regmap *map = tmdev->map;
+ struct regmap *map = priv->tm_map;
+
+ ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
+ if (ret)
@ -223,11 +225,11 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ if (ret)
+ return ret;
+
+ ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold);
+ ret = regmap_write(map, THRESHOLD_ADDR, priv->ctx.threshold);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control);
+ ret = regmap_write(map, CNTL_ADDR, priv->ctx.control);
+ if (ret)
+ return ret;
+
@ -244,23 +246,23 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+
+static void tsens_scheduler_fn(struct work_struct *work)
+{
+ struct tsens_device *tmdev = container_of(work, struct tsens_device,
+ struct tsens_priv *priv = container_of(work, struct tsens_priv,
+ tsens_work);
+ unsigned int threshold, threshold_low, code, reg, sensor, mask;
+ unsigned int sensor_addr;
+ bool upper_th_x, lower_th_x;
+ int adc_code, ret;
+
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg);
+ ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
+ if (ret)
+ return;
+ reg = reg | LOWER_STATUS_CLR | UPPER_STATUS_CLR;
+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, reg);
+ ret = regmap_write(priv->tm_map, STATUS_CNTL_8064, reg);
+ if (ret)
+ return;
+
+ mask = ~(LOWER_STATUS_CLR | UPPER_STATUS_CLR);
+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, &threshold);
+ ret = regmap_read(priv->tm_map, THRESHOLD_ADDR, &threshold);
+ if (ret)
+ return;
+ threshold_low = (threshold & THRESHOLD_LOWER_LIMIT_MASK)
@ -268,11 +270,11 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ threshold = (threshold & THRESHOLD_UPPER_LIMIT_MASK)
+ >> THRESHOLD_UPPER_LIMIT_SHIFT;
+
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg);
+ ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
+ if (ret)
+ return;
+
+ ret = regmap_read(tmdev->map, CNTL_ADDR, &sensor);
+ ret = regmap_read(priv->tm_map, CNTL_ADDR, &sensor);
+ if (ret)
+ return;
+ sensor &= (uint32_t) TSENS_8064_SENSORS_EN;
@ -286,7 +288,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+
+ /* Skip if the sensor is disabled */
+ if (sensor & 1) {
+ ret = regmap_read(tmdev->map, tmdev->sensor[0].status, &code);
+ ret = regmap_read(priv->tm_map, priv->sensor[0].status, &code);
+ if (ret)
+ return;
+ upper_th_x = code >= threshold;
@ -297,13 +299,13 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ mask |= LOWER_STATUS_CLR;
+ if (upper_th_x || lower_th_x) {
+ /* Notify user space */
+ schedule_work(&tmdev->sensor[0].notify_work);
+ regmap_read(tmdev->map, sensor_addr, &adc_code);
+ schedule_work(&priv->sensor[0].notify_work);
+ regmap_read(priv->tm_map, sensor_addr, &adc_code);
+ pr_debug("Trigger (%d degrees) for sensor %d\n",
+ code_to_degC(adc_code, &tmdev->sensor[0]), 0);
+ code_to_degC(adc_code, &priv->sensor[0]), 0);
+ }
+ }
+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg & mask);
+ regmap_write(priv->tm_map, STATUS_CNTL_8064, reg & mask);
+
+ /* force memory to sync */
+ mb();
@ -311,59 +313,59 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+
+static irqreturn_t tsens_isr(int irq, void *data)
+{
+ struct tsens_device *tmdev = data;
+ struct tsens_priv *priv = data;
+
+ schedule_work(&tmdev->tsens_work);
+ schedule_work(&priv->tsens_work);
+ return IRQ_HANDLED;
+}
+
+static void hw_init(struct tsens_device *tmdev)
+static void hw_init(struct tsens_priv *priv)
+{
+ int ret;
+ unsigned int reg_cntl = 0, reg_cfg = 0, reg_thr = 0;
+ unsigned int reg_status_cntl = 0;
+
+ regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl);
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl | TSENS_SW_RST);
+ regmap_read(priv->tm_map, CNTL_ADDR, &reg_cntl);
+ regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl | TSENS_SW_RST);
+
+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18)
+ | (((1 << tmdev->num_sensors) - 1) << SENSOR0_SHIFT);
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
+ regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_status_cntl);
+ | (((1 << priv->num_sensors) - 1) << SENSOR0_SHIFT);
+ regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+ regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_status_cntl);
+ reg_status_cntl |= LOWER_STATUS_CLR | UPPER_STATUS_CLR
+ | MIN_STATUS_MASK | MAX_STATUS_MASK;
+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg_status_cntl);
+ regmap_write(priv->tm_map, STATUS_CNTL_8064, reg_status_cntl);
+ reg_cntl |= TSENS_EN;
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
+ regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+
+ regmap_read(tmdev->map, CONFIG_ADDR, &reg_cfg);
+ regmap_read(priv->tm_map, CONFIG_ADDR, &reg_cfg);
+ reg_cfg = (reg_cfg & ~CONFIG_MASK) | (CONFIG << CONFIG_SHIFT);
+ regmap_write(tmdev->map, CONFIG_ADDR, reg_cfg);
+ regmap_write(priv->tm_map, CONFIG_ADDR, reg_cfg);
+
+ reg_thr |= (LOWER_LIMIT_TH << THRESHOLD_LOWER_LIMIT_SHIFT)
+ | (UPPER_LIMIT_TH << THRESHOLD_UPPER_LIMIT_SHIFT)
+ | (MIN_LIMIT_TH << THRESHOLD_MIN_LIMIT_SHIFT)
+ | (MAX_LIMIT_TH << THRESHOLD_MAX_LIMIT_SHIFT);
+
+ regmap_write(tmdev->map, THRESHOLD_ADDR, reg_thr);
+ regmap_write(priv->tm_map, THRESHOLD_ADDR, reg_thr);
+
+ ret = devm_request_irq(tmdev->dev, tmdev->tsens_irq, tsens_isr,
+ IRQF_TRIGGER_RISING, "tsens_interrupt", tmdev);
+ ret = devm_request_irq(priv->dev, priv->tsens_irq, tsens_isr,
+ IRQF_TRIGGER_RISING, "tsens_interrupt", priv);
+ if (ret < 0) {
+ pr_err("%s: request_irq FAIL: %d\n", __func__, ret);
+ return;
+ }
+
+ INIT_WORK(&tmdev->tsens_work, tsens_scheduler_fn);
+ INIT_WORK(&priv->tsens_work, tsens_scheduler_fn);
+}
+
+static int init_ipq8064(struct tsens_device *tmdev)
+static int init_ipq8064(struct tsens_priv *priv)
+{
+ int ret, i;
+ u32 reg_cntl, offset = 0;
+
+ init_common(tmdev);
+ if (!tmdev->map)
+ init_common(priv);
+ if (!priv->tm_map)
+ return -ENODEV;
+
+ /*
@ -372,55 +374,55 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ * but the control registers stay in the same place, i.e
+ * directly after the first 5 status registers.
+ */
+ for (i = 0; i < tmdev->num_sensors; i++) {
+ for (i = 0; i < priv->num_sensors; i++) {
+ if (i >= TSENS_8064_SEQ_SENSORS)
+ offset = TSENS_8064_S4_S5_OFFSET;
+
+ tmdev->sensor[i].status = S0_STATUS_ADDR + offset
+ priv->sensor[i].status = S0_STATUS_ADDR + offset
+ + (i << STATUS_ADDR_OFFSET);
+ tmdev->sensor[i].slope = tsens_8064_slope[i];
+ INIT_WORK(&tmdev->sensor[i].notify_work,
+ priv->sensor[i].slope = tsens_8064_slope[i];
+ INIT_WORK(&priv->sensor[i].notify_work,
+ notify_uspace_tsens_fn);
+ }
+
+ reg_cntl = SW_RST;
+ ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl);
+ ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
+ if (ret)
+ return ret;
+
+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
+ reg_cntl &= ~SW_RST;
+ ret = regmap_update_bits(tmdev->map, CONFIG_ADDR,
+ ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
+ CONFIG_MASK, CONFIG);
+
+ reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
+ reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
+ ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+ if (ret)
+ return ret;
+
+ reg_cntl |= EN;
+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
+ ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int calibrate_ipq8064(struct tsens_device *tmdev)
+static int calibrate_ipq8064(struct tsens_priv *priv)
+{
+ int i;
+ char *data, *data_backup;
+
+ ssize_t num_read = tmdev->num_sensors;
+ struct tsens_sensor *s = tmdev->sensor;
+ ssize_t num_read = priv->num_sensors;
+ struct tsens_sensor *s = priv->sensor;
+
+ data = qfprom_read(tmdev->dev, "calib");
+ data = qfprom_read(priv->dev, "calib");
+ if (IS_ERR(data)) {
+ pr_err("Calibration not found.\n");
+ return PTR_ERR(data);
+ }
+
+ data_backup = qfprom_read(tmdev->dev, "calib_backup");
+ data_backup = qfprom_read(priv->dev, "calib_backup");
+ if (IS_ERR(data_backup)) {
+ pr_err("Backup calibration not found.\n");
+ return PTR_ERR(data_backup);
@ -440,26 +442,26 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
+ }
+
+ hw_init(tmdev);
+ hw_init(priv);
+
+ return 0;
+}
+
+static int get_temp_ipq8064(struct tsens_device *tmdev, int id, int *temp)
+static int get_temp_ipq8064(struct tsens_priv *priv, int id, int *temp)
+{
+ int ret;
+ u32 code, trdy;
+ const struct tsens_sensor *s = &tmdev->sensor[id];
+ const struct tsens_sensor *s = &priv->sensor[id];
+ unsigned long timeout;
+
+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+ do {
+ ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
+ ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
+ if (ret)
+ return ret;
+ if (!(trdy & TRDY_MASK))
+ continue;
+ ret = regmap_read(tmdev->map, s->status, &code);
+ ret = regmap_read(priv->tm_map, s->status, &code);
+ if (ret)
+ return ret;
+ *temp = code_to_degC(code, s);
@ -474,18 +476,18 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ unsigned int reg_th, reg_cntl;
+ int ret, code, code_chk, hi_code, lo_code;
+ const struct tsens_sensor *s = data;
+ struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
+
+ code_chk = code = degC_to_code(temp, s);
+
+ if (code < THRESHOLD_MIN_CODE || code > THRESHOLD_MAX_CODE)
+ return -EINVAL;
+
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_cntl);
+ ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_cntl);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, &reg_th);
+ ret = regmap_read(priv->tm_map, THRESHOLD_ADDR, &reg_th);
+ if (ret)
+ return ret;
+
@ -519,7 +521,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ return -EINVAL;
+ }
+
+ ret = regmap_write(tmdev->map, THRESHOLD_ADDR, reg_th | code);
+ ret = regmap_write(priv->tm_map, THRESHOLD_ADDR, reg_th | code);
+ if (ret)
+ return ret;
+
@ -531,13 +533,13 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+{
+ unsigned int reg_cntl, mask, val;
+ const struct tsens_sensor *s = data;
+ struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
+ int ret;
+
+ if (!tmdev || trip < 0)
+ if (!priv || trip < 0)
+ return -EINVAL;
+
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_cntl);
+ ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg_cntl);
+ if (ret)
+ return ret;
+
@ -563,7 +565,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ else
+ val = reg_cntl & ~mask;
+
+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, val);
+ ret = regmap_write(priv->tm_map, STATUS_CNTL_8064, val);
+ if (ret)
+ return ret;
+
@ -582,13 +584,13 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ .set_trip_activate = set_trip_activate_ipq8064,
+};
+
+const struct tsens_data data_ipq8064 = {
+const struct tsens_plat_data data_ipq8064 = {
+ .num_sensors = 11,
+ .ops = &ops_ipq8064,
+};
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -75,8 +75,11 @@ static const struct of_device_id tsens_t
@@ -69,8 +69,11 @@ static const struct of_device_id tsens_t
}, {
.compatible = "qcom,tsens-v2",
.data = &data_tsens_v2,
@ -603,12 +605,12 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -89,7 +89,7 @@ int init_common(struct tsens_device *);
int get_temp_common(struct tsens_device *, int, int *);
@@ -324,7 +324,7 @@ extern const struct tsens_plat_data data
extern const struct tsens_plat_data data_8916, data_8974;
/* TSENS v1 targets */
-extern const struct tsens_data data_8916, data_8974, data_8960;
+extern const struct tsens_data data_8916, data_8974, data_8960, data_ipq8064;
/* TSENS v2 targets */
extern const struct tsens_data data_8996, data_tsens_v2;
-extern const struct tsens_plat_data data_tsens_v1;
+extern const struct tsens_plat_data data_tsens_v1, data_ipq8064;
/* TSENS v2 targets */
extern const struct tsens_plat_data data_8996, data_tsens_v2;

View File

@ -23,7 +23,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -77,7 +77,7 @@ static int of_thermal_get_temp(struct th
@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct th
{
struct __thermal_zone *data = tz->devdata;
@ -32,7 +32,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EINVAL;
return data->ops->get_temp(data->sensor_data, temp);
@@ -88,7 +88,8 @@ static int of_thermal_set_trips(struct t
@@ -102,7 +102,8 @@ static int of_thermal_set_trips(struct t
{
struct __thermal_zone *data = tz->devdata;
@ -42,7 +42,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EINVAL;
return data->ops->set_trips(data->sensor_data, low, high);
@@ -174,6 +175,9 @@ static int of_thermal_set_emul_temp(stru
@@ -188,6 +189,9 @@ static int of_thermal_set_emul_temp(stru
{
struct __thermal_zone *data = tz->devdata;
@ -52,7 +52,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return data->ops->set_emul_temp(data->sensor_data, temp);
}
@@ -182,7 +186,7 @@ static int of_thermal_get_trend(struct t
@@ -196,7 +200,7 @@ static int of_thermal_get_trend(struct t
{
struct __thermal_zone *data = tz->devdata;
@ -61,7 +61,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EINVAL;
return data->ops->get_trend(data->sensor_data, trip, trend);
@@ -271,7 +275,9 @@ static int of_thermal_set_mode(struct th
@@ -297,7 +301,9 @@ static int of_thermal_set_mode(struct th
mutex_unlock(&tz->lock);
data->mode = mode;
@ -72,7 +72,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return 0;
}
@@ -281,7 +287,8 @@ static int of_thermal_get_trip_type(stru
@@ -307,7 +313,8 @@ static int of_thermal_get_trip_type(stru
{
struct __thermal_zone *data = tz->devdata;
@ -82,7 +82,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EDOM;
*type = data->trips[trip].type;
@@ -289,12 +296,39 @@ static int of_thermal_get_trip_type(stru
@@ -315,12 +322,39 @@ static int of_thermal_get_trip_type(stru
return 0;
}
@ -123,7 +123,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EDOM;
*temp = data->trips[trip].temperature;
@@ -307,7 +341,8 @@ static int of_thermal_set_trip_temp(stru
@@ -333,7 +367,8 @@ static int of_thermal_set_trip_temp(stru
{
struct __thermal_zone *data = tz->devdata;
@ -133,7 +133,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EDOM;
if (data->ops->set_trip_temp) {
@@ -329,7 +364,8 @@ static int of_thermal_get_trip_hyst(stru
@@ -355,7 +390,8 @@ static int of_thermal_get_trip_hyst(stru
{
struct __thermal_zone *data = tz->devdata;
@ -143,7 +143,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EDOM;
*hyst = data->trips[trip].hysteresis;
@@ -342,7 +378,8 @@ static int of_thermal_set_trip_hyst(stru
@@ -368,7 +404,8 @@ static int of_thermal_set_trip_hyst(stru
{
struct __thermal_zone *data = tz->devdata;
@ -153,7 +153,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
return -EDOM;
/* thermal framework should take care of data->mask & (1 << trip) */
@@ -417,6 +454,9 @@ thermal_zone_of_add_sensor(struct device
@@ -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;
@ -163,7 +163,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
mutex_unlock(&tzd->lock);
return tzd;
@@ -711,7 +751,10 @@ static const char * const trip_types[] =
@@ -762,7 +802,10 @@ static const char * const trip_types[] =
[THERMAL_TRIP_ACTIVE] = "active",
[THERMAL_TRIP_PASSIVE] = "passive",
[THERMAL_TRIP_HOT] = "hot",
@ -177,52 +177,52 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
/**
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -31,7 +31,7 @@ static int tsens_get_temp(void *data, in
@@ -22,7 +22,7 @@ static int tsens_get_temp(void *data, in
static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
{
- const struct tsens_sensor *s = p;
+ struct tsens_sensor *s = p;
struct tsens_device *tmdev = s->tmdev;
- const struct tsens_sensor *s = data;
+ struct tsens_sensor *s = data;
struct tsens_priv *priv = s->priv;
if (tmdev->ops->get_trend)
@@ -40,9 +40,10 @@ static int tsens_get_trend(void *p, int
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_device *tmdev = dev_get_drvdata(dev);
- struct tsens_priv *priv = dev_get_drvdata(dev);
+ struct tsens_sensor *s = data;
+ struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
if (tmdev->ops && tmdev->ops->suspend)
return tmdev->ops->suspend(tmdev);
@@ -50,9 +51,10 @@ static int __maybe_unused tsens_suspend
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_device *tmdev = dev_get_drvdata(dev);
- struct tsens_priv *priv = dev_get_drvdata(dev);
+ struct tsens_sensor *s = data;
+ struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
if (tmdev->ops && tmdev->ops->resume)
return tmdev->ops->resume(tmdev);
@@ -60,6 +62,30 @@ static int __maybe_unused tsens_resume(s
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_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
+
+ if (tmdev->ops && tmdev->ops->set_trip_temp)
+ return tmdev->ops->set_trip_temp(s, trip, temp);
+ if (priv->ops && priv->ops->set_trip_temp)
+ return priv->ops->set_trip_temp(s, trip, temp);
+
+ return 0;
+}
@ -231,10 +231,10 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ enum thermal_trip_activation_mode mode)
+{
+ struct tsens_sensor *s = data;
+ struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;
+
+ if (tmdev->ops && tmdev->ops->set_trip_activate)
+ return tmdev->ops->set_trip_activate(s, trip, mode);
+ if (priv->ops && priv->ops->set_trip_activate)
+ return priv->ops->set_trip_activate(s, trip, mode);
+
+ return 0;
+}
@ -243,7 +243,7 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
static const struct of_device_id tsens_table[] = {
@@ -86,6 +112,8 @@ MODULE_DEVICE_TABLE(of, 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,
@ -251,8 +251,8 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
+ .set_trip_activate = tsens_activate_trip_type,
};
static int tsens_register(struct tsens_device *tmdev)
@@ -134,7 +162,7 @@ static int tsens_probe(struct platform_d
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
@ -261,32 +261,32 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
num_sensors = data->num_sensors;
@@ -155,6 +183,9 @@ static int tsens_probe(struct platform_d
tmdev->dev = dev;
tmdev->num_sensors = num_sensors;
tmdev->ops = data->ops;
@@ -144,6 +172,9 @@ static int tsens_probe(struct platform_d
priv->dev = dev;
priv->num_sensors = num_sensors;
priv->ops = data->ops;
+
+ tmdev->tsens_irq = platform_get_irq(pdev, 0);
+ priv->tsens_irq = platform_get_irq(pdev, 0);
+
for (i = 0; i < tmdev->num_sensors; i++) {
for (i = 0; i < priv->num_sensors; i++) {
if (data->hw_ids)
tmdev->sensor[i].hw_id = data->hw_ids[i];
priv->sensor[i].hw_id = data->hw_ids[i];
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -24,9 +24,12 @@ struct tsens_device;
@@ -40,9 +40,12 @@ enum tsens_ver {
struct tsens_sensor {
struct tsens_device *tmdev;
struct tsens_priv *priv;
struct thermal_zone_device *tzd;
+ struct work_struct notify_work;
int offset;
int id;
int hw_id;
unsigned int id;
unsigned int hw_id;
+ int calib_data;
+ int calib_data_backup;
int slope;
u32 status;
};
@@ -41,6 +44,9 @@ struct tsens_sensor {
@@ -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
@ -296,24 +296,27 @@ Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
*/
struct tsens_ops {
/* mandatory callbacks */
@@ -53,6 +59,9 @@ struct tsens_ops {
int (*suspend)(struct tsens_device *);
int (*resume)(struct tsens_device *);
int (*get_trend)(struct tsens_device *, int, enum thermal_trend *);
+ int (*set_trip_temp)(void *, int, int);
+ int (*set_trip_activate)(void *, int,
+ enum thermal_trip_activation_mode);
@@ -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);
};
/**
@@ -76,10 +85,12 @@ struct tsens_context {
struct tsens_device {
#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 *map;
struct regmap *tm_map;
struct regmap *srot_map;
u32 tm_offset;
struct tsens_context ctx;
@@ -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];

View File

@ -1,20 +0,0 @@
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -128,6 +128,7 @@ int __init init_common(struct tsens_devi
{
void __iomem *base;
struct resource *res;
+ resource_size_t size;
struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node);
if (!op)
@@ -142,7 +143,8 @@ int __init init_common(struct tsens_devi
}
res = platform_get_resource(op, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&op->dev, res);
+ size = resource_size(res);
+ base = devm_ioremap(&op->dev, res->start, size);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@ -0,0 +1,68 @@
--- a/drivers/thermal/qcom/tsens-ipq8064.c
+++ b/drivers/thermal/qcom/tsens-ipq8064.c
@@ -18,6 +18,7 @@
#include <linux/regmap.h>
#include <linux/thermal.h>
#include <linux/nvmem-consumer.h>
+#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include "tsens.h"
@@ -320,15 +321,42 @@ static void hw_init(struct tsens_priv *p
INIT_WORK(&priv->tsens_work, tsens_scheduler_fn);
}
+static const struct regmap_config tsens_config = {
+ .name = "tm",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
static int init_ipq8064(struct tsens_priv *priv)
{
- int ret, i;
+ struct device *dev = priv->dev;
u32 reg_cntl, offset = 0;
+ struct resource *res;
+ resource_size_t size;
+ void __iomem *base;
+ int ret, i;
+ struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
+
+ if (!op)
+ return -EINVAL;
- init_common(priv);
- if (!priv->tm_map)
- return -ENODEV;
+ /* old DTs where SROT and TM were in a contiguous 2K block */
+ priv->tm_offset = 0x1000;
+ res = platform_get_resource(op, IORESOURCE_MEM, 0);
+ size = resource_size(res);
+ base = devm_ioremap(&op->dev, res->start, size);
+ if (IS_ERR(base)) {
+ ret = PTR_ERR(base);
+ goto err_put_device;
+ }
+
+ priv->tm_map = devm_regmap_init_mmio(dev, base, &tsens_config);
+ if (IS_ERR(priv->tm_map)) {
+ ret = PTR_ERR(priv->tm_map);
+ goto err_put_device;
+ }
/*
* The status registers for each sensor are discontiguous
* because some SoCs have 5 sensors while others have more
@@ -367,6 +395,10 @@ static int init_ipq8064(struct tsens_pri
return ret;
return 0;
+
+err_put_device:
+ put_device(&op->dev);
+ return ret;
}
static int calibrate_ipq8064(struct tsens_priv *priv)

View File

@ -11,10 +11,10 @@
#include <linux/thermal.h>
+#include <linux/slab.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/interrupt.h>
@@ -210,9 +212,8 @@ static void tsens_scheduler_fn(struct wo
struct tsens_device *tmdev = container_of(work, struct tsens_device,
@@ -211,9 +213,8 @@ static void tsens_scheduler_fn(struct wo
struct tsens_priv *priv = container_of(work, struct tsens_priv,
tsens_work);
unsigned int threshold, threshold_low, code, reg, sensor, mask;
- unsigned int sensor_addr;
@ -22,32 +22,32 @@
- int adc_code, ret;
+ int ret;
ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg);
ret = regmap_read(priv->tm_map, STATUS_CNTL_8064, &reg);
if (ret)
@@ -261,9 +262,8 @@ static void tsens_scheduler_fn(struct wo
@@ -262,9 +263,8 @@ static void tsens_scheduler_fn(struct wo
if (upper_th_x || lower_th_x) {
/* Notify user space */
schedule_work(&tmdev->sensor[0].notify_work);
- regmap_read(tmdev->map, sensor_addr, &adc_code);
schedule_work(&priv->sensor[0].notify_work);
- regmap_read(priv->tm_map, sensor_addr, &adc_code);
pr_debug("Trigger (%d degrees) for sensor %d\n",
- code_to_degC(adc_code, &tmdev->sensor[0]), 0);
+ code_to_degC(code, &tmdev->sensor[0]), 0);
- code_to_degC(adc_code, &priv->sensor[0]), 0);
+ code_to_degC(code, &priv->sensor[0]), 0);
}
}
regmap_write(tmdev->map, STATUS_CNTL_8064, reg & mask);
@@ -372,40 +372,55 @@ static int init_ipq8064(struct tsens_dev
static int calibrate_ipq8064(struct tsens_device *tmdev)
regmap_write(priv->tm_map, STATUS_CNTL_8064, reg & mask);
@@ -404,40 +404,55 @@ err_put_device:
static int calibrate_ipq8064(struct tsens_priv *priv)
{
int i;
- char *data, *data_backup;
-
+ int ret = 0;
+ u8 *data, *data_backup;
+ struct device *dev = tmdev->dev;
ssize_t num_read = tmdev->num_sensors;
struct tsens_sensor *s = tmdev->sensor;
+ struct device *dev = priv->dev;
ssize_t num_read = priv->num_sensors;
struct tsens_sensor *s = priv->sensor;
- data = qfprom_read(tmdev->dev, "calib");
- data = qfprom_read(priv->dev, "calib");
+ data = qfprom_read(dev, "calib");
if (IS_ERR(data)) {
- pr_err("Calibration not found.\n");
@ -58,7 +58,7 @@
+ goto exit;
}
- data_backup = qfprom_read(tmdev->dev, "calib_backup");
- data_backup = qfprom_read(priv->dev, "calib_backup");
+ data_backup = qfprom_read(dev, "calib_backup");
if (IS_ERR(data_backup)) {
- pr_err("Backup calibration not found.\n");
@ -93,7 +93,7 @@
s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
}
hw_init(tmdev);
hw_init(priv);
- return 0;
+free_backup:
@ -104,4 +104,4 @@
+ return ret;
}
static int get_temp_ipq8064(struct tsens_device *tmdev, int id, int *temp)
static int get_temp_ipq8064(struct tsens_priv *priv, int id, int *temp)