2019-03-20 13:19:26

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 00/23] thermal: tsens: Refactor to use regmap_field

Changes pending from earlier reviews:
- Using macros from bits.h as suggested by Eduardo. I'd like to defer this
change to a separate series where I can convert over all the files (v0.1,
v1, v2) together. This series is getting quite long as it is.

Changes since v2:
- Simplify qcs404 device tree by changing 'passive' trips on non-throttling
devices to 'hot' type. Update the trip points too.
- Replace IP version reads with just a version major number in the feature
data structure. This is enough for differenting between IPs for different
code paths for now.
- Fix off-by-one typo in the REG_FIELD_FOR_EACH_ macro names.

Changes since v1:
- Anything not being throttled in the kernel converted to a hot trip point (no
cooling-maps)
- Don't print version number of the IP at boot

Description
-----------
Short term bandaid fixes to add support for more versions of the TSENS IP
is not proving to be very scalable. Here is a series to finally convert the
driver's core to use regmap_fields so that register addresses and bitfields
can be abstracted away from the code.

This series is posted as one to give a complete view of where I'm going
with this refactor. We can probably split it into smaller sets if required.
Currently it consists of the following parts:

- Patch 01-06: Style changes to make code easier to read (mostly naming
related). This has no functional change in the driver, it is a series of
search and replace operations. Ideally this will get merged first,
otherwise everything else will become painful :-)

- Patch 07-09: Merge the 8916 and 8974 source files into a single one
called v0_1.c denoting the version of the IP and open up more
opportunities for reuse.

- Patch 10: This is the core patch that adds IP-specific data based on two
data structures: tsens_features has bit flags to identify if a certain
feature is available in a version or not and an array of reg_field
pointers.

regfield_ids list the important fields across IP versions and are used as
an index.

This patch converts over all platforms except 8960 which currently
doesn't use DT data for tsens and has custom functions for everything. We
will get to it eventually, but it's conversion is not necessary for this
series to be merged.

- Patch 11-15: Clean ups, new functionality and bugfixes based on regmap_field

- Patch 16-18: Refactor the get_temp routine. We expect to have a single
get_temp routine once all the conversion is finished.

- Patch 20-22: Introduce qcs404 support using new regmap infrastructure.

Testing
-------

Since these changes affect every platform using TSENS, it should be
clarified that I have only been focussing on developing/testing this on
sdm845, msm8916, qcs404.

Future work
-----------
a. Get rid of get_temp_common in favour of get_temp_tsens_valid
b. irq support (coming soon)
c. Convert over 8960 to use regmap_field and as a result common functions


Amit Kucheria (23):
drivers: thermal: tsens: Document the data structures
drivers: thermal: tsens: Rename tsens_data
drivers: thermal: tsens: Rename tsens_device
drivers: thermal: tsens: Rename variable tmdev
drivers: thermal: tsens: Use consistent names for variables
drivers: thermal: tsens: Function prototypes should have argument
names
drivers: thermal: tsens: Rename tsens-8916 to prepare to merge with
tsens-8974
drivers: thermal: tsens: Rename constants to prepare to merge with
tsens-8974
drivers: thermal: tsens: Merge tsens-8974 into tsens-v0_1
drivers: thermal: tsens: Introduce reg_fields to deal with register
description
drivers: thermal: tsens: Save reference to the device pointer and use
it
drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER
drivers: thermal: tsens: Add new operation to check if a sensor is
enabled
drivers: thermal: tsens: change data type for sensor IDs
drivers: thermal: tsens: Introduce IP-specific max_sensor count
drivers: thermal: tsens: simplify get_temp_tsens_v2 routine
drivers: thermal: tsens: Move get_temp_tsens_v2 to allow sharing
drivers: thermal: tsens: Common get_temp() learns to do ADC conversion
dt: thermal: tsens: Add bindings for qcs404
drivers: thermal: tsens: Add generic support for TSENS v1 IP
arm64: dts: qcom: qcs404: Add tsens controller
arm64: dts: qcom: qcs404: Add thermal zones for each sensor
drivers: thermal: tsens: Move calibration constants to header file

.../bindings/thermal/qcom-tsens.txt | 14 +
arch/arm64/boot/dts/qcom/qcs404.dtsi | 272 ++++++++++++++++
drivers/thermal/qcom/Makefile | 4 +-
drivers/thermal/qcom/tsens-8916.c | 105 -------
drivers/thermal/qcom/tsens-8960.c | 84 ++---
drivers/thermal/qcom/tsens-common.c | 159 +++++++---
.../qcom/{tsens-8974.c => tsens-v0_1.c} | 166 +++++++++-
drivers/thermal/qcom/tsens-v1.c | 193 ++++++++++++
drivers/thermal/qcom/tsens-v2.c | 111 +++----
drivers/thermal/qcom/tsens.c | 100 +++---
drivers/thermal/qcom/tsens.h | 291 ++++++++++++++++--
11 files changed, 1166 insertions(+), 333 deletions(-)
delete mode 100644 drivers/thermal/qcom/tsens-8916.c
rename drivers/thermal/qcom/{tsens-8974.c => tsens-v0_1.c} (56%)
create mode 100644 drivers/thermal/qcom/tsens-v1.c

--
2.17.1



2019-03-20 13:19:42

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 02/23] drivers: thermal: tsens: Rename tsens_data

Rename to tsens_plat_data to denote that it is platform-data passed in
at compile-time.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-8916.c | 2 +-
drivers/thermal/qcom/tsens-8960.c | 2 +-
drivers/thermal/qcom/tsens-8974.c | 2 +-
drivers/thermal/qcom/tsens-v2.c | 4 ++--
drivers/thermal/qcom/tsens.c | 2 +-
drivers/thermal/qcom/tsens.h | 8 ++++----
6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
index c6dd620ac029..66edcfca1526 100644
--- a/drivers/thermal/qcom/tsens-8916.c
+++ b/drivers/thermal/qcom/tsens-8916.c
@@ -97,7 +97,7 @@ static const struct tsens_ops ops_8916 = {
.get_temp = get_temp_common,
};

-const struct tsens_data data_8916 = {
+const struct tsens_plat_data data_8916 = {
.num_sensors = 5,
.ops = &ops_8916,
.reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 0f0adb302a7b..f3c3820e6e8e 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -277,7 +277,7 @@ static const struct tsens_ops ops_8960 = {
.resume = resume_8960,
};

-const struct tsens_data data_8960 = {
+const struct tsens_plat_data data_8960 = {
.num_sensors = 11,
.ops = &ops_8960,
};
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
index 3d3fda3d731b..5023f20afc14 100644
--- a/drivers/thermal/qcom/tsens-8974.c
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -229,7 +229,7 @@ static const struct tsens_ops ops_8974 = {
.get_temp = get_temp_common,
};

-const struct tsens_data data_8974 = {
+const struct tsens_plat_data data_8974 = {
.num_sensors = 11,
.ops = &ops_8974,
.reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 381a212872bf..cc98a61e093b 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -66,13 +66,13 @@ static const struct tsens_ops ops_generic_v2 = {
.get_temp = get_temp_tsens_v2,
};

-const struct tsens_data data_tsens_v2 = {
+const struct tsens_plat_data data_tsens_v2 = {
.ops = &ops_generic_v2,
.reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
};

/* Kept around for backward compatibility with old msm8996.dtsi */
-const struct tsens_data data_8996 = {
+const struct tsens_plat_data data_8996 = {
.num_sensors = 13,
.ops = &ops_generic_v2,
.reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index f1ec9bbe4717..065ec2189bd3 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -102,7 +102,7 @@ static int tsens_probe(struct platform_device *pdev)
struct device *dev;
struct device_node *np;
struct tsens_device *tmdev;
- const struct tsens_data *data;
+ const struct tsens_plat_data *data;
const struct of_device_id *id;
u32 num_sensors;

diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 89318523c848..232376c690cc 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -65,13 +65,13 @@ enum reg_list {
};

/**
- * struct tsens_data - tsens platform data
+ * struct tsens_plat_data - tsens compile-time platform data
* @num_sensors: Number of sensors supported by platform
* @ops: operations the tsens instance supports
* @hw_ids: Subset of sensors ids supported by platform, if not the first n
* @reg_offsets: Register offsets for commonly used registers
*/
-struct tsens_data {
+struct tsens_plat_data {
const u32 num_sensors;
const struct tsens_ops *ops;
const u16 reg_offsets[REG_ARRAY_SIZE];
@@ -117,8 +117,8 @@ int init_common(struct tsens_device *);
int get_temp_common(struct tsens_device *, int, int *);

/* TSENS v1 targets */
-extern const struct tsens_data data_8916, data_8974, data_8960;
+extern const struct tsens_plat_data data_8916, data_8974, data_8960;
/* TSENS v2 targets */
-extern const struct tsens_data data_8996, data_tsens_v2;
+extern const struct tsens_plat_data data_8996, data_tsens_v2;

#endif /* __QCOM_TSENS_H__ */
--
2.17.1


2019-03-20 13:19:47

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 03/23] drivers: thermal: tsens: Rename tsens_device

Rename to tsens_priv to denote that it is private data for each tsens
instance.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-8916.c | 2 +-
drivers/thermal/qcom/tsens-8960.c | 14 +++++++-------
drivers/thermal/qcom/tsens-8974.c | 2 +-
drivers/thermal/qcom/tsens-common.c | 6 +++---
drivers/thermal/qcom/tsens-v2.c | 2 +-
drivers/thermal/qcom/tsens.c | 14 +++++++-------
drivers/thermal/qcom/tsens.h | 30 ++++++++++++++---------------
7 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
index 66edcfca1526..7b8f83c9a033 100644
--- a/drivers/thermal/qcom/tsens-8916.c
+++ b/drivers/thermal/qcom/tsens-8916.c
@@ -39,7 +39,7 @@
#define CAL_SEL_MASK 0xe0000000
#define CAL_SEL_SHIFT 29

-static int calibrate_8916(struct tsens_device *tmdev)
+static int calibrate_8916(struct tsens_priv *tmdev)
{
int base0 = 0, base1 = 0, i;
u32 p1[5], p2[5];
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index f3c3820e6e8e..7e340eea48da 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -56,7 +56,7 @@
#define TRDY_MASK BIT(7)
#define TIMEOUT_US 100

-static int suspend_8960(struct tsens_device *tmdev)
+static int suspend_8960(struct tsens_priv *tmdev)
{
int ret;
unsigned int mask;
@@ -82,7 +82,7 @@ static int suspend_8960(struct tsens_device *tmdev)
return 0;
}

-static int resume_8960(struct tsens_device *tmdev)
+static int resume_8960(struct tsens_priv *tmdev)
{
int ret;
struct regmap *map = tmdev->tm_map;
@@ -112,7 +112,7 @@ static int resume_8960(struct tsens_device *tmdev)
return 0;
}

-static int enable_8960(struct tsens_device *tmdev, int id)
+static int enable_8960(struct tsens_priv *tmdev, int id)
{
int ret;
u32 reg, mask;
@@ -138,7 +138,7 @@ static int enable_8960(struct tsens_device *tmdev, int id)
return 0;
}

-static void disable_8960(struct tsens_device *tmdev)
+static void disable_8960(struct tsens_priv *tmdev)
{
int ret;
u32 reg_cntl;
@@ -162,7 +162,7 @@ static void disable_8960(struct tsens_device *tmdev)
regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
}

-static int init_8960(struct tsens_device *tmdev)
+static int init_8960(struct tsens_priv *tmdev)
{
int ret, i;
u32 reg_cntl;
@@ -212,7 +212,7 @@ static int init_8960(struct tsens_device *tmdev)
return 0;
}

-static int calibrate_8960(struct tsens_device *tmdev)
+static int calibrate_8960(struct tsens_priv *tmdev)
{
int i;
char *data;
@@ -243,7 +243,7 @@ static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
return adc_code * slope + offset;
}

-static int get_temp_8960(struct tsens_device *tmdev, int id, int *temp)
+static int get_temp_8960(struct tsens_priv *tmdev, int id, int *temp)
{
int ret;
u32 code, trdy;
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
index 5023f20afc14..f983f98f2176 100644
--- a/drivers/thermal/qcom/tsens-8974.c
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -91,7 +91,7 @@

#define BIT_APPEND 0x3

-static int calibrate_8974(struct tsens_device *tmdev)
+static int calibrate_8974(struct tsens_priv *tmdev)
{
int base1 = 0, base2 = 0, i;
u32 p1[11], p2[11];
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index f80c73f11740..46f8c68c70f5 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -46,7 +46,7 @@ char *qfprom_read(struct device *dev, const char *cname)
* and offset values are derived from tz->tzp->slope and tz->tzp->offset
* resp.
*/
-void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
+void compute_intercept_slope(struct tsens_priv *tmdev, u32 *p1,
u32 *p2, u32 mode)
{
int i;
@@ -95,7 +95,7 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
return degc;
}

-int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
+int get_temp_common(struct tsens_priv *tmdev, int id, int *temp)
{
struct tsens_sensor *s = &tmdev->sensor[id];
u32 code;
@@ -127,7 +127,7 @@ static const struct regmap_config tsens_srot_config = {
.reg_stride = 4,
};

-int __init init_common(struct tsens_device *tmdev)
+int __init init_common(struct tsens_priv *tmdev)
{
void __iomem *tm_base, *srot_base;
struct resource *res;
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index cc98a61e093b..d812fd3f4567 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -12,7 +12,7 @@
#define LAST_TEMP_MASK 0xfff
#define STATUS_VALID_BIT BIT(21)

-static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
+static int get_temp_tsens_v2(struct tsens_priv *tmdev, int id, int *temp)
{
struct tsens_sensor *s = &tmdev->sensor[id];
u32 code;
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 065ec2189bd3..074fbb4d70f2 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -15,7 +15,7 @@
static int tsens_get_temp(void *data, int *temp)
{
const struct tsens_sensor *s = data;
- struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *tmdev = s->tmdev;

return tmdev->ops->get_temp(tmdev, s->id, temp);
}
@@ -23,7 +23,7 @@ static int tsens_get_temp(void *data, int *temp)
static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
{
const struct tsens_sensor *s = p;
- struct tsens_device *tmdev = s->tmdev;
+ struct tsens_priv *tmdev = s->tmdev;

if (tmdev->ops->get_trend)
return tmdev->ops->get_trend(tmdev, s->id, trend);
@@ -33,7 +33,7 @@ static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)

static int __maybe_unused tsens_suspend(struct device *dev)
{
- struct tsens_device *tmdev = dev_get_drvdata(dev);
+ struct tsens_priv *tmdev = dev_get_drvdata(dev);

if (tmdev->ops && tmdev->ops->suspend)
return tmdev->ops->suspend(tmdev);
@@ -43,7 +43,7 @@ static int __maybe_unused tsens_suspend(struct device *dev)

static int __maybe_unused tsens_resume(struct device *dev)
{
- struct tsens_device *tmdev = dev_get_drvdata(dev);
+ struct tsens_priv *tmdev = dev_get_drvdata(dev);

if (tmdev->ops && tmdev->ops->resume)
return tmdev->ops->resume(tmdev);
@@ -76,7 +76,7 @@ static const struct thermal_zone_of_device_ops tsens_of_ops = {
.get_trend = tsens_get_trend,
};

-static int tsens_register(struct tsens_device *tmdev)
+static int tsens_register(struct tsens_priv *tmdev)
{
int i;
struct thermal_zone_device *tzd;
@@ -101,7 +101,7 @@ static int tsens_probe(struct platform_device *pdev)
int ret, i;
struct device *dev;
struct device_node *np;
- struct tsens_device *tmdev;
+ struct tsens_priv *tmdev;
const struct tsens_plat_data *data;
const struct of_device_id *id;
u32 num_sensors;
@@ -174,7 +174,7 @@ static int tsens_probe(struct platform_device *pdev)

static int tsens_remove(struct platform_device *pdev)
{
- struct tsens_device *tmdev = platform_get_drvdata(pdev);
+ struct tsens_priv *tmdev = platform_get_drvdata(pdev);

if (tmdev->ops->disable)
tmdev->ops->disable(tmdev);
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 232376c690cc..936bdc7b1bc2 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -12,7 +12,7 @@

#include <linux/thermal.h>

-struct tsens_device;
+struct tsens_priv;

/**
* struct tsens_sensor - data for each sensor connected to the tsens device
@@ -25,7 +25,7 @@ struct tsens_device;
* @status: 8960-specific variable to track 8960 and 8660 status register offset
*/
struct tsens_sensor {
- struct tsens_device *tmdev;
+ struct tsens_priv *tmdev;
struct thermal_zone_device *tzd;
int offset;
int id;
@@ -47,15 +47,15 @@ struct tsens_sensor {
*/
struct tsens_ops {
/* mandatory callbacks */
- int (*init)(struct tsens_device *);
- int (*calibrate)(struct tsens_device *);
- int (*get_temp)(struct tsens_device *, int, int *);
+ int (*init)(struct tsens_priv *);
+ int (*calibrate)(struct tsens_priv *);
+ int (*get_temp)(struct tsens_priv *, int, int *);
/* optional callbacks */
- int (*enable)(struct tsens_device *, int);
- void (*disable)(struct tsens_device *);
- int (*suspend)(struct tsens_device *);
- int (*resume)(struct tsens_device *);
- int (*get_trend)(struct tsens_device *, int, enum thermal_trend *);
+ int (*enable)(struct tsens_priv *, int);
+ void (*disable)(struct tsens_priv *);
+ int (*suspend)(struct tsens_priv *);
+ int (*resume)(struct tsens_priv *);
+ int (*get_trend)(struct tsens_priv *, int, enum thermal_trend *);
};

enum reg_list {
@@ -87,7 +87,7 @@ struct tsens_context {
};

/**
- * struct tsens_device - private data for each instance of the tsens IP
+ * struct tsens_priv - private data for each instance of the tsens IP
* @dev: pointer to struct device
* @num_sensors: number of sensors enabled on this device
* @tm_map: pointer to TM register address space
@@ -99,7 +99,7 @@ struct tsens_context {
* @ops: pointer to list of callbacks supported by this device
* @sensor: list of sensors attached to this device
*/
-struct tsens_device {
+struct tsens_priv {
struct device *dev;
u32 num_sensors;
struct regmap *tm_map;
@@ -112,9 +112,9 @@ struct tsens_device {
};

char *qfprom_read(struct device *, const char *);
-void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
-int init_common(struct tsens_device *);
-int get_temp_common(struct tsens_device *, int, int *);
+void compute_intercept_slope(struct tsens_priv *, u32 *, u32 *, u32);
+int init_common(struct tsens_priv *);
+int get_temp_common(struct tsens_priv *, int, int *);

/* TSENS v1 targets */
extern const struct tsens_plat_data data_8916, data_8974, data_8960;
--
2.17.1


2019-03-20 13:19:59

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 04/23] drivers: thermal: tsens: Rename variable tmdev

tmdev seems to imply that this is a device pointer when in fact it is
just private platform data for each tsens device. Rename it to priv
improve code readability.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-8916.c | 16 +++---
drivers/thermal/qcom/tsens-8960.c | 82 ++++++++++++++---------------
drivers/thermal/qcom/tsens-8974.c | 16 +++---
drivers/thermal/qcom/tsens-common.c | 53 +++++++++----------
drivers/thermal/qcom/tsens-v2.c | 12 ++---
drivers/thermal/qcom/tsens.c | 80 ++++++++++++++--------------
drivers/thermal/qcom/tsens.h | 4 +-
7 files changed, 131 insertions(+), 132 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
index 7b8f83c9a033..d4ad4082c800 100644
--- a/drivers/thermal/qcom/tsens-8916.c
+++ b/drivers/thermal/qcom/tsens-8916.c
@@ -39,23 +39,23 @@
#define CAL_SEL_MASK 0xe0000000
#define CAL_SEL_SHIFT 29

-static int calibrate_8916(struct tsens_priv *tmdev)
+static int calibrate_8916(struct tsens_priv *priv)
{
int base0 = 0, base1 = 0, i;
u32 p1[5], p2[5];
int mode = 0;
u32 *qfprom_cdata, *qfprom_csel;

- qfprom_cdata = (u32 *)qfprom_read(tmdev->dev, "calib");
+ qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(qfprom_cdata))
return PTR_ERR(qfprom_cdata);

- qfprom_csel = (u32 *)qfprom_read(tmdev->dev, "calib_sel");
+ qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
if (IS_ERR(qfprom_csel))
return PTR_ERR(qfprom_csel);

mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
- dev_dbg(tmdev->dev, "calibration mode is %d\n", mode);
+ dev_dbg(priv->dev, "calibration mode is %d\n", mode);

switch (mode) {
case TWO_PT_CALIB:
@@ -65,7 +65,7 @@ static int calibrate_8916(struct tsens_priv *tmdev)
p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
- for (i = 0; i < tmdev->num_sensors; i++)
+ for (i = 0; i < priv->num_sensors; i++)
p2[i] = ((base1 + p2[i]) << 3);
/* Fall through */
case ONE_PT_CALIB2:
@@ -75,18 +75,18 @@ static int calibrate_8916(struct tsens_priv *tmdev)
p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
- for (i = 0; i < tmdev->num_sensors; i++)
+ for (i = 0; i < priv->num_sensors; i++)
p1[i] = (((base0) + p1[i]) << 3);
break;
default:
- for (i = 0; i < tmdev->num_sensors; i++) {
+ for (i = 0; i < priv->num_sensors; i++) {
p1[i] = 500;
p2[i] = 780;
}
break;
}

- compute_intercept_slope(tmdev, p1, p2, mode);
+ compute_intercept_slope(priv, p1, p2, mode);

return 0;
}
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
index 7e340eea48da..8d9b721dadb6 100644
--- a/drivers/thermal/qcom/tsens-8960.c
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -56,21 +56,21 @@
#define TRDY_MASK BIT(7)
#define TIMEOUT_US 100

-static int suspend_8960(struct tsens_priv *tmdev)
+static int suspend_8960(struct tsens_priv *priv)
{
int ret;
unsigned int mask;
- struct regmap *map = tmdev->tm_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;

- if (tmdev->num_sensors > 1)
+ if (priv->num_sensors > 1)
mask = SLP_CLK_ENA | EN;
else
mask = SLP_CLK_ENA_8660 | EN;
@@ -82,10 +82,10 @@ static int suspend_8960(struct tsens_priv *tmdev)
return 0;
}

-static int resume_8960(struct tsens_priv *tmdev)
+static int resume_8960(struct tsens_priv *priv)
{
int ret;
- struct regmap *map = tmdev->tm_map;
+ struct regmap *map = priv->tm_map;

ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
if (ret)
@@ -95,80 +95,80 @@ static int resume_8960(struct tsens_priv *tmdev)
* Separate CONFIG restore is not needed only for 8660 as
* config is part of CTRL Addr and its restored as such
*/
- if (tmdev->num_sensors > 1) {
+ if (priv->num_sensors > 1) {
ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
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;

return 0;
}

-static int enable_8960(struct tsens_priv *tmdev, int id)
+static int enable_8960(struct tsens_priv *priv, int id)
{
int ret;
u32 reg, mask;

- ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg);
+ ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
if (ret)
return ret;

mask = BIT(id + SENSOR0_SHIFT);
- ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg | SW_RST);
+ ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
if (ret)
return ret;

- if (tmdev->num_sensors > 1)
+ if (priv->num_sensors > 1)
reg |= mask | SLP_CLK_ENA | EN;
else
reg |= mask | SLP_CLK_ENA_8660 | EN;

- ret = regmap_write(tmdev->tm_map, CNTL_ADDR, reg);
+ ret = regmap_write(priv->tm_map, CNTL_ADDR, reg);
if (ret)
return ret;

return 0;
}

-static void disable_8960(struct tsens_priv *tmdev)
+static void disable_8960(struct tsens_priv *priv)
{
int ret;
u32 reg_cntl;
u32 mask;

- mask = GENMASK(tmdev->num_sensors - 1, 0);
+ mask = GENMASK(priv->num_sensors - 1, 0);
mask <<= SENSOR0_SHIFT;
mask |= EN;

- ret = regmap_read(tmdev->tm_map, CNTL_ADDR, &reg_cntl);
+ ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg_cntl);
if (ret)
return;

reg_cntl &= ~mask;

- if (tmdev->num_sensors > 1)
+ if (priv->num_sensors > 1)
reg_cntl &= ~SLP_CLK_ENA;
else
reg_cntl &= ~SLP_CLK_ENA_8660;

- regmap_write(tmdev->tm_map, CNTL_ADDR, reg_cntl);
+ regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
}

-static int init_8960(struct tsens_priv *tmdev)
+static int init_8960(struct tsens_priv *priv)
{
int ret, i;
u32 reg_cntl;

- tmdev->tm_map = dev_get_regmap(tmdev->dev, NULL);
- if (!tmdev->tm_map)
+ priv->tm_map = dev_get_regmap(priv->dev, NULL);
+ if (!priv->tm_map)
return -ENODEV;

/*
@@ -177,21 +177,21 @@ static int init_8960(struct tsens_priv *tmdev)
* 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 >= 5)
- tmdev->sensor[i].status = S0_STATUS_ADDR + 40;
- tmdev->sensor[i].status += i * 4;
+ priv->sensor[i].status = S0_STATUS_ADDR + 40;
+ priv->sensor[i].status += i * 4;
}

reg_cntl = SW_RST;
- ret = regmap_update_bits(tmdev->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
+ ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
if (ret)
return ret;

- if (tmdev->num_sensors > 1) {
+ if (priv->num_sensors > 1) {
reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
reg_cntl &= ~SW_RST;
- ret = regmap_update_bits(tmdev->tm_map, CONFIG_ADDR,
+ ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
CONFIG_MASK, CONFIG);
} else {
reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
@@ -199,30 +199,30 @@ static int init_8960(struct tsens_priv *tmdev)
reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
}

- reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
- ret = regmap_write(tmdev->tm_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->tm_map, CNTL_ADDR, reg_cntl);
+ ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
if (ret)
return ret;

return 0;
}

-static int calibrate_8960(struct tsens_priv *tmdev)
+static int calibrate_8960(struct tsens_priv *priv)
{
int i;
char *data;

- 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))
- data = qfprom_read(tmdev->dev, "calib_backup");
+ data = qfprom_read(priv->dev, "calib_backup");
if (IS_ERR(data))
return PTR_ERR(data);

@@ -243,21 +243,21 @@ static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
return adc_code * slope + offset;
}

-static int get_temp_8960(struct tsens_priv *tmdev, int id, int *temp)
+static int get_temp_8960(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->tm_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->tm_map, s->status, &code);
+ ret = regmap_read(priv->tm_map, s->status, &code);
if (ret)
return ret;
*temp = code_to_mdegC(code, s);
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
index f983f98f2176..303157fd00be 100644
--- a/drivers/thermal/qcom/tsens-8974.c
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -91,7 +91,7 @@

#define BIT_APPEND 0x3

-static int calibrate_8974(struct tsens_priv *tmdev)
+static int calibrate_8974(struct tsens_priv *priv)
{
int base1 = 0, base2 = 0, i;
u32 p1[11], p2[11];
@@ -99,11 +99,11 @@ static int calibrate_8974(struct tsens_priv *tmdev)
u32 *calib, *bkp;
u32 calib_redun_sel;

- calib = (u32 *)qfprom_read(tmdev->dev, "calib");
+ calib = (u32 *)qfprom_read(priv->dev, "calib");
if (IS_ERR(calib))
return PTR_ERR(calib);

- bkp = (u32 *)qfprom_read(tmdev->dev, "calib_backup");
+ bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
if (IS_ERR(bkp))
return PTR_ERR(bkp);

@@ -184,25 +184,25 @@ static int calibrate_8974(struct tsens_priv *tmdev)

switch (mode) {
case ONE_PT_CALIB:
- for (i = 0; i < tmdev->num_sensors; i++)
+ for (i = 0; i < priv->num_sensors; i++)
p1[i] += (base1 << 2) | BIT_APPEND;
break;
case TWO_PT_CALIB:
- for (i = 0; i < tmdev->num_sensors; i++) {
+ for (i = 0; i < priv->num_sensors; i++) {
p2[i] += base2;
p2[i] <<= 2;
p2[i] |= BIT_APPEND;
}
/* Fall through */
case ONE_PT_CALIB2:
- for (i = 0; i < tmdev->num_sensors; i++) {
+ for (i = 0; i < priv->num_sensors; i++) {
p1[i] += base1;
p1[i] <<= 2;
p1[i] |= BIT_APPEND;
}
break;
default:
- for (i = 0; i < tmdev->num_sensors; i++)
+ for (i = 0; i < priv->num_sensors; i++)
p2[i] = 780;
p1[0] = 502;
p1[1] = 509;
@@ -218,7 +218,7 @@ static int calibrate_8974(struct tsens_priv *tmdev)
break;
}

- compute_intercept_slope(tmdev, p1, p2, mode);
+ compute_intercept_slope(priv, p1, p2, mode);

return 0;
}
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 46f8c68c70f5..f0ef4e3cf7f9 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -46,18 +46,18 @@ char *qfprom_read(struct device *dev, const char *cname)
* and offset values are derived from tz->tzp->slope and tz->tzp->offset
* resp.
*/
-void compute_intercept_slope(struct tsens_priv *tmdev, u32 *p1,
+void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
u32 *p2, u32 mode)
{
int i;
int num, den;

- for (i = 0; i < tmdev->num_sensors; i++) {
- dev_dbg(tmdev->dev,
+ for (i = 0; i < priv->num_sensors; i++) {
+ dev_dbg(priv->dev,
"sensor%d - data_point1:%#x data_point2:%#x\n",
i, p1[i], p2[i]);

- tmdev->sensor[i].slope = SLOPE_DEFAULT;
+ priv->sensor[i].slope = SLOPE_DEFAULT;
if (mode == TWO_PT_CALIB) {
/*
* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
@@ -66,13 +66,13 @@ void compute_intercept_slope(struct tsens_priv *tmdev, u32 *p1,
num = p2[i] - p1[i];
num *= SLOPE_FACTOR;
den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
- tmdev->sensor[i].slope = num / den;
+ priv->sensor[i].slope = num / den;
}

- tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
+ priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
(CAL_DEGC_PT1 *
- tmdev->sensor[i].slope);
- dev_dbg(tmdev->dev, "offset:%d\n", tmdev->sensor[i].offset);
+ priv->sensor[i].slope);
+ dev_dbg(priv->dev, "offset:%d\n", priv->sensor[i].offset);
}
}

@@ -95,15 +95,15 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
return degc;
}

-int get_temp_common(struct tsens_priv *tmdev, int id, int *temp)
+int get_temp_common(struct tsens_priv *priv, int id, int *temp)
{
- struct tsens_sensor *s = &tmdev->sensor[id];
+ struct tsens_sensor *s = &priv->sensor[id];
u32 code;
unsigned int status_reg;
int last_temp = 0, ret;

- status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET;
- ret = regmap_read(tmdev->tm_map, status_reg, &code);
+ status_reg = priv->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET;
+ ret = regmap_read(priv->tm_map, status_reg, &code);
if (ret)
return ret;
last_temp = code & SN_ST_TEMP_MASK;
@@ -127,21 +127,21 @@ static const struct regmap_config tsens_srot_config = {
.reg_stride = 4,
};

-int __init init_common(struct tsens_priv *tmdev)
+int __init init_common(struct tsens_priv *priv)
{
void __iomem *tm_base, *srot_base;
struct resource *res;
u32 code;
int ret;
- struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node);
- u16 ctrl_offset = tmdev->reg_offsets[SROT_CTRL_OFFSET];
+ struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
+ u16 ctrl_offset = priv->reg_offsets[SROT_CTRL_OFFSET];

if (!op)
return -EINVAL;

if (op->num_resources > 1) {
/* DT with separate SROT and TM address space */
- tmdev->tm_offset = 0;
+ priv->tm_offset = 0;
res = platform_get_resource(op, IORESOURCE_MEM, 1);
srot_base = devm_ioremap_resource(&op->dev, res);
if (IS_ERR(srot_base)) {
@@ -149,16 +149,15 @@ int __init init_common(struct tsens_priv *tmdev)
goto err_put_device;
}

- tmdev->srot_map = devm_regmap_init_mmio(tmdev->dev, srot_base,
+ priv->srot_map = devm_regmap_init_mmio(priv->dev, srot_base,
&tsens_srot_config);
- if (IS_ERR(tmdev->srot_map)) {
- ret = PTR_ERR(tmdev->srot_map);
+ if (IS_ERR(priv->srot_map)) {
+ ret = PTR_ERR(priv->srot_map);
goto err_put_device;
}
-
} else {
/* old DTs where SROT and TM were in a contiguous 2K block */
- tmdev->tm_offset = 0x1000;
+ priv->tm_offset = 0x1000;
}

res = platform_get_resource(op, IORESOURCE_MEM, 0);
@@ -168,18 +167,18 @@ int __init init_common(struct tsens_priv *tmdev)
goto err_put_device;
}

- tmdev->tm_map = devm_regmap_init_mmio(tmdev->dev, tm_base, &tsens_config);
- if (IS_ERR(tmdev->tm_map)) {
- ret = PTR_ERR(tmdev->tm_map);
+ priv->tm_map = devm_regmap_init_mmio(priv->dev, tm_base, &tsens_config);
+ if (IS_ERR(priv->tm_map)) {
+ ret = PTR_ERR(priv->tm_map);
goto err_put_device;
}

- if (tmdev->srot_map) {
- ret = regmap_read(tmdev->srot_map, ctrl_offset, &code);
+ if (priv->srot_map) {
+ ret = regmap_read(priv->srot_map, ctrl_offset, &code);
if (ret)
goto err_put_device;
if (!(code & TSENS_EN)) {
- dev_err(tmdev->dev, "tsens device is not enabled\n");
+ dev_err(priv->dev, "tsens device is not enabled\n");
ret = -ENODEV;
goto err_put_device;
}
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index d812fd3f4567..8b700772d903 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -12,16 +12,16 @@
#define LAST_TEMP_MASK 0xfff
#define STATUS_VALID_BIT BIT(21)

-static int get_temp_tsens_v2(struct tsens_priv *tmdev, int id, int *temp)
+static int get_temp_tsens_v2(struct tsens_priv *priv, int id, int *temp)
{
- struct tsens_sensor *s = &tmdev->sensor[id];
+ struct tsens_sensor *s = &priv->sensor[id];
u32 code;
unsigned int status_reg;
u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
int ret;

- status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4;
- ret = regmap_read(tmdev->tm_map, status_reg, &code);
+ status_reg = priv->tm_offset + STATUS_OFFSET + s->hw_id * 4;
+ ret = regmap_read(priv->tm_map, status_reg, &code);
if (ret)
return ret;
last_temp = code & LAST_TEMP_MASK;
@@ -29,7 +29,7 @@ static int get_temp_tsens_v2(struct tsens_priv *tmdev, int id, int *temp)
goto done;

/* Try a second time */
- ret = regmap_read(tmdev->tm_map, status_reg, &code);
+ ret = regmap_read(priv->tm_map, status_reg, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
@@ -40,7 +40,7 @@ static int get_temp_tsens_v2(struct tsens_priv *tmdev, int id, int *temp)
}

/* Try a third/last time */
- ret = regmap_read(tmdev->tm_map, status_reg, &code);
+ ret = regmap_read(priv->tm_map, status_reg, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 074fbb4d70f2..4582d2b30e94 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -15,38 +15,38 @@
static int tsens_get_temp(void *data, int *temp)
{
const struct tsens_sensor *s = data;
- struct tsens_priv *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;

- return tmdev->ops->get_temp(tmdev, s->id, temp);
+ return priv->ops->get_temp(priv, s->id, temp);
}

static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
{
const struct tsens_sensor *s = p;
- struct tsens_priv *tmdev = s->tmdev;
+ struct tsens_priv *priv = s->priv;

- if (tmdev->ops->get_trend)
- return tmdev->ops->get_trend(tmdev, s->id, trend);
+ if (priv->ops->get_trend)
+ return priv->ops->get_trend(priv, s->id, trend);

return -ENOTSUPP;
}

static int __maybe_unused tsens_suspend(struct device *dev)
{
- struct tsens_priv *tmdev = dev_get_drvdata(dev);
+ struct tsens_priv *priv = dev_get_drvdata(dev);

- if (tmdev->ops && tmdev->ops->suspend)
- return tmdev->ops->suspend(tmdev);
+ if (priv->ops && priv->ops->suspend)
+ return priv->ops->suspend(priv);

return 0;
}

static int __maybe_unused tsens_resume(struct device *dev)
{
- struct tsens_priv *tmdev = dev_get_drvdata(dev);
+ struct tsens_priv *priv = dev_get_drvdata(dev);

- if (tmdev->ops && tmdev->ops->resume)
- return tmdev->ops->resume(tmdev);
+ if (priv->ops && priv->ops->resume)
+ return priv->ops->resume(priv);

return 0;
}
@@ -76,22 +76,22 @@ static const struct thermal_zone_of_device_ops tsens_of_ops = {
.get_trend = tsens_get_trend,
};

-static int tsens_register(struct tsens_priv *tmdev)
+static int tsens_register(struct tsens_priv *priv)
{
int i;
struct thermal_zone_device *tzd;

- for (i = 0; i < tmdev->num_sensors; i++) {
- tmdev->sensor[i].tmdev = tmdev;
- tmdev->sensor[i].id = i;
- tzd = devm_thermal_zone_of_sensor_register(tmdev->dev, i,
- &tmdev->sensor[i],
+ for (i = 0; i < priv->num_sensors; i++) {
+ priv->sensor[i].priv = priv;
+ priv->sensor[i].id = i;
+ tzd = devm_thermal_zone_of_sensor_register(priv->dev, i,
+ &priv->sensor[i],
&tsens_of_ops);
if (IS_ERR(tzd))
continue;
- tmdev->sensor[i].tzd = tzd;
- if (tmdev->ops->enable)
- tmdev->ops->enable(tmdev, i);
+ priv->sensor[i].tzd = tzd;
+ if (priv->ops->enable)
+ priv->ops->enable(priv, i);
}
return 0;
}
@@ -101,7 +101,7 @@ static int tsens_probe(struct platform_device *pdev)
int ret, i;
struct device *dev;
struct device_node *np;
- struct tsens_priv *tmdev;
+ struct tsens_priv *priv;
const struct tsens_plat_data *data;
const struct of_device_id *id;
u32 num_sensors;
@@ -129,55 +129,55 @@ static int tsens_probe(struct platform_device *pdev)
return -EINVAL;
}

- tmdev = devm_kzalloc(dev,
- struct_size(tmdev, sensor, num_sensors),
+ priv = devm_kzalloc(dev,
+ struct_size(priv, sensor, num_sensors),
GFP_KERNEL);
- if (!tmdev)
+ if (!priv)
return -ENOMEM;

- tmdev->dev = dev;
- tmdev->num_sensors = num_sensors;
- tmdev->ops = data->ops;
- for (i = 0; i < tmdev->num_sensors; i++) {
+ priv->dev = dev;
+ priv->num_sensors = num_sensors;
+ priv->ops = data->ops;
+ 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];
else
- tmdev->sensor[i].hw_id = i;
+ priv->sensor[i].hw_id = i;
}
for (i = 0; i < REG_ARRAY_SIZE; i++) {
- tmdev->reg_offsets[i] = data->reg_offsets[i];
+ priv->reg_offsets[i] = data->reg_offsets[i];
}

- if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp)
+ if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
return -EINVAL;

- ret = tmdev->ops->init(tmdev);
+ ret = priv->ops->init(priv);
if (ret < 0) {
dev_err(dev, "tsens init failed\n");
return ret;
}

- if (tmdev->ops->calibrate) {
- ret = tmdev->ops->calibrate(tmdev);
+ if (priv->ops->calibrate) {
+ ret = priv->ops->calibrate(priv);
if (ret < 0) {
dev_err(dev, "tsens calibration failed\n");
return ret;
}
}

- ret = tsens_register(tmdev);
+ ret = tsens_register(priv);

- platform_set_drvdata(pdev, tmdev);
+ platform_set_drvdata(pdev, priv);

return ret;
}

static int tsens_remove(struct platform_device *pdev)
{
- struct tsens_priv *tmdev = platform_get_drvdata(pdev);
+ struct tsens_priv *priv = platform_get_drvdata(pdev);

- if (tmdev->ops->disable)
- tmdev->ops->disable(tmdev);
+ if (priv->ops->disable)
+ priv->ops->disable(priv);

return 0;
}
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 936bdc7b1bc2..61ca2905ee7a 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -16,7 +16,7 @@ struct tsens_priv;

/**
* struct tsens_sensor - data for each sensor connected to the tsens device
- * @tmdev: tsens device instance that this sensor is connected to
+ * @priv: tsens device instance that this sensor is connected to
* @tzd: pointer to the thermal zone that this sensor is in
* @offset: offset of temperature adjustment curve
* @id: Sensor ID
@@ -25,7 +25,7 @@ struct tsens_priv;
* @status: 8960-specific variable to track 8960 and 8660 status register offset
*/
struct tsens_sensor {
- struct tsens_priv *tmdev;
+ struct tsens_priv *priv;
struct thermal_zone_device *tzd;
int offset;
int id;
--
2.17.1


2019-03-20 13:20:09

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 05/23] drivers: thermal: tsens: Use consistent names for variables

tsens_get_temp() uses the name 'data' for the void pointer, use the same
in tsens_get_trend() for consistency.

Remove a stray space while we're at it.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 4582d2b30e94..0b5be08d515f 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -20,13 +20,13 @@ static int tsens_get_temp(void *data, int *temp)
return priv->ops->get_temp(priv, s->id, temp);
}

-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;
+ const struct tsens_sensor *s = data;
struct tsens_priv *priv = s->priv;

if (priv->ops->get_trend)
- return priv->ops->get_trend(priv, s->id, trend);
+ return priv->ops->get_trend(priv, s->id, trend);

return -ENOTSUPP;
}
--
2.17.1


2019-03-20 13:20:12

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 06/23] drivers: thermal: tsens: Function prototypes should have argument names

check_patch complains a lot as follows:

WARNING: function definition argument 'struct tsens_priv *' should also have an identifier name
+ int (*init)(struct tsens_priv *);

Fix it.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens.h | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 61ca2905ee7a..4d6a406f8dca 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -47,15 +47,15 @@ struct tsens_sensor {
*/
struct tsens_ops {
/* mandatory callbacks */
- int (*init)(struct tsens_priv *);
- int (*calibrate)(struct tsens_priv *);
- int (*get_temp)(struct tsens_priv *, int, int *);
+ int (*init)(struct tsens_priv *priv);
+ int (*calibrate)(struct tsens_priv *priv);
+ int (*get_temp)(struct tsens_priv *priv, int i, int *temp);
/* optional callbacks */
- int (*enable)(struct tsens_priv *, int);
- void (*disable)(struct tsens_priv *);
- int (*suspend)(struct tsens_priv *);
- int (*resume)(struct tsens_priv *);
- int (*get_trend)(struct tsens_priv *, int, enum thermal_trend *);
+ int (*enable)(struct tsens_priv *priv, int i);
+ void (*disable)(struct tsens_priv *priv);
+ 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);
};

enum reg_list {
@@ -111,10 +111,10 @@ struct tsens_priv {
struct tsens_sensor sensor[0];
};

-char *qfprom_read(struct device *, const char *);
-void compute_intercept_slope(struct tsens_priv *, u32 *, u32 *, u32);
-int init_common(struct tsens_priv *);
-int get_temp_common(struct tsens_priv *, int, int *);
+char *qfprom_read(struct device *dev, const char *cname);
+void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
+int init_common(struct tsens_priv *priv);
+int get_temp_common(struct tsens_priv *priv, int i, int *temp);

/* TSENS v1 targets */
extern const struct tsens_plat_data data_8916, data_8974, data_8960;
--
2.17.1


2019-03-20 13:20:20

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 07/23] drivers: thermal: tsens: Rename tsens-8916 to prepare to merge with tsens-8974

8916 and 8974 use v0.1.0 of the TSENS IP. Rename tsens-8916 to prepare
it for merging with tsens-8974 in a later commit.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/Makefile | 2 +-
drivers/thermal/qcom/{tsens-8916.c => tsens-v0_1.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename drivers/thermal/qcom/{tsens-8916.c => tsens-v0_1.c} (100%)

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 717a08600bb5..1f2fafd43dff 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,3 +1,3 @@
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-v0_1.o tsens-8974.o tsens-8960.o tsens-v2.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-v0_1.c
similarity index 100%
rename from drivers/thermal/qcom/tsens-8916.c
rename to drivers/thermal/qcom/tsens-v0_1.c
--
2.17.1


2019-03-20 13:20:34

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 09/23] drivers: thermal: tsens: Merge tsens-8974 into tsens-v0_1

8974 and 8916 have the same version of the TSENS IP. Merge the files to
allow for better code reuse.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/Makefile | 2 +-
drivers/thermal/qcom/tsens-8974.c | 236 ------------------------------
drivers/thermal/qcom/tsens-v0_1.c | 229 +++++++++++++++++++++++++++++
drivers/thermal/qcom/tsens.h | 8 +-
4 files changed, 236 insertions(+), 239 deletions(-)
delete mode 100644 drivers/thermal/qcom/tsens-8974.c

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 1f2fafd43dff..7fa3cadce760 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
-qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o tsens-8974.o tsens-8960.o tsens-v2.o
+qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o tsens-8960.o tsens-v2.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
deleted file mode 100644
index 303157fd00be..000000000000
--- a/drivers/thermal/qcom/tsens-8974.c
+++ /dev/null
@@ -1,236 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/platform_device.h>
-#include "tsens.h"
-
-/* eeprom layout data for 8974 */
-#define BASE1_MASK 0xff
-#define S0_P1_MASK 0x3f00
-#define S1_P1_MASK 0xfc000
-#define S2_P1_MASK 0x3f00000
-#define S3_P1_MASK 0xfc000000
-#define S4_P1_MASK 0x3f
-#define S5_P1_MASK 0xfc0
-#define S6_P1_MASK 0x3f000
-#define S7_P1_MASK 0xfc0000
-#define S8_P1_MASK 0x3f000000
-#define S8_P1_MASK_BKP 0x3f
-#define S9_P1_MASK 0x3f
-#define S9_P1_MASK_BKP 0xfc0
-#define S10_P1_MASK 0xfc0
-#define S10_P1_MASK_BKP 0x3f000
-#define CAL_SEL_0_1 0xc0000000
-#define CAL_SEL_2 0x40000000
-#define CAL_SEL_SHIFT 30
-#define CAL_SEL_SHIFT_2 28
-
-#define S0_P1_SHIFT 8
-#define S1_P1_SHIFT 14
-#define S2_P1_SHIFT 20
-#define S3_P1_SHIFT 26
-#define S5_P1_SHIFT 6
-#define S6_P1_SHIFT 12
-#define S7_P1_SHIFT 18
-#define S8_P1_SHIFT 24
-#define S9_P1_BKP_SHIFT 6
-#define S10_P1_SHIFT 6
-#define S10_P1_BKP_SHIFT 12
-
-#define BASE2_SHIFT 12
-#define BASE2_BKP_SHIFT 18
-#define S0_P2_SHIFT 20
-#define S0_P2_BKP_SHIFT 26
-#define S1_P2_SHIFT 26
-#define S2_P2_BKP_SHIFT 6
-#define S3_P2_SHIFT 6
-#define S3_P2_BKP_SHIFT 12
-#define S4_P2_SHIFT 12
-#define S4_P2_BKP_SHIFT 18
-#define S5_P2_SHIFT 18
-#define S5_P2_BKP_SHIFT 24
-#define S6_P2_SHIFT 24
-#define S7_P2_BKP_SHIFT 6
-#define S8_P2_SHIFT 6
-#define S8_P2_BKP_SHIFT 12
-#define S9_P2_SHIFT 12
-#define S9_P2_BKP_SHIFT 18
-#define S10_P2_SHIFT 18
-#define S10_P2_BKP_SHIFT 24
-
-#define BASE2_MASK 0xff000
-#define BASE2_BKP_MASK 0xfc0000
-#define S0_P2_MASK 0x3f00000
-#define S0_P2_BKP_MASK 0xfc000000
-#define S1_P2_MASK 0xfc000000
-#define S1_P2_BKP_MASK 0x3f
-#define S2_P2_MASK 0x3f
-#define S2_P2_BKP_MASK 0xfc0
-#define S3_P2_MASK 0xfc0
-#define S3_P2_BKP_MASK 0x3f000
-#define S4_P2_MASK 0x3f000
-#define S4_P2_BKP_MASK 0xfc0000
-#define S5_P2_MASK 0xfc0000
-#define S5_P2_BKP_MASK 0x3f000000
-#define S6_P2_MASK 0x3f000000
-#define S6_P2_BKP_MASK 0x3f
-#define S7_P2_MASK 0x3f
-#define S7_P2_BKP_MASK 0xfc0
-#define S8_P2_MASK 0xfc0
-#define S8_P2_BKP_MASK 0x3f000
-#define S9_P2_MASK 0x3f000
-#define S9_P2_BKP_MASK 0xfc0000
-#define S10_P2_MASK 0xfc0000
-#define S10_P2_BKP_MASK 0x3f000000
-
-#define BKP_SEL 0x3
-#define BKP_REDUN_SEL 0xe0000000
-#define BKP_REDUN_SHIFT 29
-
-#define BIT_APPEND 0x3
-
-static int calibrate_8974(struct tsens_priv *priv)
-{
- int base1 = 0, base2 = 0, i;
- u32 p1[11], p2[11];
- int mode = 0;
- u32 *calib, *bkp;
- u32 calib_redun_sel;
-
- calib = (u32 *)qfprom_read(priv->dev, "calib");
- if (IS_ERR(calib))
- return PTR_ERR(calib);
-
- bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
- if (IS_ERR(bkp))
- return PTR_ERR(bkp);
-
- calib_redun_sel = bkp[1] & BKP_REDUN_SEL;
- calib_redun_sel >>= BKP_REDUN_SHIFT;
-
- if (calib_redun_sel == BKP_SEL) {
- mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
- mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
-
- switch (mode) {
- case TWO_PT_CALIB:
- base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
- p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
- p2[1] = (bkp[3] & S1_P2_BKP_MASK);
- p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
- p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
- p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
- p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
- p2[6] = (calib[5] & S6_P2_BKP_MASK);
- p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
- p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
- p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
- p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
- /* Fall through */
- case ONE_PT_CALIB:
- case ONE_PT_CALIB2:
- base1 = bkp[0] & BASE1_MASK;
- p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
- p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
- p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
- p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
- p1[4] = (bkp[1] & S4_P1_MASK);
- p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
- p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
- p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
- p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
- p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
- p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
- break;
- }
- } else {
- mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
- mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
-
- switch (mode) {
- case TWO_PT_CALIB:
- base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
- p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
- p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
- p2[2] = (calib[3] & S2_P2_MASK);
- p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
- p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
- p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
- p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
- p2[7] = (calib[4] & S7_P2_MASK);
- p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
- p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
- p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
- /* Fall through */
- case ONE_PT_CALIB:
- case ONE_PT_CALIB2:
- base1 = calib[0] & BASE1_MASK;
- p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
- p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
- p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
- p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
- p1[4] = (calib[1] & S4_P1_MASK);
- p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
- p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
- p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
- p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
- p1[9] = (calib[2] & S9_P1_MASK);
- p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
- break;
- }
- }
-
- switch (mode) {
- case ONE_PT_CALIB:
- for (i = 0; i < priv->num_sensors; i++)
- p1[i] += (base1 << 2) | BIT_APPEND;
- break;
- case TWO_PT_CALIB:
- for (i = 0; i < priv->num_sensors; i++) {
- p2[i] += base2;
- p2[i] <<= 2;
- p2[i] |= BIT_APPEND;
- }
- /* Fall through */
- case ONE_PT_CALIB2:
- for (i = 0; i < priv->num_sensors; i++) {
- p1[i] += base1;
- p1[i] <<= 2;
- p1[i] |= BIT_APPEND;
- }
- break;
- default:
- for (i = 0; i < priv->num_sensors; i++)
- p2[i] = 780;
- p1[0] = 502;
- p1[1] = 509;
- p1[2] = 503;
- p1[3] = 509;
- p1[4] = 505;
- p1[5] = 509;
- p1[6] = 507;
- p1[7] = 510;
- p1[8] = 508;
- p1[9] = 509;
- p1[10] = 508;
- break;
- }
-
- compute_intercept_slope(priv, p1, p2, mode);
-
- return 0;
-}
-
-static const struct tsens_ops ops_8974 = {
- .init = init_common,
- .calibrate = calibrate_8974,
- .get_temp = get_temp_common,
-};
-
-const struct tsens_plat_data data_8974 = {
- .num_sensors = 11,
- .ops = &ops_8974,
- .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
-};
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 30909594b1cf..a6e26be1234f 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -39,6 +39,91 @@
#define MSM8916_CAL_SEL_MASK 0xe0000000
#define MSM8916_CAL_SEL_SHIFT 29

+/* eeprom layout data for 8974 */
+#define BASE1_MASK 0xff
+#define S0_P1_MASK 0x3f00
+#define S1_P1_MASK 0xfc000
+#define S2_P1_MASK 0x3f00000
+#define S3_P1_MASK 0xfc000000
+#define S4_P1_MASK 0x3f
+#define S5_P1_MASK 0xfc0
+#define S6_P1_MASK 0x3f000
+#define S7_P1_MASK 0xfc0000
+#define S8_P1_MASK 0x3f000000
+#define S8_P1_MASK_BKP 0x3f
+#define S9_P1_MASK 0x3f
+#define S9_P1_MASK_BKP 0xfc0
+#define S10_P1_MASK 0xfc0
+#define S10_P1_MASK_BKP 0x3f000
+#define CAL_SEL_0_1 0xc0000000
+#define CAL_SEL_2 0x40000000
+#define CAL_SEL_SHIFT 30
+#define CAL_SEL_SHIFT_2 28
+
+#define S0_P1_SHIFT 8
+#define S1_P1_SHIFT 14
+#define S2_P1_SHIFT 20
+#define S3_P1_SHIFT 26
+#define S5_P1_SHIFT 6
+#define S6_P1_SHIFT 12
+#define S7_P1_SHIFT 18
+#define S8_P1_SHIFT 24
+#define S9_P1_BKP_SHIFT 6
+#define S10_P1_SHIFT 6
+#define S10_P1_BKP_SHIFT 12
+
+#define BASE2_SHIFT 12
+#define BASE2_BKP_SHIFT 18
+#define S0_P2_SHIFT 20
+#define S0_P2_BKP_SHIFT 26
+#define S1_P2_SHIFT 26
+#define S2_P2_BKP_SHIFT 6
+#define S3_P2_SHIFT 6
+#define S3_P2_BKP_SHIFT 12
+#define S4_P2_SHIFT 12
+#define S4_P2_BKP_SHIFT 18
+#define S5_P2_SHIFT 18
+#define S5_P2_BKP_SHIFT 24
+#define S6_P2_SHIFT 24
+#define S7_P2_BKP_SHIFT 6
+#define S8_P2_SHIFT 6
+#define S8_P2_BKP_SHIFT 12
+#define S9_P2_SHIFT 12
+#define S9_P2_BKP_SHIFT 18
+#define S10_P2_SHIFT 18
+#define S10_P2_BKP_SHIFT 24
+
+#define BASE2_MASK 0xff000
+#define BASE2_BKP_MASK 0xfc0000
+#define S0_P2_MASK 0x3f00000
+#define S0_P2_BKP_MASK 0xfc000000
+#define S1_P2_MASK 0xfc000000
+#define S1_P2_BKP_MASK 0x3f
+#define S2_P2_MASK 0x3f
+#define S2_P2_BKP_MASK 0xfc0
+#define S3_P2_MASK 0xfc0
+#define S3_P2_BKP_MASK 0x3f000
+#define S4_P2_MASK 0x3f000
+#define S4_P2_BKP_MASK 0xfc0000
+#define S5_P2_MASK 0xfc0000
+#define S5_P2_BKP_MASK 0x3f000000
+#define S6_P2_MASK 0x3f000000
+#define S6_P2_BKP_MASK 0x3f
+#define S7_P2_MASK 0x3f
+#define S7_P2_BKP_MASK 0xfc0
+#define S8_P2_MASK 0xfc0
+#define S8_P2_BKP_MASK 0x3f000
+#define S9_P2_MASK 0x3f000
+#define S9_P2_BKP_MASK 0xfc0000
+#define S10_P2_MASK 0xfc0000
+#define S10_P2_BKP_MASK 0x3f000000
+
+#define BKP_SEL 0x3
+#define BKP_REDUN_SEL 0xe0000000
+#define BKP_REDUN_SHIFT 29
+
+#define BIT_APPEND 0x3
+
static int calibrate_8916(struct tsens_priv *priv)
{
int base0 = 0, base1 = 0, i;
@@ -91,6 +176,138 @@ static int calibrate_8916(struct tsens_priv *priv)
return 0;
}

+static int calibrate_8974(struct tsens_priv *priv)
+{
+ int base1 = 0, base2 = 0, i;
+ u32 p1[11], p2[11];
+ int mode = 0;
+ u32 *calib, *bkp;
+ u32 calib_redun_sel;
+
+ calib = (u32 *)qfprom_read(priv->dev, "calib");
+ if (IS_ERR(calib))
+ return PTR_ERR(calib);
+
+ bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
+ if (IS_ERR(bkp))
+ return PTR_ERR(bkp);
+
+ calib_redun_sel = bkp[1] & BKP_REDUN_SEL;
+ calib_redun_sel >>= BKP_REDUN_SHIFT;
+
+ if (calib_redun_sel == BKP_SEL) {
+ mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
+ mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
+
+ switch (mode) {
+ case TWO_PT_CALIB:
+ base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
+ p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
+ p2[1] = (bkp[3] & S1_P2_BKP_MASK);
+ p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
+ p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
+ p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
+ p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
+ p2[6] = (calib[5] & S6_P2_BKP_MASK);
+ p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
+ p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
+ p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
+ p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
+ /* Fall through */
+ case ONE_PT_CALIB:
+ case ONE_PT_CALIB2:
+ base1 = bkp[0] & BASE1_MASK;
+ p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+ p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+ p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+ p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
+ p1[4] = (bkp[1] & S4_P1_MASK);
+ p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
+ p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
+ p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
+ p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
+ p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
+ p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
+ break;
+ }
+ } else {
+ mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
+ mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
+
+ switch (mode) {
+ case TWO_PT_CALIB:
+ base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
+ p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
+ p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
+ p2[2] = (calib[3] & S2_P2_MASK);
+ p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
+ p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
+ p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
+ p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
+ p2[7] = (calib[4] & S7_P2_MASK);
+ p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
+ p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
+ p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
+ /* Fall through */
+ case ONE_PT_CALIB:
+ case ONE_PT_CALIB2:
+ base1 = calib[0] & BASE1_MASK;
+ p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+ p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+ p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+ p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
+ p1[4] = (calib[1] & S4_P1_MASK);
+ p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
+ p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
+ p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
+ p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
+ p1[9] = (calib[2] & S9_P1_MASK);
+ p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
+ break;
+ }
+ }
+
+ switch (mode) {
+ case ONE_PT_CALIB:
+ for (i = 0; i < priv->num_sensors; i++)
+ p1[i] += (base1 << 2) | BIT_APPEND;
+ break;
+ case TWO_PT_CALIB:
+ for (i = 0; i < priv->num_sensors; i++) {
+ p2[i] += base2;
+ p2[i] <<= 2;
+ p2[i] |= BIT_APPEND;
+ }
+ /* Fall through */
+ case ONE_PT_CALIB2:
+ for (i = 0; i < priv->num_sensors; i++) {
+ p1[i] += base1;
+ p1[i] <<= 2;
+ p1[i] |= BIT_APPEND;
+ }
+ break;
+ default:
+ for (i = 0; i < priv->num_sensors; i++)
+ p2[i] = 780;
+ p1[0] = 502;
+ p1[1] = 509;
+ p1[2] = 503;
+ p1[3] = 509;
+ p1[4] = 505;
+ p1[5] = 509;
+ p1[6] = 507;
+ p1[7] = 510;
+ p1[8] = 508;
+ p1[9] = 509;
+ p1[10] = 508;
+ break;
+ }
+
+ compute_intercept_slope(priv, p1, p2, mode);
+
+ return 0;
+}
+
static const struct tsens_ops ops_8916 = {
.init = init_common,
.calibrate = calibrate_8916,
@@ -103,3 +320,15 @@ const struct tsens_plat_data data_8916 = {
.reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
.hw_ids = (unsigned int []){0, 1, 2, 4, 5 },
};
+
+static const struct tsens_ops ops_8974 = {
+ .init = init_common,
+ .calibrate = calibrate_8974,
+ .get_temp = get_temp_common,
+};
+
+const struct tsens_plat_data data_8974 = {
+ .num_sensors = 11,
+ .ops = &ops_8974,
+ .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
+};
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 4d6a406f8dca..27b8f74829d9 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -116,8 +116,12 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo
int init_common(struct tsens_priv *priv);
int get_temp_common(struct tsens_priv *priv, int i, int *temp);

-/* TSENS v1 targets */
-extern const struct tsens_plat_data data_8916, data_8974, data_8960;
+/* TSENS target */
+extern const struct tsens_plat_data data_8960;
+
+/* TSENS v0.1 targets */
+extern const struct tsens_plat_data data_8916, data_8974;
+
/* TSENS v2 targets */
extern const struct tsens_plat_data data_8996, data_tsens_v2;

--
2.17.1


2019-03-20 13:20:40

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 08/23] drivers: thermal: tsens: Rename constants to prepare to merge with tsens-8974

Some #defines in tsens-v_0_1.c clash with those in tsens-8974.c. Prefix
them with 8916 to avoid the clash so we can merge the two files.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-v0_1.c | 88 +++++++++++++++----------------
1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index d4ad4082c800..30909594b1cf 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -7,37 +7,37 @@
#include "tsens.h"

/* eeprom layout data for 8916 */
-#define BASE0_MASK 0x0000007f
-#define BASE1_MASK 0xfe000000
-#define BASE0_SHIFT 0
-#define BASE1_SHIFT 25
-
-#define S0_P1_MASK 0x00000f80
-#define S1_P1_MASK 0x003e0000
-#define S2_P1_MASK 0xf8000000
-#define S3_P1_MASK 0x000003e0
-#define S4_P1_MASK 0x000f8000
-
-#define S0_P2_MASK 0x0001f000
-#define S1_P2_MASK 0x07c00000
-#define S2_P2_MASK 0x0000001f
-#define S3_P2_MASK 0x00007c00
-#define S4_P2_MASK 0x01f00000
-
-#define S0_P1_SHIFT 7
-#define S1_P1_SHIFT 17
-#define S2_P1_SHIFT 27
-#define S3_P1_SHIFT 5
-#define S4_P1_SHIFT 15
-
-#define S0_P2_SHIFT 12
-#define S1_P2_SHIFT 22
-#define S2_P2_SHIFT 0
-#define S3_P2_SHIFT 10
-#define S4_P2_SHIFT 20
-
-#define CAL_SEL_MASK 0xe0000000
-#define CAL_SEL_SHIFT 29
+#define MSM8916_BASE0_MASK 0x0000007f
+#define MSM8916_BASE1_MASK 0xfe000000
+#define MSM8916_BASE0_SHIFT 0
+#define MSM8916_BASE1_SHIFT 25
+
+#define MSM8916_S0_P1_MASK 0x00000f80
+#define MSM8916_S1_P1_MASK 0x003e0000
+#define MSM8916_S2_P1_MASK 0xf8000000
+#define MSM8916_S3_P1_MASK 0x000003e0
+#define MSM8916_S4_P1_MASK 0x000f8000
+
+#define MSM8916_S0_P2_MASK 0x0001f000
+#define MSM8916_S1_P2_MASK 0x07c00000
+#define MSM8916_S2_P2_MASK 0x0000001f
+#define MSM8916_S3_P2_MASK 0x00007c00
+#define MSM8916_S4_P2_MASK 0x01f00000
+
+#define MSM8916_S0_P1_SHIFT 7
+#define MSM8916_S1_P1_SHIFT 17
+#define MSM8916_S2_P1_SHIFT 27
+#define MSM8916_S3_P1_SHIFT 5
+#define MSM8916_S4_P1_SHIFT 15
+
+#define MSM8916_S0_P2_SHIFT 12
+#define MSM8916_S1_P2_SHIFT 22
+#define MSM8916_S2_P2_SHIFT 0
+#define MSM8916_S3_P2_SHIFT 10
+#define MSM8916_S4_P2_SHIFT 20
+
+#define MSM8916_CAL_SEL_MASK 0xe0000000
+#define MSM8916_CAL_SEL_SHIFT 29

static int calibrate_8916(struct tsens_priv *priv)
{
@@ -54,27 +54,27 @@ static int calibrate_8916(struct tsens_priv *priv)
if (IS_ERR(qfprom_csel))
return PTR_ERR(qfprom_csel);

- mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
+ mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
dev_dbg(priv->dev, "calibration mode is %d\n", mode);

switch (mode) {
case TWO_PT_CALIB:
- base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
- p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
- p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
- p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
- p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
- p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
+ base1 = (qfprom_cdata[1] & MSM8916_BASE1_MASK) >> MSM8916_BASE1_SHIFT;
+ p2[0] = (qfprom_cdata[0] & MSM8916_S0_P2_MASK) >> MSM8916_S0_P2_SHIFT;
+ p2[1] = (qfprom_cdata[0] & MSM8916_S1_P2_MASK) >> MSM8916_S1_P2_SHIFT;
+ p2[2] = (qfprom_cdata[1] & MSM8916_S2_P2_MASK) >> MSM8916_S2_P2_SHIFT;
+ p2[3] = (qfprom_cdata[1] & MSM8916_S3_P2_MASK) >> MSM8916_S3_P2_SHIFT;
+ p2[4] = (qfprom_cdata[1] & MSM8916_S4_P2_MASK) >> MSM8916_S4_P2_SHIFT;
for (i = 0; i < priv->num_sensors; i++)
p2[i] = ((base1 + p2[i]) << 3);
/* Fall through */
case ONE_PT_CALIB2:
- base0 = (qfprom_cdata[0] & BASE0_MASK);
- p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
- p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
- p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
- p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
- p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
+ base0 = (qfprom_cdata[0] & MSM8916_BASE0_MASK);
+ p1[0] = (qfprom_cdata[0] & MSM8916_S0_P1_MASK) >> MSM8916_S0_P1_SHIFT;
+ p1[1] = (qfprom_cdata[0] & MSM8916_S1_P1_MASK) >> MSM8916_S1_P1_SHIFT;
+ p1[2] = (qfprom_cdata[0] & MSM8916_S2_P1_MASK) >> MSM8916_S2_P1_SHIFT;
+ p1[3] = (qfprom_cdata[1] & MSM8916_S3_P1_MASK) >> MSM8916_S3_P1_SHIFT;
+ p1[4] = (qfprom_cdata[1] & MSM8916_S4_P1_MASK) >> MSM8916_S4_P1_SHIFT;
for (i = 0; i < priv->num_sensors; i++)
p1[i] = (((base0) + p1[i]) << 3);
break;
--
2.17.1


2019-03-20 13:20:41

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 01/23] drivers: thermal: tsens: Document the data structures

Describe how the TSENS device and the various sensors connected to it
are described in the driver

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens.h | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 7b7feee5dc46..89318523c848 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -14,6 +14,16 @@

struct tsens_device;

+/**
+ * struct tsens_sensor - data for each sensor connected to the tsens device
+ * @tmdev: tsens device instance that this sensor is connected to
+ * @tzd: pointer to the thermal zone that this sensor is in
+ * @offset: offset of temperature adjustment curve
+ * @id: Sensor ID
+ * @hw_id: HW ID can be used in case of platform-specific IDs
+ * @slope: slope of temperature adjustment curve
+ * @status: 8960-specific variable to track 8960 and 8660 status register offset
+ */
struct tsens_sensor {
struct tsens_device *tmdev;
struct thermal_zone_device *tzd;
@@ -55,8 +65,8 @@ enum reg_list {
};

/**
- * struct tsens_data - tsens instance specific data
- * @num_sensors: Max number of sensors supported by platform
+ * struct tsens_data - tsens platform data
+ * @num_sensors: Number of sensors supported by platform
* @ops: operations the tsens instance supports
* @hw_ids: Subset of sensors ids supported by platform, if not the first n
* @reg_offsets: Register offsets for commonly used registers
@@ -68,12 +78,27 @@ struct tsens_data {
unsigned int *hw_ids;
};

-/* Registers to be saved/restored across a context loss */
+/**
+ * struct tsens_context - Registers to be saved/restored across a context loss
+ */
struct tsens_context {
int threshold;
int control;
};

+/**
+ * struct tsens_device - private data for each instance of the tsens IP
+ * @dev: pointer to struct device
+ * @num_sensors: number of sensors enabled on this device
+ * @tm_map: pointer to TM register address space
+ * @srot_map: pointer to SROT register address space
+ * @tm_offset: deal with old device trees that don't address TM and SROT
+ * address space separately
+ * @reg_offsets: array of offsets to important regs for this version of IP
+ * @ctx: registers to be saved and restored during suspend/resume
+ * @ops: pointer to list of callbacks supported by this device
+ * @sensor: list of sensors attached to this device
+ */
struct tsens_device {
struct device *dev;
u32 num_sensors;
--
2.17.1


2019-03-20 13:20:56

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 15/23] drivers: thermal: tsens: Introduce IP-specific max_sensor count

The IP can support 'm' sensors while the platform can enable 'n' sensors
of the 'm' where n <= m.

Track maximum sensors supported by the IP so that we can correctly track
what subset of the sensors are supported on the platform.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 4 ++--
drivers/thermal/qcom/tsens-v0_1.c | 1 +
drivers/thermal/qcom/tsens-v2.c | 1 +
drivers/thermal/qcom/tsens.h | 2 ++
4 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index c76f8cfb25a2..5607c5cc635c 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -198,7 +198,7 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}
/* now alloc regmap_fields in tm_map */
- for (i = 0, j = LAST_TEMP_0; i < priv->num_sensors; i++, j++) {
+ for (i = 0, j = LAST_TEMP_0; i < priv->feat->max_sensors; i++, j++) {
priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
priv->fields[j]);
if (IS_ERR(priv->rf[j])) {
@@ -206,7 +206,7 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}
}
- for (i = 0, j = VALID_0; i < priv->num_sensors; i++, j++) {
+ for (i = 0, j = VALID_0; i < priv->feat->max_sensors; i++, j++) {
priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
priv->fields[j]);
if (IS_ERR(priv->rf[j])) {
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 431255bfd0ef..b3a63d7b19ea 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -324,6 +324,7 @@ const struct tsens_features tsens_v0_1_feat = {
.crit_int = 0,
.adc = 1,
.srot_split = 1,
+ .max_sensors = 11,
};

const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 4b98dbe4e3c3..f3eb8661cf7a 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -88,6 +88,7 @@ const struct tsens_features tsens_v2_feat = {
.crit_int = 1,
.adc = 0,
.srot_split = 1,
+ .max_sensors = 16,
};

const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 527c42cfd2d5..080e15a09ac2 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -242,12 +242,14 @@ enum regfield_ids {
* @adc: do the sensors only output adc code (instead of temperature)?
* @srot_split: does the IP neatly splits the register space into SROT and TM,
* with SROT only being available to secure boot firmware?
+ * @max_sensors: maximum sensors supported by this version of the IP
*/
struct tsens_features {
unsigned int ver_major;
unsigned int crit_int:1;
unsigned int adc:1;
unsigned int srot_split:1;
+ unsigned int max_sensors;
};

/**
--
2.17.1


2019-03-20 13:21:10

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 19/23] dt: thermal: tsens: Add bindings for qcs404

qcs404 uses v1 of the TSENS IP block. Create a fallback DT property
"qcom,tsens-v1" to gather common code

Signed-off-by: Amit Kucheria <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/thermal/qcom-tsens.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
index 1d9e8cf61018..673cc1831ee9 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
@@ -6,11 +6,14 @@ Required properties:
- "qcom,msm8916-tsens" (MSM8916)
- "qcom,msm8974-tsens" (MSM8974)
- "qcom,msm8996-tsens" (MSM8996)
+ - "qcom,qcs404-tsens", "qcom,tsens-v1" (QCS404)
- "qcom,msm8998-tsens", "qcom,tsens-v2" (MSM8998)
- "qcom,sdm845-tsens", "qcom,tsens-v2" (SDM845)
The generic "qcom,tsens-v2" property must be used as a fallback for any SoC
with version 2 of the TSENS IP. MSM8996 is the only exception because the
generic property did not exist when support was added.
+ Similarly, the generic "qcom,tsens-v1" property must be used as a fallback for
+ any SoC with version 1 of the TSENS IP.

- reg: Address range of the thermal registers.
New platforms containing v2.x.y of the TSENS IP must specify the SROT and TM
@@ -39,3 +42,14 @@ tsens0: thermal-sensor@c263000 {
#qcom,sensors = <13>;
#thermal-sensor-cells = <1>;
};
+
+Example 3 (for any platform containing v1 of the TSENS IP):
+tsens: thermal-sensor@4a9000 {
+ compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
+ reg = <0x004a9000 0x1000>, /* TM */
+ <0x004a8000 0x1000>; /* SROT */
+ nvmem-cells = <&tsens_caldata>;
+ nvmem-cell-names = "calib";
+ #qcom,sensors = <10>;
+ #thermal-sensor-cells = <1>;
+ };
--
2.17.1


2019-03-20 13:21:14

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 16/23] drivers: thermal: tsens: simplify get_temp_tsens_v2 routine

The current implementation is based on an algorithm published in the
docs. Instead of reading the temperature thrice w/o any explanation,
improve the algorithm.

This will become the basis for a common get_temp routine in the future.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-v2.c | 55 ++++++++++-----------------------
1 file changed, 17 insertions(+), 38 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index f3eb8661cf7a..716d7f827459 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -25,58 +25,37 @@
#define TM_Sn_STATUS_OFF 0x00a0
#define TM_TRDY_OFF 0x00e4

-#define LAST_TEMP_MASK 0xfff
-
-static int get_temp_tsens_v2(struct tsens_priv *priv, int id, int *temp)
+static int get_temp_tsens_v2(struct tsens_priv *priv, int i, int *temp)
{
- struct tsens_sensor *s = &priv->sensor[id];
+ struct tsens_sensor *s = &priv->sensor[i];
u32 temp_idx = LAST_TEMP_0 + s->hw_id;
u32 valid_idx = VALID_0 + s->hw_id;
- u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0, valid;
+ u32 last_temp = 0, valid, mask;
int ret;

- ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
- if (ret)
- return ret;
-
ret = regmap_field_read(priv->rf[valid_idx], &valid);
if (ret)
return ret;
-
- if (valid)
- goto done;
-
- /* Try a second time */
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[temp_idx], &last_temp2);
- if (ret)
- return ret;
- if (valid) {
- last_temp = last_temp2;
- goto done;
+ while (!valid) {
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ */
+ ndelay(400);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
}

- /* Try a third/last time */
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[temp_idx], &last_temp3);
+ /* Valid bit is set, OK to read the temperature */
+ ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
if (ret)
return ret;
- if (valid) {
- last_temp = last_temp3;
- goto done;
- }

- if (last_temp == last_temp2)
- last_temp = last_temp2;
- else if (last_temp2 == last_temp3)
- last_temp = last_temp3;
-done:
+ mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
+ priv->fields[LAST_TEMP_0].lsb);
/* Convert temperature from deciCelsius to milliCelsius */
- *temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100;
+ *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;

return 0;
}
--
2.17.1


2019-03-20 13:21:14

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 10/23] drivers: thermal: tsens: Introduce reg_fields to deal with register description

As we add support for newer versions of the TSENS IP, the current
approach isn't scaling because registers and bitfields get moved around,
requiring platform-specific hacks in the code. By moving to regmap, we
can hide the register level differences away from the code.

Define a common set of registers and bit-fields that we care about
across the various tsens IP versions.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 62 +++++----
drivers/thermal/qcom/tsens-v0_1.c | 50 ++++++-
drivers/thermal/qcom/tsens-v2.c | 105 ++++++++++----
drivers/thermal/qcom/tsens.c | 5 +-
drivers/thermal/qcom/tsens.h | 206 +++++++++++++++++++++++++++-
5 files changed, 370 insertions(+), 58 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index f0ef4e3cf7f9..0f9deec2517a 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -12,13 +12,6 @@
#include <linux/regmap.h>
#include "tsens.h"

-/* SROT */
-#define TSENS_EN BIT(0)
-
-/* TM */
-#define STATUS_OFFSET 0x30
-#define SN_ADDR_OFFSET 0x4
-#define SN_ST_TEMP_MASK 0x3ff
#define CAL_DEGC_PT1 30
#define CAL_DEGC_PT2 120
#define SLOPE_FACTOR 1000
@@ -95,18 +88,14 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
return degc;
}

-int get_temp_common(struct tsens_priv *priv, int id, int *temp)
+int get_temp_common(struct tsens_priv *priv, int i, int *temp)
{
- struct tsens_sensor *s = &priv->sensor[id];
- u32 code;
- unsigned int status_reg;
+ struct tsens_sensor *s = &priv->sensor[i];
int last_temp = 0, ret;

- status_reg = priv->tm_offset + STATUS_OFFSET + s->hw_id * SN_ADDR_OFFSET;
- ret = regmap_read(priv->tm_map, status_reg, &code);
+ ret = regmap_field_read(priv->rf[LAST_TEMP_0 + s->hw_id], &last_temp);
if (ret)
return ret;
- last_temp = code & SN_ST_TEMP_MASK;

*temp = code_to_degc(last_temp, s) * 1000;

@@ -131,10 +120,9 @@ int __init init_common(struct tsens_priv *priv)
{
void __iomem *tm_base, *srot_base;
struct resource *res;
- u32 code;
- int ret;
+ u32 enabled;
+ int ret, i, j;
struct platform_device *op = of_find_device_by_node(priv->dev->of_node);
- u16 ctrl_offset = priv->reg_offsets[SROT_CTRL_OFFSET];

if (!op)
return -EINVAL;
@@ -173,13 +161,41 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}

- if (priv->srot_map) {
- ret = regmap_read(priv->srot_map, ctrl_offset, &code);
- if (ret)
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(priv->dev, priv->srot_map,
+ priv->fields[TSENS_EN]);
+ if (IS_ERR(priv->rf[TSENS_EN])) {
+ ret = PTR_ERR(priv->rf[TSENS_EN]);
+ goto err_put_device;
+ }
+ ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
+ if (ret)
+ goto err_put_device;
+ if (!enabled) {
+ dev_err(priv->dev, "tsens device is not enabled\n");
+ ret = -ENODEV;
+ goto err_put_device;
+ }
+
+ priv->rf[SENSOR_EN] = devm_regmap_field_alloc(priv->dev, priv->srot_map,
+ priv->fields[SENSOR_EN]);
+ if (IS_ERR(priv->rf[SENSOR_EN])) {
+ ret = PTR_ERR(priv->rf[SENSOR_EN]);
+ goto err_put_device;
+ }
+ /* now alloc regmap_fields in tm_map */
+ for (i = 0, j = LAST_TEMP_0; i < priv->num_sensors; i++, j++) {
+ priv->rf[j] = devm_regmap_field_alloc(priv->dev, priv->tm_map,
+ priv->fields[j]);
+ if (IS_ERR(priv->rf[j])) {
+ ret = PTR_ERR(priv->rf[j]);
goto err_put_device;
- if (!(code & TSENS_EN)) {
- dev_err(priv->dev, "tsens device is not enabled\n");
- ret = -ENODEV;
+ }
+ }
+ for (i = 0, j = VALID_0; i < priv->num_sensors; i++, j++) {
+ priv->rf[j] = devm_regmap_field_alloc(priv->dev, priv->tm_map,
+ priv->fields[j]);
+ if (IS_ERR(priv->rf[j])) {
+ ret = PTR_ERR(priv->rf[j]);
goto err_put_device;
}
}
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index a6e26be1234f..d171a4a8c454 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -6,6 +6,15 @@
#include <linux/platform_device.h>
#include "tsens.h"

+/* ----- SROT ------ */
+#define SROT_CTRL_OFF 0x0000
+
+/* ----- TM ------ */
+#define TM_INT_EN_OFF 0x0000
+#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
+#define TM_Sn_STATUS_OFF 0x0030
+#define TM_TRDY_OFF 0x005c
+
/* eeprom layout data for 8916 */
#define MSM8916_BASE0_MASK 0x0000007f
#define MSM8916_BASE1_MASK 0xfe000000
@@ -308,6 +317,40 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0;
}

+/* v0.1: 8916, 8974 */
+
+const struct tsens_features tsens_v0_1_feat = {
+ .ver_major = VER_0_1,
+ .crit_int = 0,
+ .adc = 1,
+ .srot_split = 1,
+};
+
+const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
+ /* ----- SROT ------ */
+ /* No VERSION information */
+
+ /* CTRL_OFFSET */
+ [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
+ [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+
+ /* ----- TM ------ */
+ /* INTERRUPT ENABLE */
+ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
+
+ /* Sn_STATUS */
+ REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
+ /* No VALID field on v0.1 */
+ REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
+ REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
+ REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
+ /* No CRITICAL field on v0.1 */
+ REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
+
+ /* TRDY: 1=ready, 0=in progress */
+ [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
+};
+
static const struct tsens_ops ops_8916 = {
.init = init_common,
.calibrate = calibrate_8916,
@@ -317,8 +360,10 @@ static const struct tsens_ops ops_8916 = {
const struct tsens_plat_data data_8916 = {
.num_sensors = 5,
.ops = &ops_8916,
- .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
.hw_ids = (unsigned int []){0, 1, 2, 4, 5 },
+
+ .feat = &tsens_v0_1_feat,
+ .fields = tsens_v0_1_regfields,
};

static const struct tsens_ops ops_8974 = {
@@ -330,5 +375,6 @@ static const struct tsens_ops ops_8974 = {
const struct tsens_plat_data data_8974 = {
.num_sensors = 11,
.ops = &ops_8974,
- .reg_offsets = { [SROT_CTRL_OFFSET] = 0x0 },
+ .feat = &tsens_v0_1_feat,
+ .fields = tsens_v0_1_regfields,
};
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 8b700772d903..e15a302f7878 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -4,50 +4,70 @@
* Copyright (c) 2018, Linaro Limited
*/

-#include <linux/regmap.h>
#include <linux/bitops.h>
+#include <linux/regmap.h>
#include "tsens.h"

-#define STATUS_OFFSET 0xa0
+/* ----- SROT ------ */
+#define SROT_HW_VER_OFF 0x0000
+#define SROT_CTRL_OFF 0x0004
+
+/* ----- TM ------ */
+#define TM_INT_EN_OFF 0x0004
+#define TM_UPPER_LOWER_INT_STATUS_OFF 0x0008
+#define TM_UPPER_LOWER_INT_CLEAR_OFF 0x000c
+#define TM_UPPER_LOWER_INT_MASK_OFF 0x0010
+#define TM_CRITICAL_INT_STATUS_OFF 0x0014
+#define TM_CRITICAL_INT_CLEAR_OFF 0x0018
+#define TM_CRITICAL_INT_MASK_OFF 0x001c
+#define TM_Sn_UPPER_LOWER_THRESHOLD_OFF 0x0020
+#define TM_Sn_CRITICAL_THRESHOLD_OFF 0x0060
+#define TM_Sn_STATUS_OFF 0x00a0
+#define TM_TRDY_OFF 0x00e4
+
#define LAST_TEMP_MASK 0xfff
-#define STATUS_VALID_BIT BIT(21)

static int get_temp_tsens_v2(struct tsens_priv *priv, int id, int *temp)
{
struct tsens_sensor *s = &priv->sensor[id];
- u32 code;
- unsigned int status_reg;
- u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
+ u32 temp_idx = LAST_TEMP_0 + s->hw_id;
+ u32 valid_idx = VALID_0 + s->hw_id;
+ u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0, valid;
int ret;

- status_reg = priv->tm_offset + STATUS_OFFSET + s->hw_id * 4;
- ret = regmap_read(priv->tm_map, status_reg, &code);
+ ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
+ if (ret)
+ return ret;
+
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
if (ret)
return ret;
- last_temp = code & LAST_TEMP_MASK;
- if (code & STATUS_VALID_BIT)
+
+ if (valid)
goto done;

/* Try a second time */
- ret = regmap_read(priv->tm_map, status_reg, &code);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[temp_idx], &last_temp2);
if (ret)
return ret;
- if (code & STATUS_VALID_BIT) {
- last_temp = code & LAST_TEMP_MASK;
+ if (valid) {
+ last_temp = last_temp2;
goto done;
- } else {
- last_temp2 = code & LAST_TEMP_MASK;
}

/* Try a third/last time */
- ret = regmap_read(priv->tm_map, status_reg, &code);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
if (ret)
return ret;
- if (code & STATUS_VALID_BIT) {
- last_temp = code & LAST_TEMP_MASK;
+ ret = regmap_field_read(priv->rf[temp_idx], &last_temp3);
+ if (ret)
+ return ret;
+ if (valid) {
+ last_temp = last_temp3;
goto done;
- } else {
- last_temp3 = code & LAST_TEMP_MASK;
}

if (last_temp == last_temp2)
@@ -61,19 +81,58 @@ static int get_temp_tsens_v2(struct tsens_priv *priv, int id, int *temp)
return 0;
}

+/* v2.x: 8996, 8998, sdm845 */
+
+const struct tsens_features tsens_v2_feat = {
+ .ver_major = VER_2_X,
+ .crit_int = 1,
+ .adc = 0,
+ .srot_split = 1,
+};
+
+const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
+ /* ----- SROT ------ */
+ /* VERSION */
+ [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
+ [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
+ [VER_STEP] = REG_FIELD(SROT_HW_VER_OFF, 0, 15),
+ /* CTRL_OFF */
+ [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
+ [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+
+ /* ----- TM ------ */
+ /* INTERRUPT ENABLE */
+ /* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */
+ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 2),
+
+ /* Sn_STATUS */
+ REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11),
+ REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21),
+ REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16),
+ REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17),
+ REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS, TM_Sn_STATUS_OFF, 18, 18),
+ REG_FIELD_FOR_EACH_SENSOR16(CRITICAL_STATUS, TM_Sn_STATUS_OFF, 19, 19),
+ REG_FIELD_FOR_EACH_SENSOR16(MAX_STATUS, TM_Sn_STATUS_OFF, 20, 20),
+
+ /* TRDY: 1=ready, 0=in progress */
+ [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
+};
+
static const struct tsens_ops ops_generic_v2 = {
.init = init_common,
.get_temp = get_temp_tsens_v2,
};

const struct tsens_plat_data data_tsens_v2 = {
- .ops = &ops_generic_v2,
- .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
+ .ops = &ops_generic_v2,
+ .feat = &tsens_v2_feat,
+ .fields = tsens_v2_regfields,
};

/* Kept around for backward compatibility with old msm8996.dtsi */
const struct tsens_plat_data data_8996 = {
.num_sensors = 13,
.ops = &ops_generic_v2,
- .reg_offsets = { [SROT_CTRL_OFFSET] = 0x4 },
+ .feat = &tsens_v2_feat,
+ .fields = tsens_v2_regfields,
};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 0b5be08d515f..b91a0b88d33c 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -144,9 +144,8 @@ static int tsens_probe(struct platform_device *pdev)
else
priv->sensor[i].hw_id = i;
}
- for (i = 0; i < REG_ARRAY_SIZE; i++) {
- priv->reg_offsets[i] = data->reg_offsets[i];
- }
+ priv->feat = data->feat;
+ priv->fields = data->fields;

if (!priv->ops || !priv->ops->init || !priv->ops->get_temp)
return -EINVAL;
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 27b8f74829d9..a9390e06b4dd 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -11,9 +11,16 @@
#define TWO_PT_CALIB 0x3

#include <linux/thermal.h>
+#include <linux/regmap.h>

struct tsens_priv;

+enum tsens_ver {
+ VER_0_1 = 0,
+ VER_1_X,
+ VER_2_X,
+};
+
/**
* struct tsens_sensor - data for each sensor connected to the tsens device
* @priv: tsens device instance that this sensor is connected to
@@ -58,10 +65,189 @@ struct tsens_ops {
int (*get_trend)(struct tsens_priv *priv, int i, enum thermal_trend *trend);
};

-enum reg_list {
- SROT_CTRL_OFFSET,
+#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
+ [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
+ [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
+ [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
+ [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
+ [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
+ [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
+ [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
+ [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
+ [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
+ [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
+ [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit)
+
+#define REG_FIELD_FOR_EACH_SENSOR16(_name, _offset, _startbit, _stopbit) \
+ [_name##_##0] = REG_FIELD(_offset, _startbit, _stopbit), \
+ [_name##_##1] = REG_FIELD(_offset + 4, _startbit, _stopbit), \
+ [_name##_##2] = REG_FIELD(_offset + 8, _startbit, _stopbit), \
+ [_name##_##3] = REG_FIELD(_offset + 12, _startbit, _stopbit), \
+ [_name##_##4] = REG_FIELD(_offset + 16, _startbit, _stopbit), \
+ [_name##_##5] = REG_FIELD(_offset + 20, _startbit, _stopbit), \
+ [_name##_##6] = REG_FIELD(_offset + 24, _startbit, _stopbit), \
+ [_name##_##7] = REG_FIELD(_offset + 28, _startbit, _stopbit), \
+ [_name##_##8] = REG_FIELD(_offset + 32, _startbit, _stopbit), \
+ [_name##_##9] = REG_FIELD(_offset + 36, _startbit, _stopbit), \
+ [_name##_##10] = REG_FIELD(_offset + 40, _startbit, _stopbit), \
+ [_name##_##11] = REG_FIELD(_offset + 44, _startbit, _stopbit), \
+ [_name##_##12] = REG_FIELD(_offset + 48, _startbit, _stopbit), \
+ [_name##_##13] = REG_FIELD(_offset + 52, _startbit, _stopbit), \
+ [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \
+ [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit)
+
+/* reg_field IDs to use as an index into an array */
+enum regfield_ids {
+ /* ----- SROT ------ */
+ /* HW_VER */
+ VER_MAJOR = 0,
+ VER_MINOR,
+ VER_STEP,
+ /* CTRL_OFFSET */
+ TSENS_EN = 3,
+ TSENS_SW_RST,
+ SENSOR_EN,
+ CODE_OR_TEMP,
+
+ /* ----- TM ------ */
+ /* STATUS */
+ LAST_TEMP_0 = 7, /* Last temperature reading */
+ LAST_TEMP_1,
+ LAST_TEMP_2,
+ LAST_TEMP_3,
+ LAST_TEMP_4,
+ LAST_TEMP_5,
+ LAST_TEMP_6,
+ LAST_TEMP_7,
+ LAST_TEMP_8,
+ LAST_TEMP_9,
+ LAST_TEMP_10,
+ LAST_TEMP_11,
+ LAST_TEMP_12,
+ LAST_TEMP_13,
+ LAST_TEMP_14,
+ LAST_TEMP_15,
+ VALID_0 = 23, /* VALID reading or not */
+ VALID_1,
+ VALID_2,
+ VALID_3,
+ VALID_4,
+ VALID_5,
+ VALID_6,
+ VALID_7,
+ VALID_8,
+ VALID_9,
+ VALID_10,
+ VALID_11,
+ VALID_12,
+ VALID_13,
+ VALID_14,
+ VALID_15,
+ MIN_STATUS_0, /* MIN threshold violated */
+ MIN_STATUS_1,
+ MIN_STATUS_2,
+ MIN_STATUS_3,
+ MIN_STATUS_4,
+ MIN_STATUS_5,
+ MIN_STATUS_6,
+ MIN_STATUS_7,
+ MIN_STATUS_8,
+ MIN_STATUS_9,
+ MIN_STATUS_10,
+ MIN_STATUS_11,
+ MIN_STATUS_12,
+ MIN_STATUS_13,
+ MIN_STATUS_14,
+ MIN_STATUS_15,
+ MAX_STATUS_0, /* MAX threshold violated */
+ MAX_STATUS_1,
+ MAX_STATUS_2,
+ MAX_STATUS_3,
+ MAX_STATUS_4,
+ MAX_STATUS_5,
+ MAX_STATUS_6,
+ MAX_STATUS_7,
+ MAX_STATUS_8,
+ MAX_STATUS_9,
+ MAX_STATUS_10,
+ MAX_STATUS_11,
+ MAX_STATUS_12,
+ MAX_STATUS_13,
+ MAX_STATUS_14,
+ MAX_STATUS_15,
+ LOWER_STATUS_0, /* LOWER threshold violated */
+ LOWER_STATUS_1,
+ LOWER_STATUS_2,
+ LOWER_STATUS_3,
+ LOWER_STATUS_4,
+ LOWER_STATUS_5,
+ LOWER_STATUS_6,
+ LOWER_STATUS_7,
+ LOWER_STATUS_8,
+ LOWER_STATUS_9,
+ LOWER_STATUS_10,
+ LOWER_STATUS_11,
+ LOWER_STATUS_12,
+ LOWER_STATUS_13,
+ LOWER_STATUS_14,
+ LOWER_STATUS_15,
+ UPPER_STATUS_0, /* UPPER threshold violated */
+ UPPER_STATUS_1,
+ UPPER_STATUS_2,
+ UPPER_STATUS_3,
+ UPPER_STATUS_4,
+ UPPER_STATUS_5,
+ UPPER_STATUS_6,
+ UPPER_STATUS_7,
+ UPPER_STATUS_8,
+ UPPER_STATUS_9,
+ UPPER_STATUS_10,
+ UPPER_STATUS_11,
+ UPPER_STATUS_12,
+ UPPER_STATUS_13,
+ UPPER_STATUS_14,
+ UPPER_STATUS_15,
+ CRITICAL_STATUS_0, /* CRITICAL threshold violated */
+ CRITICAL_STATUS_1,
+ CRITICAL_STATUS_2,
+ CRITICAL_STATUS_3,
+ CRITICAL_STATUS_4,
+ CRITICAL_STATUS_5,
+ CRITICAL_STATUS_6,
+ CRITICAL_STATUS_7,
+ CRITICAL_STATUS_8,
+ CRITICAL_STATUS_9,
+ CRITICAL_STATUS_10,
+ CRITICAL_STATUS_11,
+ CRITICAL_STATUS_12,
+ CRITICAL_STATUS_13,
+ CRITICAL_STATUS_14,
+ CRITICAL_STATUS_15,
+ /* TRDY */
+ TRDY,
+ /* INTERRUPT ENABLE */
+ INT_EN, /* Pre-V1, V1.x */
+ LOW_INT_EN, /* V2.x */
+ UP_INT_EN, /* V2.x */
+ CRIT_INT_EN, /* V2.x */

- REG_ARRAY_SIZE,
+ /* Keep last */
+ MAX_REGFIELDS
+};
+
+/**
+ * struct tsens_features - Features supported by the IP
+ * @ver_major: Major number of IP version
+ * @crit_int: does the IP support critical interrupts?
+ * @adc: do the sensors only output adc code (instead of temperature)?
+ * @srot_split: does the IP neatly splits the register space into SROT and TM,
+ * with SROT only being available to secure boot firmware?
+ */
+struct tsens_features {
+ unsigned int ver_major;
+ unsigned int crit_int:1;
+ unsigned int adc:1;
+ unsigned int srot_split:1;
};

/**
@@ -69,13 +255,15 @@ enum reg_list {
* @num_sensors: Number of sensors supported by platform
* @ops: operations the tsens instance supports
* @hw_ids: Subset of sensors ids supported by platform, if not the first n
- * @reg_offsets: Register offsets for commonly used registers
+ * @feat: features of the IP
+ * @fields: bitfield locations
*/
struct tsens_plat_data {
const u32 num_sensors;
const struct tsens_ops *ops;
- const u16 reg_offsets[REG_ARRAY_SIZE];
unsigned int *hw_ids;
+ const struct tsens_features *feat;
+ const struct reg_field *fields;
};

/**
@@ -94,8 +282,10 @@ struct tsens_context {
* @srot_map: pointer to SROT register address space
* @tm_offset: deal with old device trees that don't address TM and SROT
* address space separately
- * @reg_offsets: array of offsets to important regs for this version of IP
+ * @rf: array of regmap_fields used to store value of the field
* @ctx: registers to be saved and restored during suspend/resume
+ * @feat: features of the IP
+ * @fields: bitfield locations
* @ops: pointer to list of callbacks supported by this device
* @sensor: list of sensors attached to this device
*/
@@ -105,8 +295,10 @@ struct tsens_priv {
struct regmap *tm_map;
struct regmap *srot_map;
u32 tm_offset;
- u16 reg_offsets[REG_ARRAY_SIZE];
+ struct regmap_field *rf[MAX_REGFIELDS];
struct tsens_context ctx;
+ const struct tsens_features *feat;
+ const struct reg_field *fields;
const struct tsens_ops *ops;
struct tsens_sensor sensor[0];
};
--
2.17.1


2019-03-20 13:21:17

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 20/23] drivers: thermal: tsens: Add generic support for TSENS v1 IP

qcs404 has a single TSENS IP block with 10 sensors. It uses version 1.4
of the TSENS IP, functionality for which is encapsulated inside the
qcom,tsens-v1 compatible.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/Makefile | 4 +-
drivers/thermal/qcom/tsens-v1.c | 193 ++++++++++++++++++++++++++++++++
drivers/thermal/qcom/tsens.c | 3 +
drivers/thermal/qcom/tsens.h | 3 +
4 files changed, 202 insertions(+), 1 deletion(-)
create mode 100644 drivers/thermal/qcom/tsens-v1.c

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 7fa3cadce760..fc6fe50cdde4 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
-qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o tsens-8960.o tsens-v2.o
+
+qcom_tsens-y += tsens.o tsens-common.o tsens-v0_1.o \
+ tsens-8960.o tsens-v2.o tsens-v1.o
obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
new file mode 100644
index 000000000000..a1221efd1ddc
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include "tsens.h"
+
+/* ----- SROT ------ */
+#define SROT_HW_VER_OFF 0x0000
+#define SROT_CTRL_OFF 0x0004
+
+/* ----- TM ------ */
+#define TM_INT_EN_OFF 0x0000
+#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
+#define TM_Sn_STATUS_OFF 0x0044
+#define TM_TRDY_OFF 0x0084
+
+/* eeprom layout data for qcs404/405 (v1) */
+#define BASE0_MASK 0x000007f8
+#define BASE1_MASK 0x0007f800
+#define BASE0_SHIFT 3
+#define BASE1_SHIFT 11
+
+#define S0_P1_MASK 0x0000003f
+#define S1_P1_MASK 0x0003f000
+#define S2_P1_MASK 0x3f000000
+#define S3_P1_MASK 0x000003f0
+#define S4_P1_MASK 0x003f0000
+#define S5_P1_MASK 0x0000003f
+#define S6_P1_MASK 0x0003f000
+#define S7_P1_MASK 0x3f000000
+#define S8_P1_MASK 0x000003f0
+#define S9_P1_MASK 0x003f0000
+
+#define S0_P2_MASK 0x00000fc0
+#define S1_P2_MASK 0x00fc0000
+#define S2_P2_MASK_1_0 0xc0000000
+#define S2_P2_MASK_5_2 0x0000000f
+#define S3_P2_MASK 0x0000fc00
+#define S4_P2_MASK 0x0fc00000
+#define S5_P2_MASK 0x00000fc0
+#define S6_P2_MASK 0x00fc0000
+#define S7_P2_MASK_1_0 0xc0000000
+#define S7_P2_MASK_5_2 0x0000000f
+#define S8_P2_MASK 0x0000fc00
+#define S9_P2_MASK 0x0fc00000
+
+#define S0_P1_SHIFT 0
+#define S0_P2_SHIFT 6
+#define S1_P1_SHIFT 12
+#define S1_P2_SHIFT 18
+#define S2_P1_SHIFT 24
+#define S2_P2_SHIFT_1_0 30
+
+#define S2_P2_SHIFT_5_2 0
+#define S3_P1_SHIFT 4
+#define S3_P2_SHIFT 10
+#define S4_P1_SHIFT 16
+#define S4_P2_SHIFT 22
+
+#define S5_P1_SHIFT 0
+#define S5_P2_SHIFT 6
+#define S6_P1_SHIFT 12
+#define S6_P2_SHIFT 18
+#define S7_P1_SHIFT 24
+#define S7_P2_SHIFT_1_0 30
+
+#define S7_P2_SHIFT_5_2 0
+#define S8_P1_SHIFT 4
+#define S8_P2_SHIFT 10
+#define S9_P1_SHIFT 16
+#define S9_P2_SHIFT 22
+
+#define CAL_SEL_MASK 7
+#define CAL_SEL_SHIFT 0
+
+static int calibrate_v1(struct tsens_priv *priv)
+{
+ u32 base0 = 0, base1 = 0;
+ u32 p1[10], p2[10];
+ u32 mode = 0, lsb = 0, msb = 0;
+ u32 *qfprom_cdata;
+ int i;
+
+ qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
+ if (IS_ERR(qfprom_cdata))
+ return PTR_ERR(qfprom_cdata);
+
+ mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
+ dev_dbg(priv->dev, "calibration mode is %d\n", mode);
+
+ switch (mode) {
+ case TWO_PT_CALIB:
+ base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
+ p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
+ p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
+ /* This value is split over two registers, 2 bits and 4 bits */
+ lsb = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
+ msb = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
+ p2[2] = msb << 2 | lsb;
+ p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
+ p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
+ p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
+ p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
+ /* This value is split over two registers, 2 bits and 4 bits */
+ lsb = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
+ msb = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
+ p2[7] = msb << 2 | lsb;
+ p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
+ p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
+ for (i = 0; i < priv->num_sensors; i++)
+ p2[i] = ((base1 + p2[i]) << 2);
+ /* Fall through */
+ case ONE_PT_CALIB2:
+ base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
+ p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+ p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+ p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+ p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
+ p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
+ p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
+ p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
+ p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
+ p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
+ p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
+ for (i = 0; i < priv->num_sensors; i++)
+ p1[i] = (((base0) + p1[i]) << 2);
+ break;
+ default:
+ for (i = 0; i < priv->num_sensors; i++) {
+ p1[i] = 500;
+ p2[i] = 780;
+ }
+ break;
+ }
+
+ compute_intercept_slope(priv, p1, p2, mode);
+
+ return 0;
+}
+
+/* v1.x: qcs404,405 */
+
+const struct tsens_features tsens_v1_feat = {
+ .ver_major = VER_1_X,
+ .crit_int = 0,
+ .adc = 1,
+ .srot_split = 1,
+ .max_sensors = 11,
+};
+
+const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
+ /* ----- SROT ------ */
+ /* VERSION */
+ [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
+ [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
+ [VER_STEP] = REG_FIELD(SROT_HW_VER_OFF, 0, 15),
+ /* CTRL_OFFSET */
+ [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
+ [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+ [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 13),
+
+ /* ----- TM ------ */
+ /* INTERRUPT ENABLE */
+ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
+
+ /* Sn_STATUS */
+ REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
+ REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14),
+ REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
+ REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
+ REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
+ /* No CRITICAL field on v1.x */
+ REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
+
+ /* TRDY: 1=ready, 0=in progress */
+ [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
+};
+
+static const struct tsens_ops ops_generic_v1 = {
+ .init = init_common,
+ .calibrate = calibrate_v1,
+ .get_temp = get_temp_tsens_valid,
+};
+
+const struct tsens_plat_data data_tsens_v1 = {
+ .ops = &ops_generic_v1,
+ .feat = &tsens_v1_feat,
+ .fields = tsens_v1_regfields,
+};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index fc44cac31fa5..36b0b52db524 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -63,6 +63,9 @@ static const struct of_device_id tsens_table[] = {
}, {
.compatible = "qcom,msm8996-tsens",
.data = &data_8996,
+ }, {
+ .compatible = "qcom,tsens-v1",
+ .data = &data_tsens_v1,
}, {
.compatible = "qcom,tsens-v2",
.data = &data_tsens_v2,
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index f14a87aa1a47..d648fba235cf 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -318,6 +318,9 @@ extern const struct tsens_plat_data data_8960;
/* TSENS v0.1 targets */
extern const struct tsens_plat_data data_8916, data_8974;

+/* TSENS v1 targets */
+extern const struct tsens_plat_data data_tsens_v1;
+
/* TSENS v2 targets */
extern const struct tsens_plat_data data_8996, data_tsens_v2;

--
2.17.1


2019-03-20 13:21:21

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 21/23] arm64: dts: qcom: qcs404: Add tsens controller

qcs404 has a single TSENS IP block with 10 sensors. The calibration data
is stored in an eeprom (qfprom) that is accessed through the nvmem
framework. We add the qfprom node to allow the tsens sensors to be
calibrated correctly.

Signed-off-by: Amit Kucheria <[email protected]>
---
arch/arm64/boot/dts/qcom/qcs404.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index e8fd26633d57..7881792980b8 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -259,6 +259,16 @@
reg = <0x00060000 0x6000>;
};

+ qfprom: qfprom@a4000 {
+ compatible = "qcom,qfprom";
+ reg = <0x000a4000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ tsens_caldata: caldata@d0 {
+ reg = <0x1f8 0x14>;
+ };
+ };
+
rng: rng@e3000 {
compatible = "qcom,prng-ee";
reg = <0x000e3000 0x1000>;
@@ -266,6 +276,16 @@
clock-names = "core";
};

+ tsens: thermal-sensor@4a9000 {
+ compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
+ reg = <0x004a9000 0x1000>, /* TM */
+ <0x004a8000 0x1000>; /* SROT */
+ nvmem-cells = <&tsens_caldata>;
+ nvmem-cell-names = "calib";
+ #qcom,sensors = <10>;
+ #thermal-sensor-cells = <1>;
+ };
+
tlmm: pinctrl@1000000 {
compatible = "qcom,qcs404-pinctrl";
reg = <0x01000000 0x200000>,
--
2.17.1


2019-03-20 13:21:23

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 22/23] arm64: dts: qcom: qcs404: Add thermal zones for each sensor

qcs404 has 10 sensors connected to the single TSENS IP. Define a thermal
zone for each of those sensors to expose the temperature of each zone.

Signed-off-by: Amit Kucheria <[email protected]>
---
arch/arm64/boot/dts/qcom/qcs404.dtsi | 252 +++++++++++++++++++++++++++
1 file changed, 252 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index 7881792980b8..2423c816b98d 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-qcs404.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/thermal/thermal.h>

/ {
interrupt-parent = <&intc>;
@@ -31,6 +32,7 @@
reg = <0x100>;
enable-method = "psci";
next-level-cache = <&L2_0>;
+ #cooling-cells= <2>;
};

CPU1: cpu@101 {
@@ -39,6 +41,7 @@
reg = <0x101>;
enable-method = "psci";
next-level-cache = <&L2_0>;
+ #cooling-cells= <2>;
};

CPU2: cpu@102 {
@@ -47,6 +50,7 @@
reg = <0x102>;
enable-method = "psci";
next-level-cache = <&L2_0>;
+ #cooling-cells= <2>;
};

CPU3: cpu@103 {
@@ -55,6 +59,7 @@
reg = <0x103>;
enable-method = "psci";
next-level-cache = <&L2_0>;
+ #cooling-cells= <2>;
};

L2_0: l2-cache {
@@ -866,4 +871,251 @@
#interrupt-cells = <2>;
};
};
+
+ thermal-zones {
+ aoss-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 0>;
+
+ trips {
+ aoss_alert0: trip-point@0 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ };
+ };
+
+ q6-hvx-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 1>;
+
+ trips {
+ q6_hvx_alert0: trip-point@0 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ };
+ };
+
+ lpass-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 2>;
+
+ trips {
+ lpass_alert0: trip-point@0 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ };
+ };
+
+ wlan-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 3>;
+
+ trips {
+ wlan_alert0: trip-point@0 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ };
+ };
+
+ cluster-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 4>;
+
+ trips {
+ cluster_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ cluster_alert1: trip-point@1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cluster_crit: cluster_crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cluster_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 5>;
+
+ trips {
+ cpu0_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ cpu0_alert1: trip-point@1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu0_crit: cpu_crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu0_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 6>;
+
+ trips {
+ cpu1_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ cpu1_alert1: trip-point@1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu1_crit: cpu_crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu1_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu2-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 7>;
+
+ trips {
+ cpu2_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ cpu2_alert1: trip-point@1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu2_crit: cpu_crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu2_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu3-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 8>;
+
+ trips {
+ cpu3_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ cpu3_alert1: trip-point@1 {
+ temperature = <105000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu3_crit: cpu_crit {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ cooling-maps {
+ map0 {
+ trip = <&cpu3_alert1>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ gpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 9>;
+
+ trips {
+ gpu_alert0: trip-point@0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+ };
+ };
+ };
};
--
2.17.1


2019-03-20 13:21:27

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 23/23] drivers: thermal: tsens: Move calibration constants to header file

This will allow calibration routines to correctly include the constants
from anywhere and allow more code sharing.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 5 -----
drivers/thermal/qcom/tsens.h | 5 +++++
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 92747ccb2850..928e8e81ba69 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -12,11 +12,6 @@
#include <linux/regmap.h>
#include "tsens.h"

-#define CAL_DEGC_PT1 30
-#define CAL_DEGC_PT2 120
-#define SLOPE_FACTOR 1000
-#define SLOPE_DEFAULT 3200
-
char *qfprom_read(struct device *dev, const char *cname)
{
struct nvmem_cell *cell;
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index d648fba235cf..eefe3844fb4e 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -9,6 +9,11 @@
#define ONE_PT_CALIB 0x1
#define ONE_PT_CALIB2 0x2
#define TWO_PT_CALIB 0x3
+#define CAL_DEGC_PT1 30
+#define CAL_DEGC_PT2 120
+#define SLOPE_FACTOR 1000
+#define SLOPE_DEFAULT 3200
+

#include <linux/thermal.h>
#include <linux/regmap.h>
--
2.17.1


2019-03-20 13:21:40

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 17/23] drivers: thermal: tsens: Move get_temp_tsens_v2 to allow sharing

Just rename the function and move it to allow code sharing with future
versions of TSENS IP

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 35 +++++++++++++++++++++++++++
drivers/thermal/qcom/tsens-v2.c | 37 +----------------------------
drivers/thermal/qcom/tsens.h | 1 +
3 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 5607c5cc635c..5adbf1a2e0fb 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -102,6 +102,41 @@ static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
return degc;
}

+int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp)
+{
+ struct tsens_sensor *s = &priv->sensor[i];
+ u32 temp_idx = LAST_TEMP_0 + s->hw_id;
+ u32 valid_idx = VALID_0 + s->hw_id;
+ u32 last_temp = 0, valid, mask;
+ int ret;
+
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ while (!valid) {
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ */
+ ndelay(400);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (ret)
+ return ret;
+ }
+
+ /* Valid bit is set, OK to read the temperature */
+ ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
+ if (ret)
+ return ret;
+
+ mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
+ priv->fields[LAST_TEMP_0].lsb);
+ /* Convert temperature from deciCelsius to milliCelsius */
+ *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
+
+ return 0;
+}
+
int get_temp_common(struct tsens_priv *priv, int i, int *temp)
{
struct tsens_sensor *s = &priv->sensor[i];
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 716d7f827459..36fbfa6a471e 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -25,41 +25,6 @@
#define TM_Sn_STATUS_OFF 0x00a0
#define TM_TRDY_OFF 0x00e4

-static int get_temp_tsens_v2(struct tsens_priv *priv, int i, int *temp)
-{
- struct tsens_sensor *s = &priv->sensor[i];
- u32 temp_idx = LAST_TEMP_0 + s->hw_id;
- u32 valid_idx = VALID_0 + s->hw_id;
- u32 last_temp = 0, valid, mask;
- int ret;
-
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- while (!valid) {
- /* Valid bit is 0 for 6 AHB clock cycles.
- * At 19.2MHz, 1 AHB clock is ~60ns.
- * We should enter this loop very, very rarely.
- */
- ndelay(400);
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
- if (ret)
- return ret;
- }
-
- /* Valid bit is set, OK to read the temperature */
- ret = regmap_field_read(priv->rf[temp_idx], &last_temp);
- if (ret)
- return ret;
-
- mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
- priv->fields[LAST_TEMP_0].lsb);
- /* Convert temperature from deciCelsius to milliCelsius */
- *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
-
- return 0;
-}
-
/* v2.x: 8996, 8998, sdm845 */

const struct tsens_features tsens_v2_feat = {
@@ -101,7 +66,7 @@ const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {

static const struct tsens_ops ops_generic_v2 = {
.init = init_common,
- .get_temp = get_temp_tsens_v2,
+ .get_temp = get_temp_tsens_valid,
};

const struct tsens_plat_data data_tsens_v2 = {
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 080e15a09ac2..f14a87aa1a47 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -308,6 +308,7 @@ struct tsens_priv {
char *qfprom_read(struct device *dev, const char *cname);
void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
int init_common(struct tsens_priv *priv);
+int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp);
int get_temp_common(struct tsens_priv *priv, int i, int *temp);
bool is_sensor_enabled(struct tsens_priv *priv, u32 hw_id);

--
2.17.1


2019-03-20 13:21:41

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 18/23] drivers: thermal: tsens: Common get_temp() learns to do ADC conversion

get_temp() learns to return temperature regardless of whether it is
returned as ADC code or direct temperature.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 5adbf1a2e0fb..92747ccb2850 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -129,10 +129,15 @@ int get_temp_tsens_valid(struct tsens_priv *priv, int i, int *temp)
if (ret)
return ret;

- mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
- priv->fields[LAST_TEMP_0].lsb);
- /* Convert temperature from deciCelsius to milliCelsius */
- *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
+ if (priv->feat->adc) {
+ /* Convert temperature from ADC code to milliCelsius */
+ *temp = code_to_degc(last_temp, s) * 1000;
+ } else {
+ mask = GENMASK(priv->fields[LAST_TEMP_0].msb,
+ priv->fields[LAST_TEMP_0].lsb);
+ /* Convert temperature from deciCelsius to milliCelsius */
+ *temp = sign_extend32(last_temp, fls(mask) - 1) * 100;
+ }

return 0;
}
--
2.17.1


2019-03-20 13:21:57

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 14/23] drivers: thermal: tsens: change data type for sensor IDs

The IDs cannot be negative, fix the data type.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index a3bf7de88ae8..527c42cfd2d5 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -35,8 +35,8 @@ struct tsens_sensor {
struct tsens_priv *priv;
struct thermal_zone_device *tzd;
int offset;
- int id;
- int hw_id;
+ unsigned int id;
+ unsigned int hw_id;
int slope;
u32 status;
};
--
2.17.1


2019-03-20 13:22:51

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 11/23] drivers: thermal: tsens: Save reference to the device pointer and use it

Code cleanup making it easier to read

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 0f9deec2517a..9d7a6c328ae0 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -119,6 +119,7 @@ static const struct regmap_config tsens_srot_config = {
int __init init_common(struct tsens_priv *priv)
{
void __iomem *tm_base, *srot_base;
+ struct device *dev = priv->dev;
struct resource *res;
u32 enabled;
int ret, i, j;
@@ -137,7 +138,7 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}

- priv->srot_map = devm_regmap_init_mmio(priv->dev, srot_base,
+ priv->srot_map = devm_regmap_init_mmio(dev, srot_base,
&tsens_srot_config);
if (IS_ERR(priv->srot_map)) {
ret = PTR_ERR(priv->srot_map);
@@ -155,13 +156,13 @@ int __init init_common(struct tsens_priv *priv)
goto err_put_device;
}

- priv->tm_map = devm_regmap_init_mmio(priv->dev, tm_base, &tsens_config);
+ priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config);
if (IS_ERR(priv->tm_map)) {
ret = PTR_ERR(priv->tm_map);
goto err_put_device;
}

- priv->rf[TSENS_EN] = devm_regmap_field_alloc(priv->dev, priv->srot_map,
+ priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
priv->fields[TSENS_EN]);
if (IS_ERR(priv->rf[TSENS_EN])) {
ret = PTR_ERR(priv->rf[TSENS_EN]);
@@ -171,12 +172,12 @@ int __init init_common(struct tsens_priv *priv)
if (ret)
goto err_put_device;
if (!enabled) {
- dev_err(priv->dev, "tsens device is not enabled\n");
+ dev_err(dev, "tsens device is not enabled\n");
ret = -ENODEV;
goto err_put_device;
}

- priv->rf[SENSOR_EN] = devm_regmap_field_alloc(priv->dev, priv->srot_map,
+ priv->rf[SENSOR_EN] = devm_regmap_field_alloc(dev, priv->srot_map,
priv->fields[SENSOR_EN]);
if (IS_ERR(priv->rf[SENSOR_EN])) {
ret = PTR_ERR(priv->rf[SENSOR_EN]);
@@ -184,7 +185,7 @@ int __init init_common(struct tsens_priv *priv)
}
/* now alloc regmap_fields in tm_map */
for (i = 0, j = LAST_TEMP_0; i < priv->num_sensors; i++, j++) {
- priv->rf[j] = devm_regmap_field_alloc(priv->dev, priv->tm_map,
+ priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
priv->fields[j]);
if (IS_ERR(priv->rf[j])) {
ret = PTR_ERR(priv->rf[j]);
@@ -192,7 +193,7 @@ int __init init_common(struct tsens_priv *priv)
}
}
for (i = 0, j = VALID_0; i < priv->num_sensors; i++, j++) {
- priv->rf[j] = devm_regmap_field_alloc(priv->dev, priv->tm_map,
+ priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map,
priv->fields[j]);
if (IS_ERR(priv->rf[j])) {
ret = PTR_ERR(priv->rf[j]);
--
2.17.1


2019-03-20 13:23:28

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 13/23] drivers: thermal: tsens: Add new operation to check if a sensor is enabled

is_sensor_enabled() checks if the sensors are enabled on this platform.
It is possible that the SoC might choose not to enable all the sensors
that the IP block is capable of supporting.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens-common.c | 14 ++++++++++++++
drivers/thermal/qcom/tsens-v0_1.c | 1 +
drivers/thermal/qcom/tsens-v2.c | 1 +
drivers/thermal/qcom/tsens.c | 5 +++++
drivers/thermal/qcom/tsens.h | 1 +
5 files changed, 22 insertions(+)

diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
index 9d7a6c328ae0..c76f8cfb25a2 100644
--- a/drivers/thermal/qcom/tsens-common.c
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -69,6 +69,20 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
}
}

+bool is_sensor_enabled(struct tsens_priv *priv, u32 hw_id)
+{
+ u32 val;
+ int ret;
+
+ if ((hw_id > (priv->num_sensors - 1)) || (hw_id < 0))
+ return -EINVAL;
+ ret = regmap_field_read(priv->rf[SENSOR_EN], &val);
+ if (ret)
+ return ret;
+
+ return val & (1 << hw_id);
+}
+
static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
{
int degc, num, den;
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index d171a4a8c454..431255bfd0ef 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -333,6 +333,7 @@ const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
/* CTRL_OFFSET */
[TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
[TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+ [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 13),

/* ----- TM ------ */
/* INTERRUPT ENABLE */
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index e15a302f7878..4b98dbe4e3c3 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -99,6 +99,7 @@ const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
/* CTRL_OFF */
[TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
[TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
+ [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 18),

/* ----- TM ------ */
/* INTERRUPT ENABLE */
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 057b33353ba3..fc44cac31fa5 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -82,6 +82,11 @@ static int tsens_register(struct tsens_priv *priv)
struct thermal_zone_device *tzd;

for (i = 0; i < priv->num_sensors; i++) {
+ if (!is_sensor_enabled(priv, priv->sensor[i].hw_id)) {
+ dev_err(priv->dev, "sensor %d: disabled\n",
+ priv->sensor[i].hw_id);
+ continue;
+ }
priv->sensor[i].priv = priv;
priv->sensor[i].id = i;
tzd = devm_thermal_zone_of_sensor_register(priv->dev, i,
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index a9390e06b4dd..a3bf7de88ae8 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -307,6 +307,7 @@ char *qfprom_read(struct device *dev, const char *cname);
void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mode);
int init_common(struct tsens_priv *priv);
int get_temp_common(struct tsens_priv *priv, int i, int *temp);
+bool is_sensor_enabled(struct tsens_priv *priv, u32 hw_id);

/* TSENS target */
extern const struct tsens_plat_data data_8960;
--
2.17.1


2019-03-20 14:09:35

by Amit Kucheria

[permalink] [raw]
Subject: [PATCHv3 12/23] drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER

We print a calibration failure message on -EPROBE_DEFER from
nvmem/qfprom as follows:
[ 3.003090] qcom-tsens 4a9000.thermal-sensor: version: 1.4
[ 3.005376] qcom-tsens 4a9000.thermal-sensor: tsens calibration failed
[ 3.113248] qcom-tsens 4a9000.thermal-sensor: version: 1.4

This confuses people when, in fact, calibration succeeds later when
nvmem/qfprom device is available. Don't print this message on a
-EPROBE_DEFER.

Signed-off-by: Amit Kucheria <[email protected]>
---
drivers/thermal/qcom/tsens.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index b91a0b88d33c..057b33353ba3 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -159,7 +159,8 @@ static int tsens_probe(struct platform_device *pdev)
if (priv->ops->calibrate) {
ret = priv->ops->calibrate(priv);
if (ret < 0) {
- dev_err(dev, "tsens calibration failed\n");
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "tsens calibration failed\n");
return ret;
}
}
--
2.17.1


2019-06-24 11:01:14

by Amit Kucheria

[permalink] [raw]
Subject: Re: [PATCHv3 21/23] arm64: dts: qcom: qcs404: Add tsens controller

On Wed, Mar 20, 2019 at 6:50 PM Amit Kucheria <[email protected]> wrote:
>
> qcs404 has a single TSENS IP block with 10 sensors. The calibration data
> is stored in an eeprom (qfprom) that is accessed through the nvmem
> framework. We add the qfprom node to allow the tsens sensors to be
> calibrated correctly.
>
> Signed-off-by: Amit Kucheria <[email protected]>

Hi Bjorn,

Could you please pick this patch and patch 22 in this series if you
have no other review comments? I can resend these separately if
required.

The driver (drivers/thermal/qcom/tsens-v1.c) was merged and only these
DT changes are pending.

Regards,
Amit


> ---
> arch/arm64/boot/dts/qcom/qcs404.dtsi | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
> index e8fd26633d57..7881792980b8 100644
> --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
> +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
> @@ -259,6 +259,16 @@
> reg = <0x00060000 0x6000>;
> };
>
> + qfprom: qfprom@a4000 {
> + compatible = "qcom,qfprom";
> + reg = <0x000a4000 0x1000>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + tsens_caldata: caldata@d0 {
> + reg = <0x1f8 0x14>;
> + };
> + };
> +
> rng: rng@e3000 {
> compatible = "qcom,prng-ee";
> reg = <0x000e3000 0x1000>;
> @@ -266,6 +276,16 @@
> clock-names = "core";
> };
>
> + tsens: thermal-sensor@4a9000 {
> + compatible = "qcom,qcs404-tsens", "qcom,tsens-v1";
> + reg = <0x004a9000 0x1000>, /* TM */
> + <0x004a8000 0x1000>; /* SROT */
> + nvmem-cells = <&tsens_caldata>;
> + nvmem-cell-names = "calib";
> + #qcom,sensors = <10>;
> + #thermal-sensor-cells = <1>;
> + };
> +
> tlmm: pinctrl@1000000 {
> compatible = "qcom,qcs404-pinctrl";
> reg = <0x01000000 0x200000>,
> --
> 2.17.1
>