All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
@ 2018-04-21 15:12 ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

The only capability of the Armada thermal driver is currently just to
read one sensor (the default one) per AP and one per CP.

Actually, there is one sensor per core in the AP806 plus one sensor in
the thermal IP itself. The CP110 just features one thermal sensor in its
own thermal IP.

Also, there is no need for the thermal core to poll the temperature of
each sensor by software as this IP (at least for AP806 and CP110
compatibles) features an hardware overheat interrupt.

This series first improves the readability of this driver, then adds
support for multi-channel thermal IPs, and finally adds support for the
hardware overheat interrupt. The bindings and the device-trees are
updated accordingly.

Please note that the thermal IP raises SEI interrupts, from which the
support as just been contributed and not merged yet. Applying the last
DT patches referring to the 'sei' and 'icu_sei' nodes will require this
feature [1] to have been accepted first.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html

Thank you,
Miquèl


Miquel Raynal (27):
  thermal: armada: add a function that sanitizes the thermal zone name
  thermal: armada: remove useless register accesses
  thermal: armada: remove misleading comments
  thermal: armada: rename the initialization routine
  thermal: armada: dissociate a380 and cp110 ->init() hooks
  thermal: armada: average over samples to avoid glitches
  thermal: armada: convert driver to syscon register accesses
  thermal: armada: use the resource managed registration helper
    alternative
  thermal: armada: add multi-channel sensors support
  thermal: armada: remove sensors validity from the IP initialization
  thermal: armada: move validity check out of the read function
  thermal: armada: get rid of the ->is_valid() pointer
  thermal: armada: add overheat interrupt support
  dt-bindings: cp110: rename cp110 syscon file
  dt-bindings: ap806: prepare the syscon file to list other syscons
    nodes
  dt-bindings: cp110: prepare the syscon file to list other syscons
    nodes
  dt-bindings: ap806: add the thermal node in the syscon file
  dt-bindings: cp110: update documentation since DT de-duplication
  dt-bindings: cp110: add the thermal node in the syscon file
  dt-bindings: thermal: armada: add reference to new bindings
  arm64: dts: marvell: rename ap806 syscon node
  arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
  arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
  arm64: dts: marvell: add macro to make distinction between node names
  arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
  arm64: dts: marvell: add interrupt support to ap806 thermal node
  arm64: dts: marvell: add interrupt support to cp110 thermal node

 .../arm/marvell/ap806-system-controller.txt        |  55 +-
 ...controller0.txt => cp110-system-controller.txt} |  66 +-
 .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
 arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
 drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
 7 files changed, 976 insertions(+), 156 deletions(-)
 rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)

-- 
2.14.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
@ 2018-04-21 15:12 ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

The only capability of the Armada thermal driver is currently just to
read one sensor (the default one) per AP and one per CP.

Actually, there is one sensor per core in the AP806 plus one sensor in
the thermal IP itself. The CP110 just features one thermal sensor in its
own thermal IP.

Also, there is no need for the thermal core to poll the temperature of
each sensor by software as this IP (at least for AP806 and CP110
compatibles) features an hardware overheat interrupt.

This series first improves the readability of this driver, then adds
support for multi-channel thermal IPs, and finally adds support for the
hardware overheat interrupt. The bindings and the device-trees are
updated accordingly.

Please note that the thermal IP raises SEI interrupts, from which the
support as just been contributed and not merged yet. Applying the last
DT patches referring to the 'sei' and 'icu_sei' nodes will require this
feature [1] to have been accepted first.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html

Thank you,
Miqu?l


Miquel Raynal (27):
  thermal: armada: add a function that sanitizes the thermal zone name
  thermal: armada: remove useless register accesses
  thermal: armada: remove misleading comments
  thermal: armada: rename the initialization routine
  thermal: armada: dissociate a380 and cp110 ->init() hooks
  thermal: armada: average over samples to avoid glitches
  thermal: armada: convert driver to syscon register accesses
  thermal: armada: use the resource managed registration helper
    alternative
  thermal: armada: add multi-channel sensors support
  thermal: armada: remove sensors validity from the IP initialization
  thermal: armada: move validity check out of the read function
  thermal: armada: get rid of the ->is_valid() pointer
  thermal: armada: add overheat interrupt support
  dt-bindings: cp110: rename cp110 syscon file
  dt-bindings: ap806: prepare the syscon file to list other syscons
    nodes
  dt-bindings: cp110: prepare the syscon file to list other syscons
    nodes
  dt-bindings: ap806: add the thermal node in the syscon file
  dt-bindings: cp110: update documentation since DT de-duplication
  dt-bindings: cp110: add the thermal node in the syscon file
  dt-bindings: thermal: armada: add reference to new bindings
  arm64: dts: marvell: rename ap806 syscon node
  arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
  arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
  arm64: dts: marvell: add macro to make distinction between node names
  arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
  arm64: dts: marvell: add interrupt support to ap806 thermal node
  arm64: dts: marvell: add interrupt support to cp110 thermal node

 .../arm/marvell/ap806-system-controller.txt        |  55 +-
 ...controller0.txt => cp110-system-controller.txt} |  66 +-
 .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
 arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
 drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
 7 files changed, 976 insertions(+), 156 deletions(-)
 rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)

-- 
2.14.1

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/27] thermal: armada: add a function that sanitizes the thermal zone name
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Thermal zone names must follow certain rules imposed by the framework.
They are limited in length and shall not have any hyphen '-'.

This is done in a separate function for future use in another location.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 4c275ec10ac5..077e8e562306 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -70,6 +70,7 @@ struct armada_thermal_priv {
 	void __iomem *status;
 	void __iomem *control0;
 	void __iomem *control1;
+	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
 };
 
@@ -353,6 +354,36 @@ static const struct of_device_id armada_thermal_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
+static void armada_set_sane_name(struct platform_device *pdev,
+				 struct armada_thermal_priv *priv)
+{
+	const char *name = dev_name(&pdev->dev);
+	char *insane_char;
+
+	if (strlen(name) > THERMAL_NAME_LENGTH) {
+		/*
+		 * When inside a system controller, the device name has the
+		 * form: f06f8000.system-controller:ap-thermal so stripping
+		 * after the ':' should give us a shorter but meaningful name.
+		 */
+		name = strrchr(name, ':');
+		if (!name)
+			name = "armada_thermal";
+		else
+			name++;
+	}
+
+	/* Save the name locally */
+	strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH);
+
+	/* Then check there are no '-' or hwmon core will complain */
+	do {
+		insane_char = strpbrk(priv->zone_name, "-");
+		if (insane_char)
+			*insane_char = '_';
+	} while (insane_char);
+}
+
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	void __iomem *control = NULL;
@@ -381,6 +412,9 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	priv->data = (struct armada_thermal_data *)match->data;
 
+	/* Ensure device name is correct for the thermal core */
+	armada_set_sane_name(pdev, priv);
+
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). New bindings cover
@@ -402,7 +436,7 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	priv->data->init_sensor(pdev, priv);
 
-	thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv,
+	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 					       &ops, NULL, 0, 0);
 	if (IS_ERR(thermal)) {
 		dev_err(&pdev->dev,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 01/27] thermal: armada: add a function that sanitizes the thermal zone name
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Thermal zone names must follow certain rules imposed by the framework.
They are limited in length and shall not have any hyphen '-'.

This is done in a separate function for future use in another location.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 4c275ec10ac5..077e8e562306 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -70,6 +70,7 @@ struct armada_thermal_priv {
 	void __iomem *status;
 	void __iomem *control0;
 	void __iomem *control1;
+	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
 };
 
@@ -353,6 +354,36 @@ static const struct of_device_id armada_thermal_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
+static void armada_set_sane_name(struct platform_device *pdev,
+				 struct armada_thermal_priv *priv)
+{
+	const char *name = dev_name(&pdev->dev);
+	char *insane_char;
+
+	if (strlen(name) > THERMAL_NAME_LENGTH) {
+		/*
+		 * When inside a system controller, the device name has the
+		 * form: f06f8000.system-controller:ap-thermal so stripping
+		 * after the ':' should give us a shorter but meaningful name.
+		 */
+		name = strrchr(name, ':');
+		if (!name)
+			name = "armada_thermal";
+		else
+			name++;
+	}
+
+	/* Save the name locally */
+	strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH);
+
+	/* Then check there are no '-' or hwmon core will complain */
+	do {
+		insane_char = strpbrk(priv->zone_name, "-");
+		if (insane_char)
+			*insane_char = '_';
+	} while (insane_char);
+}
+
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	void __iomem *control = NULL;
@@ -381,6 +412,9 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	priv->data = (struct armada_thermal_data *)match->data;
 
+	/* Ensure device name is correct for the thermal core */
+	armada_set_sane_name(pdev, priv);
+
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). New bindings cover
@@ -402,7 +436,7 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	priv->data->init_sensor(pdev, priv);
 
-	thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv,
+	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 					       &ops, NULL, 0, 0);
 	if (IS_ERR(thermal)) {
 		dev_err(&pdev->dev,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 02/27] thermal: armada: remove useless register accesses
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Prepare the migration to use regmaps by first simplifying the
initialization functions: avoid unnecessary write/read cycles on
configuration registers.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 077e8e562306..6fdb90b3c001 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -103,16 +103,13 @@ static void armadaxp_init_sensor(struct platform_device *pdev,
 
 	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control1);
 
 	/* Reset the sensor */
-	reg = readl_relaxed(priv->control1);
-	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
+	reg |= PMU_TDC0_SW_RST_MASK;
 
 	writel(reg, priv->control1);
 
@@ -129,14 +126,13 @@ static void armada370_init_sensor(struct platform_device *pdev,
 
 	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control1);
 
 	reg &= ~PMU_TDC0_START_CAL_MASK;
+
 	writel(reg, priv->control1);
 
 	msleep(10);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 02/27] thermal: armada: remove useless register accesses
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Prepare the migration to use regmaps by first simplifying the
initialization functions: avoid unnecessary write/read cycles on
configuration registers.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 077e8e562306..6fdb90b3c001 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -103,16 +103,13 @@ static void armadaxp_init_sensor(struct platform_device *pdev,
 
 	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control1);
 
 	/* Reset the sensor */
-	reg = readl_relaxed(priv->control1);
-	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
+	reg |= PMU_TDC0_SW_RST_MASK;
 
 	writel(reg, priv->control1);
 
@@ -129,14 +126,13 @@ static void armada370_init_sensor(struct platform_device *pdev,
 
 	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control1);
 
 	reg &= ~PMU_TDC0_START_CAL_MASK;
+
 	writel(reg, priv->control1);
 
 	msleep(10);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 03/27] thermal: armada: remove misleading comments
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

On older versions of this thermal IP, TSEN referred as the internal
sensor in the thermal IP while EXT_TSEN referred as sensors outside of
this IP, ie in the CPUs most of the time. The bit names in the
specifications do not follow this rule anymore, so remove these comments
that are misleading.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 6fdb90b3c001..18155e43e67f 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -51,12 +51,10 @@
 #define CONTROL0_TSEN_TC_TRIM_MASK	0x7
 #define CONTROL0_TSEN_TC_TRIM_VAL	0x3
 
-/* TSEN refers to the temperature sensors within the AP */
 #define CONTROL0_TSEN_START		BIT(0)
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
 
-/* EXT_TSEN refers to the external temperature sensors, out of the AP */
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 03/27] thermal: armada: remove misleading comments
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

On older versions of this thermal IP, TSEN referred as the internal
sensor in the thermal IP while EXT_TSEN referred as sensors outside of
this IP, ie in the CPUs most of the time. The bit names in the
specifications do not follow this rule anymore, so remove these comments
that are misleading.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 6fdb90b3c001..18155e43e67f 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -51,12 +51,10 @@
 #define CONTROL0_TSEN_TC_TRIM_MASK	0x7
 #define CONTROL0_TSEN_TC_TRIM_VAL	0x3
 
-/* TSEN refers to the temperature sensors within the AP */
 #define CONTROL0_TSEN_START		BIT(0)
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
 
-/* EXT_TSEN refers to the external temperature sensors, out of the AP */
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 04/27] thermal: armada: rename the initialization routine
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Calling a hook ->init_sensor() while what is initialized is the IP
itself and not the sensors is misleading. Rename the hook ->init() to
avoid any confusion in later work bringing multi-sensors support.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 18155e43e67f..3d22a6016b04 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -73,9 +73,9 @@ struct armada_thermal_priv {
 };
 
 struct armada_thermal_data {
-	/* Initialize the sensor */
-	void (*init_sensor)(struct platform_device *pdev,
-			    struct armada_thermal_priv *);
+	/* Initialize the thermal IC */
+	void (*init)(struct platform_device *pdev,
+		     struct armada_thermal_priv *priv);
 
 	/* Test for a valid sensor value (optional) */
 	bool (*is_valid)(struct armada_thermal_priv *);
@@ -94,8 +94,8 @@ struct armada_thermal_data {
 	bool needs_control0;
 };
 
-static void armadaxp_init_sensor(struct platform_device *pdev,
-				 struct armada_thermal_priv *priv)
+static void armadaxp_init(struct platform_device *pdev,
+			  struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -117,8 +117,8 @@ static void armadaxp_init_sensor(struct platform_device *pdev,
 	writel(reg, priv->status);
 }
 
-static void armada370_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada370_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -136,8 +136,8 @@ static void armada370_init_sensor(struct platform_device *pdev,
 	msleep(10);
 }
 
-static void armada375_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada375_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -164,8 +164,8 @@ static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 				   STATUS_POLL_TIMEOUT_US);
 }
 
-static void armada380_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada380_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg = readl_relaxed(priv->control1);
 
@@ -186,8 +186,8 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	armada_wait_sensor_validity(priv);
 }
 
-static void armada_ap806_init_sensor(struct platform_device *pdev,
-				     struct armada_thermal_priv *priv)
+static void armada_ap806_init(struct platform_device *pdev,
+			      struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -247,7 +247,7 @@ static struct thermal_zone_device_ops ops = {
 };
 
 static const struct armada_thermal_data armadaxp_data = {
-	.init_sensor = armadaxp_init_sensor,
+	.init = armadaxp_init,
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
 	.coef_b = 3153000000ULL,
@@ -257,7 +257,7 @@ static const struct armada_thermal_data armadaxp_data = {
 
 static const struct armada_thermal_data armada370_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada370_init_sensor,
+	.init = armada370_init,
 	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
@@ -268,7 +268,7 @@ static const struct armada_thermal_data armada370_data = {
 
 static const struct armada_thermal_data armada375_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada375_init_sensor,
+	.init = armada375_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x1ff,
@@ -280,7 +280,7 @@ static const struct armada_thermal_data armada375_data = {
 
 static const struct armada_thermal_data armada380_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada380_init_sensor,
+	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -292,7 +292,7 @@ static const struct armada_thermal_data armada380_data = {
 
 static const struct armada_thermal_data armada_ap806_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada_ap806_init_sensor,
+	.init = armada_ap806_init,
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -306,7 +306,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 
 static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada380_init_sensor,
+	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -428,7 +428,7 @@ static int armada_thermal_probe(struct platform_device *pdev)
 		priv->control1 = control + CONTROL1_OFFSET;
 	}
 
-	priv->data->init_sensor(pdev, priv);
+	priv->data->init(pdev, priv);
 
 	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 					       &ops, NULL, 0, 0);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 04/27] thermal: armada: rename the initialization routine
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Calling a hook ->init_sensor() while what is initialized is the IP
itself and not the sensors is misleading. Rename the hook ->init() to
avoid any confusion in later work bringing multi-sensors support.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 18155e43e67f..3d22a6016b04 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -73,9 +73,9 @@ struct armada_thermal_priv {
 };
 
 struct armada_thermal_data {
-	/* Initialize the sensor */
-	void (*init_sensor)(struct platform_device *pdev,
-			    struct armada_thermal_priv *);
+	/* Initialize the thermal IC */
+	void (*init)(struct platform_device *pdev,
+		     struct armada_thermal_priv *priv);
 
 	/* Test for a valid sensor value (optional) */
 	bool (*is_valid)(struct armada_thermal_priv *);
@@ -94,8 +94,8 @@ struct armada_thermal_data {
 	bool needs_control0;
 };
 
-static void armadaxp_init_sensor(struct platform_device *pdev,
-				 struct armada_thermal_priv *priv)
+static void armadaxp_init(struct platform_device *pdev,
+			  struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -117,8 +117,8 @@ static void armadaxp_init_sensor(struct platform_device *pdev,
 	writel(reg, priv->status);
 }
 
-static void armada370_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada370_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -136,8 +136,8 @@ static void armada370_init_sensor(struct platform_device *pdev,
 	msleep(10);
 }
 
-static void armada375_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada375_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -164,8 +164,8 @@ static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 				   STATUS_POLL_TIMEOUT_US);
 }
 
-static void armada380_init_sensor(struct platform_device *pdev,
-				  struct armada_thermal_priv *priv)
+static void armada380_init(struct platform_device *pdev,
+			   struct armada_thermal_priv *priv)
 {
 	u32 reg = readl_relaxed(priv->control1);
 
@@ -186,8 +186,8 @@ static void armada380_init_sensor(struct platform_device *pdev,
 	armada_wait_sensor_validity(priv);
 }
 
-static void armada_ap806_init_sensor(struct platform_device *pdev,
-				     struct armada_thermal_priv *priv)
+static void armada_ap806_init(struct platform_device *pdev,
+			      struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
@@ -247,7 +247,7 @@ static struct thermal_zone_device_ops ops = {
 };
 
 static const struct armada_thermal_data armadaxp_data = {
-	.init_sensor = armadaxp_init_sensor,
+	.init = armadaxp_init,
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
 	.coef_b = 3153000000ULL,
@@ -257,7 +257,7 @@ static const struct armada_thermal_data armadaxp_data = {
 
 static const struct armada_thermal_data armada370_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada370_init_sensor,
+	.init = armada370_init,
 	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
@@ -268,7 +268,7 @@ static const struct armada_thermal_data armada370_data = {
 
 static const struct armada_thermal_data armada375_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada375_init_sensor,
+	.init = armada375_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x1ff,
@@ -280,7 +280,7 @@ static const struct armada_thermal_data armada375_data = {
 
 static const struct armada_thermal_data armada380_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada380_init_sensor,
+	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -292,7 +292,7 @@ static const struct armada_thermal_data armada380_data = {
 
 static const struct armada_thermal_data armada_ap806_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada_ap806_init_sensor,
+	.init = armada_ap806_init,
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -306,7 +306,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 
 static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid = armada_is_valid,
-	.init_sensor = armada380_init_sensor,
+	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
@@ -428,7 +428,7 @@ static int armada_thermal_probe(struct platform_device *pdev)
 		priv->control1 = control + CONTROL1_OFFSET;
 	}
 
-	priv->data->init_sensor(pdev, priv);
+	priv->data->init(pdev, priv);
 
 	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 					       &ops, NULL, 0, 0);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 05/27] thermal: armada: dissociate a380 and cp110 ->init() hooks
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Until now, Armada 380 and CP110 could share the same ->init() function
because their use was identical.

Prepare the support of multi-sensors support and overheat interrupt
feature by separating the initialization paths before they actually
diverge.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 3d22a6016b04..9291ea3ad2f7 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -200,6 +200,12 @@ static void armada_ap806_init(struct platform_device *pdev,
 	armada_wait_sensor_validity(priv);
 }
 
+static void armada_cp110_init(struct platform_device *pdev,
+			      struct armada_thermal_priv *priv)
+{
+	armada380_init(pdev, priv);
+}
+
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	u32 reg = readl_relaxed(priv->status);
@@ -306,7 +312,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 
 static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid = armada_is_valid,
-	.init = armada380_init,
+	.init = armada_cp110_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 05/27] thermal: armada: dissociate a380 and cp110 ->init() hooks
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Until now, Armada 380 and CP110 could share the same ->init() function
because their use was identical.

Prepare the support of multi-sensors support and overheat interrupt
feature by separating the initialization paths before they actually
diverge.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 3d22a6016b04..9291ea3ad2f7 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -200,6 +200,12 @@ static void armada_ap806_init(struct platform_device *pdev,
 	armada_wait_sensor_validity(priv);
 }
 
+static void armada_cp110_init(struct platform_device *pdev,
+			      struct armada_thermal_priv *priv)
+{
+	armada380_init(pdev, priv);
+}
+
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	u32 reg = readl_relaxed(priv->status);
@@ -306,7 +312,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 
 static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid = armada_is_valid,
-	.init = armada380_init,
+	.init = armada_cp110_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 06/27] thermal: armada: average over samples to avoid glitches
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Configure the sample frequency and number of averaged samples.

This is needed for two reasons:
1/ To be bootloader independent.
2/ To prepare the introduction of multi-sensors support by preventing
   inconsistencies when reading temperatures that could be a mean of
   samples took from different sensors.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 9291ea3ad2f7..1f9706d96a0d 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -54,7 +54,12 @@
 #define CONTROL0_TSEN_START		BIT(0)
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
+#define CONTROL0_TSEN_AVG_BYPASS	BIT(6)
+#define CONTROL0_TSEN_OSR_SHIFT		24
+#define CONTROL0_TSEN_OSR_MAX		0x3
 
+#define CONTROL1_TSEN_AVG_SHIFT		0
+#define CONTROL1_TSEN_AVG_MASK		0x7
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
 
@@ -194,6 +199,13 @@ static void armada_ap806_init(struct platform_device *pdev,
 	reg = readl_relaxed(priv->control0);
 	reg &= ~CONTROL0_TSEN_RESET;
 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
+
+	/* Sample every ~2ms */
+	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
+
+	/* Enable average (2 samples by default) */
+	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
+
 	writel(reg, priv->control0);
 
 	/* Wait the sensors to be valid or the core will warn the user */
@@ -203,7 +215,20 @@ static void armada_ap806_init(struct platform_device *pdev,
 static void armada_cp110_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	u32 reg;
+
 	armada380_init(pdev, priv);
+
+	/* Sample every ~2ms */
+	reg = readl_relaxed(priv->control0);
+	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
+	writel(reg, priv->control0);
+
+	/* Average the output value over 2^1 = 2 samples */
+	reg = readl_relaxed(priv->control1);
+	reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
+	reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
+	writel(reg, priv->control1);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 06/27] thermal: armada: average over samples to avoid glitches
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Configure the sample frequency and number of averaged samples.

This is needed for two reasons:
1/ To be bootloader independent.
2/ To prepare the introduction of multi-sensors support by preventing
   inconsistencies when reading temperatures that could be a mean of
   samples took from different sensors.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 9291ea3ad2f7..1f9706d96a0d 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -54,7 +54,12 @@
 #define CONTROL0_TSEN_START		BIT(0)
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
+#define CONTROL0_TSEN_AVG_BYPASS	BIT(6)
+#define CONTROL0_TSEN_OSR_SHIFT		24
+#define CONTROL0_TSEN_OSR_MAX		0x3
 
+#define CONTROL1_TSEN_AVG_SHIFT		0
+#define CONTROL1_TSEN_AVG_MASK		0x7
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
 
@@ -194,6 +199,13 @@ static void armada_ap806_init(struct platform_device *pdev,
 	reg = readl_relaxed(priv->control0);
 	reg &= ~CONTROL0_TSEN_RESET;
 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
+
+	/* Sample every ~2ms */
+	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
+
+	/* Enable average (2 samples by default) */
+	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
+
 	writel(reg, priv->control0);
 
 	/* Wait the sensors to be valid or the core will warn the user */
@@ -203,7 +215,20 @@ static void armada_ap806_init(struct platform_device *pdev,
 static void armada_cp110_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	u32 reg;
+
 	armada380_init(pdev, priv);
+
+	/* Sample every ~2ms */
+	reg = readl_relaxed(priv->control0);
+	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
+	writel(reg, priv->control0);
+
+	/* Average the output value over 2^1 = 2 samples */
+	reg = readl_relaxed(priv->control1);
+	reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
+	reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
+	writel(reg, priv->control1);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 07/27] thermal: armada: convert driver to syscon register accesses
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Until recently, only one register was referenced in MVEBU thermal IP
node. Recent changes added a second entry pointing to another
register right next to it. We cannot know for sure that we will not
have to access other registers. That will be actually the case when
overheat interrupt feature will come, where it will be needed to access
DFX registers in the same area.

This approach is not scalable so intead of adding consinuously memory
areas in the DT (and change de DT bindings, while keeping backward
compatibility), move the thermal node into a wider syscon from which it
will be possible to also configure the thermal interrupt.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 197 +++++++++++++++++++++++++--------------
 1 file changed, 128 insertions(+), 69 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 1f9706d96a0d..be346c6afde2 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -24,6 +24,8 @@
 #include <linux/of_device.h>
 #include <linux/thermal.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -39,14 +41,6 @@
 #define A375_READOUT_INVERT		BIT(15)
 #define A375_HW_RESETn			BIT(8)
 
-/* Legacy bindings */
-#define LEGACY_CONTROL_MEM_LEN		0x4
-
-/* Current bindings with the 2 control registers under the same memory area */
-#define LEGACY_CONTROL1_OFFSET		0x0
-#define CONTROL0_OFFSET			0x0
-#define CONTROL1_OFFSET			0x4
-
 /* Errata fields */
 #define CONTROL0_TSEN_TC_TRIM_MASK	0x7
 #define CONTROL0_TSEN_TC_TRIM_VAL	0x3
@@ -70,9 +64,7 @@ struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
-	void __iomem *status;
-	void __iomem *control0;
-	void __iomem *control1;
+	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
 };
@@ -96,15 +88,20 @@ struct armada_thermal_data {
 	unsigned int temp_shift;
 	unsigned int temp_mask;
 	u32 is_valid_bit;
-	bool needs_control0;
+
+	/* Syscon access */
+	unsigned int syscon_control0_off;
+	unsigned int syscon_control1_off;
+	unsigned int syscon_status_off;
 };
 
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
 
 	/* Reference calibration value */
@@ -114,29 +111,31 @@ static void armadaxp_init(struct platform_device *pdev,
 	/* Reset the sensor */
 	reg |= PMU_TDC0_SW_RST_MASK;
 
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	/* Enable the sensor */
-	reg = readl_relaxed(priv->status);
+	regmap_read(priv->syscon, data->syscon_status_off, &reg);
 	reg &= ~PMU_TM_DISABLE_MASK;
-	writel(reg, priv->status);
+	regmap_write(priv->syscon, data->syscon_status_off, reg);
 }
 
 static void armada370_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
 
+	/* Reset the sensor */
 	reg &= ~PMU_TDC0_START_CAL_MASK;
 
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	msleep(10);
 }
@@ -144,18 +143,20 @@ static void armada370_init(struct platform_device *pdev,
 static void armada375_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
 	reg &= ~A375_READOUT_INVERT;
 	reg &= ~A375_HW_RESETn;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
-	writel(reg, priv->control1);
 	msleep(20);
 
 	reg |= A375_HW_RESETn;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
 	msleep(50);
 }
 
@@ -163,29 +164,29 @@ static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
-	readl_relaxed_poll_timeout(priv->status, reg,
-				   reg & priv->data->is_valid_bit,
-				   STATUS_POLL_PERIOD_US,
-				   STATUS_POLL_TIMEOUT_US);
+	regmap_read_poll_timeout(priv->syscon, priv->data->syscon_status_off,
+				 reg, reg & priv->data->is_valid_bit,
+				 STATUS_POLL_PERIOD_US,
+				 STATUS_POLL_TIMEOUT_US);
 }
 
 static void armada380_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
-	u32 reg = readl_relaxed(priv->control1);
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
 
 	/* Disable the HW/SW reset */
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
 	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	/* Set Tsen Tc Trim to correct default value (errata #132698) */
-	if (priv->control0) {
-		reg = readl_relaxed(priv->control0);
-		reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
-		reg |= CONTROL0_TSEN_TC_TRIM_VAL;
-		writel(reg, priv->control0);
-	}
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
+	reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
+	reg |= CONTROL0_TSEN_TC_TRIM_VAL;
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Wait the sensors to be valid or the core will warn the user */
 	armada_wait_sensor_validity(priv);
@@ -194,9 +195,10 @@ static void armada380_init(struct platform_device *pdev,
 static void armada_ap806_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control0);
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
 	reg &= ~CONTROL0_TSEN_RESET;
 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
 
@@ -206,7 +208,7 @@ static void armada_ap806_init(struct platform_device *pdev,
 	/* Enable average (2 samples by default) */
 	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
 
-	writel(reg, priv->control0);
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Wait the sensors to be valid or the core will warn the user */
 	armada_wait_sensor_validity(priv);
@@ -215,25 +217,28 @@ static void armada_ap806_init(struct platform_device *pdev,
 static void armada_cp110_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
 	armada380_init(pdev, priv);
 
 	/* Sample every ~2ms */
-	reg = readl_relaxed(priv->control0);
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
 	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
-	writel(reg, priv->control0);
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Average the output value over 2^1 = 2 samples */
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
 	reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
-	u32 reg = readl_relaxed(priv->status);
+	u32 reg;
+
+	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 
 	return reg & priv->data->is_valid_bit;
 }
@@ -252,7 +257,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 		return -EIO;
 	}
 
-	reg = readl_relaxed(priv->status);
+	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
 	if (priv->data->signed_sample)
 		/* The most significant bit is the sign bit */
@@ -284,6 +289,8 @@ static const struct armada_thermal_data armadaxp_data = {
 	.coef_b = 3153000000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13825,
+	.syscon_status_off = 0xb0,
+	.syscon_control1_off = 0xd0,
 };
 
 static const struct armada_thermal_data armada370_data = {
@@ -295,6 +302,8 @@ static const struct armada_thermal_data armada370_data = {
 	.coef_b = 3153000000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13825,
+	.syscon_status_off = 0x0,
+	.syscon_control1_off = 0x4,
 };
 
 static const struct armada_thermal_data armada375_data = {
@@ -306,7 +315,9 @@ static const struct armada_thermal_data armada375_data = {
 	.coef_b = 3171900000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13616,
-	.needs_control0 = true,
+	.syscon_status_off = 0x78,
+	.syscon_control0_off = 0x7c,
+	.syscon_control1_off = 0x80,
 };
 
 static const struct armada_thermal_data armada380_data = {
@@ -319,6 +330,9 @@ static const struct armada_thermal_data armada380_data = {
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
 	.inverted = true,
+	.syscon_control0_off = 0x70,
+	.syscon_control1_off = 0x74,
+	.syscon_status_off = 0x78,
 };
 
 static const struct armada_thermal_data armada_ap806_data = {
@@ -332,7 +346,9 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.coef_div = 1,
 	.inverted = true,
 	.signed_sample = true,
-	.needs_control0 = true,
+	.syscon_control0_off = 0x84,
+	.syscon_control1_off = 0x88,
+	.syscon_status_off = 0x8C,
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
@@ -345,7 +361,9 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
 	.inverted = true,
-	.needs_control0 = true,
+	.syscon_control0_off = 0x70,
+	.syscon_control1_off = 0x74,
+	.syscon_status_off = 0x78,
 };
 
 static const struct of_device_id armada_thermal_id_table[] = {
@@ -379,6 +397,57 @@ static const struct of_device_id armada_thermal_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
+static const struct regmap_config armada_thermal_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+};
+
+static int armada_thermal_probe_legacy(struct platform_device *pdev,
+				       struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	struct resource *res;
+	void __iomem *base;
+
+	/* First memory region points towards the status register */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	/*
+	 * Edit the resource start address and length to map over all the
+	 * registers, instead of pointing at them one by one.
+	 */
+	res->start -= data->syscon_status_off;
+	res->end = res->start + max(data->syscon_status_off,
+				    max(data->syscon_control0_off,
+					data->syscon_control1_off)) +
+		   sizeof(unsigned int) - 1;
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
+					     &armada_thermal_regmap_config);
+	if (IS_ERR(priv->syscon))
+		return PTR_ERR(priv->syscon);
+
+	return 0;
+}
+
+static int armada_thermal_probe_syscon(struct platform_device *pdev,
+				       struct armada_thermal_priv *priv)
+{
+	priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
+	if (IS_ERR(priv->syscon))
+		return PTR_ERR(priv->syscon);
+
+	return 0;
+}
+
 static void armada_set_sane_name(struct platform_device *pdev,
 				 struct armada_thermal_priv *priv)
 {
@@ -411,11 +480,10 @@ static void armada_set_sane_name(struct platform_device *pdev,
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
-	void __iomem *control = NULL;
 	struct thermal_zone_device *thermal;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
-	struct resource *res;
+	int ret;
 
 	match = of_match_device(armada_thermal_id_table, &pdev->dev);
 	if (!match)
@@ -425,16 +493,6 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->status = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->status))
-		return PTR_ERR(priv->status);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	control = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(control))
-		return PTR_ERR(control);
-
 	priv->data = (struct armada_thermal_data *)match->data;
 
 	/* Ensure device name is correct for the thermal core */
@@ -442,22 +500,23 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
-	 * as "control MSB" on old documentation). New bindings cover
+	 * as "control MSB" on old documentation). Then, bindings moved to cover
 	 * "control0/control LSB" and "control1/control MSB" registers within
-	 * the same resource, which is then of size 8 instead of 4.
+	 * the same resource, which was then of size 8 instead of 4.
+	 *
+	 * The logic of defining sporadic registers is broken. For instance, it
+	 * blocked the addition of the overheat interrupt feature that needed
+	 * another resource somewhere else in the same memory area. One solution
+	 * is to define an overall system controller and put the thermal node
+	 * into it, which requires the use of regmaps across all the driver.
 	 */
-	if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
-		/* ->control0 unavailable in this configuration */
-		if (priv->data->needs_control0) {
-			dev_err(&pdev->dev, "No access to control0 register\n");
-			return -EINVAL;
-		}
+	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node)))
+		ret = armada_thermal_probe_legacy(pdev, priv);
+	else
+		ret = armada_thermal_probe_syscon(pdev, priv);
 
-		priv->control1 = control + LEGACY_CONTROL1_OFFSET;
-	} else {
-		priv->control0 = control + CONTROL0_OFFSET;
-		priv->control1 = control + CONTROL1_OFFSET;
-	}
+	if (ret)
+		return ret;
 
 	priv->data->init(pdev, priv);
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 07/27] thermal: armada: convert driver to syscon register accesses
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Until recently, only one register was referenced in MVEBU thermal IP
node. Recent changes added a second entry pointing to another
register right next to it. We cannot know for sure that we will not
have to access other registers. That will be actually the case when
overheat interrupt feature will come, where it will be needed to access
DFX registers in the same area.

This approach is not scalable so intead of adding consinuously memory
areas in the DT (and change de DT bindings, while keeping backward
compatibility), move the thermal node into a wider syscon from which it
will be possible to also configure the thermal interrupt.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 197 +++++++++++++++++++++++++--------------
 1 file changed, 128 insertions(+), 69 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 1f9706d96a0d..be346c6afde2 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -24,6 +24,8 @@
 #include <linux/of_device.h>
 #include <linux/thermal.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -39,14 +41,6 @@
 #define A375_READOUT_INVERT		BIT(15)
 #define A375_HW_RESETn			BIT(8)
 
-/* Legacy bindings */
-#define LEGACY_CONTROL_MEM_LEN		0x4
-
-/* Current bindings with the 2 control registers under the same memory area */
-#define LEGACY_CONTROL1_OFFSET		0x0
-#define CONTROL0_OFFSET			0x0
-#define CONTROL1_OFFSET			0x4
-
 /* Errata fields */
 #define CONTROL0_TSEN_TC_TRIM_MASK	0x7
 #define CONTROL0_TSEN_TC_TRIM_VAL	0x3
@@ -70,9 +64,7 @@ struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
-	void __iomem *status;
-	void __iomem *control0;
-	void __iomem *control1;
+	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
 };
@@ -96,15 +88,20 @@ struct armada_thermal_data {
 	unsigned int temp_shift;
 	unsigned int temp_mask;
 	u32 is_valid_bit;
-	bool needs_control0;
+
+	/* Syscon access */
+	unsigned int syscon_control0_off;
+	unsigned int syscon_control1_off;
+	unsigned int syscon_status_off;
 };
 
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
 
 	/* Reference calibration value */
@@ -114,29 +111,31 @@ static void armadaxp_init(struct platform_device *pdev,
 	/* Reset the sensor */
 	reg |= PMU_TDC0_SW_RST_MASK;
 
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	/* Enable the sensor */
-	reg = readl_relaxed(priv->status);
+	regmap_read(priv->syscon, data->syscon_status_off, &reg);
 	reg &= ~PMU_TM_DISABLE_MASK;
-	writel(reg, priv->status);
+	regmap_write(priv->syscon, data->syscon_status_off, reg);
 }
 
 static void armada370_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
 
+	/* Reset the sensor */
 	reg &= ~PMU_TDC0_START_CAL_MASK;
 
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	msleep(10);
 }
@@ -144,18 +143,20 @@ static void armada370_init(struct platform_device *pdev,
 static void armada375_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
 	reg &= ~A375_READOUT_INVERT;
 	reg &= ~A375_HW_RESETn;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
-	writel(reg, priv->control1);
 	msleep(20);
 
 	reg |= A375_HW_RESETn;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
 	msleep(50);
 }
 
@@ -163,29 +164,29 @@ static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
-	readl_relaxed_poll_timeout(priv->status, reg,
-				   reg & priv->data->is_valid_bit,
-				   STATUS_POLL_PERIOD_US,
-				   STATUS_POLL_TIMEOUT_US);
+	regmap_read_poll_timeout(priv->syscon, priv->data->syscon_status_off,
+				 reg, reg & priv->data->is_valid_bit,
+				 STATUS_POLL_PERIOD_US,
+				 STATUS_POLL_TIMEOUT_US);
 }
 
 static void armada380_init(struct platform_device *pdev,
 			   struct armada_thermal_priv *priv)
 {
-	u32 reg = readl_relaxed(priv->control1);
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
 
 	/* Disable the HW/SW reset */
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
 	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 
 	/* Set Tsen Tc Trim to correct default value (errata #132698) */
-	if (priv->control0) {
-		reg = readl_relaxed(priv->control0);
-		reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
-		reg |= CONTROL0_TSEN_TC_TRIM_VAL;
-		writel(reg, priv->control0);
-	}
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
+	reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
+	reg |= CONTROL0_TSEN_TC_TRIM_VAL;
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Wait the sensors to be valid or the core will warn the user */
 	armada_wait_sensor_validity(priv);
@@ -194,9 +195,10 @@ static void armada380_init(struct platform_device *pdev,
 static void armada_ap806_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
-	reg = readl_relaxed(priv->control0);
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
 	reg &= ~CONTROL0_TSEN_RESET;
 	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
 
@@ -206,7 +208,7 @@ static void armada_ap806_init(struct platform_device *pdev,
 	/* Enable average (2 samples by default) */
 	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
 
-	writel(reg, priv->control0);
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Wait the sensors to be valid or the core will warn the user */
 	armada_wait_sensor_validity(priv);
@@ -215,25 +217,28 @@ static void armada_ap806_init(struct platform_device *pdev,
 static void armada_cp110_init(struct platform_device *pdev,
 			      struct armada_thermal_priv *priv)
 {
+	struct armada_thermal_data *data = priv->data;
 	u32 reg;
 
 	armada380_init(pdev, priv);
 
 	/* Sample every ~2ms */
-	reg = readl_relaxed(priv->control0);
+	regmap_read(priv->syscon, data->syscon_control0_off, &reg);
 	reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
-	writel(reg, priv->control0);
+	regmap_write(priv->syscon, data->syscon_control0_off, reg);
 
 	/* Average the output value over 2^1 = 2 samples */
-	reg = readl_relaxed(priv->control1);
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
 	reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
 	reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
-	writel(reg, priv->control1);
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
-	u32 reg = readl_relaxed(priv->status);
+	u32 reg;
+
+	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 
 	return reg & priv->data->is_valid_bit;
 }
@@ -252,7 +257,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 		return -EIO;
 	}
 
-	reg = readl_relaxed(priv->status);
+	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
 	if (priv->data->signed_sample)
 		/* The most significant bit is the sign bit */
@@ -284,6 +289,8 @@ static const struct armada_thermal_data armadaxp_data = {
 	.coef_b = 3153000000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13825,
+	.syscon_status_off = 0xb0,
+	.syscon_control1_off = 0xd0,
 };
 
 static const struct armada_thermal_data armada370_data = {
@@ -295,6 +302,8 @@ static const struct armada_thermal_data armada370_data = {
 	.coef_b = 3153000000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13825,
+	.syscon_status_off = 0x0,
+	.syscon_control1_off = 0x4,
 };
 
 static const struct armada_thermal_data armada375_data = {
@@ -306,7 +315,9 @@ static const struct armada_thermal_data armada375_data = {
 	.coef_b = 3171900000ULL,
 	.coef_m = 10000000ULL,
 	.coef_div = 13616,
-	.needs_control0 = true,
+	.syscon_status_off = 0x78,
+	.syscon_control0_off = 0x7c,
+	.syscon_control1_off = 0x80,
 };
 
 static const struct armada_thermal_data armada380_data = {
@@ -319,6 +330,9 @@ static const struct armada_thermal_data armada380_data = {
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
 	.inverted = true,
+	.syscon_control0_off = 0x70,
+	.syscon_control1_off = 0x74,
+	.syscon_status_off = 0x78,
 };
 
 static const struct armada_thermal_data armada_ap806_data = {
@@ -332,7 +346,9 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.coef_div = 1,
 	.inverted = true,
 	.signed_sample = true,
-	.needs_control0 = true,
+	.syscon_control0_off = 0x84,
+	.syscon_control1_off = 0x88,
+	.syscon_status_off = 0x8C,
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
@@ -345,7 +361,9 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
 	.inverted = true,
-	.needs_control0 = true,
+	.syscon_control0_off = 0x70,
+	.syscon_control1_off = 0x74,
+	.syscon_status_off = 0x78,
 };
 
 static const struct of_device_id armada_thermal_id_table[] = {
@@ -379,6 +397,57 @@ static const struct of_device_id armada_thermal_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
+static const struct regmap_config armada_thermal_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+};
+
+static int armada_thermal_probe_legacy(struct platform_device *pdev,
+				       struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	struct resource *res;
+	void __iomem *base;
+
+	/* First memory region points towards the status register */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	/*
+	 * Edit the resource start address and length to map over all the
+	 * registers, instead of pointing at them one by one.
+	 */
+	res->start -= data->syscon_status_off;
+	res->end = res->start + max(data->syscon_status_off,
+				    max(data->syscon_control0_off,
+					data->syscon_control1_off)) +
+		   sizeof(unsigned int) - 1;
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
+					     &armada_thermal_regmap_config);
+	if (IS_ERR(priv->syscon))
+		return PTR_ERR(priv->syscon);
+
+	return 0;
+}
+
+static int armada_thermal_probe_syscon(struct platform_device *pdev,
+				       struct armada_thermal_priv *priv)
+{
+	priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
+	if (IS_ERR(priv->syscon))
+		return PTR_ERR(priv->syscon);
+
+	return 0;
+}
+
 static void armada_set_sane_name(struct platform_device *pdev,
 				 struct armada_thermal_priv *priv)
 {
@@ -411,11 +480,10 @@ static void armada_set_sane_name(struct platform_device *pdev,
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
-	void __iomem *control = NULL;
 	struct thermal_zone_device *thermal;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
-	struct resource *res;
+	int ret;
 
 	match = of_match_device(armada_thermal_id_table, &pdev->dev);
 	if (!match)
@@ -425,16 +493,6 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->status = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->status))
-		return PTR_ERR(priv->status);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	control = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(control))
-		return PTR_ERR(control);
-
 	priv->data = (struct armada_thermal_data *)match->data;
 
 	/* Ensure device name is correct for the thermal core */
@@ -442,22 +500,23 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
-	 * as "control MSB" on old documentation). New bindings cover
+	 * as "control MSB" on old documentation). Then, bindings moved to cover
 	 * "control0/control LSB" and "control1/control MSB" registers within
-	 * the same resource, which is then of size 8 instead of 4.
+	 * the same resource, which was then of size 8 instead of 4.
+	 *
+	 * The logic of defining sporadic registers is broken. For instance, it
+	 * blocked the addition of the overheat interrupt feature that needed
+	 * another resource somewhere else in the same memory area. One solution
+	 * is to define an overall system controller and put the thermal node
+	 * into it, which requires the use of regmaps across all the driver.
 	 */
-	if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
-		/* ->control0 unavailable in this configuration */
-		if (priv->data->needs_control0) {
-			dev_err(&pdev->dev, "No access to control0 register\n");
-			return -EINVAL;
-		}
+	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node)))
+		ret = armada_thermal_probe_legacy(pdev, priv);
+	else
+		ret = armada_thermal_probe_syscon(pdev, priv);
 
-		priv->control1 = control + LEGACY_CONTROL1_OFFSET;
-	} else {
-		priv->control0 = control + CONTROL0_OFFSET;
-		priv->control1 = control + CONTROL1_OFFSET;
-	}
+	if (ret)
+		return ret;
 
 	priv->data->init(pdev, priv);
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 08/27] thermal: armada: use the resource managed registration helper alternative
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Current use of thermal_zone_device_register() triggers a warning at boot
and should be replaced by devm_thermal_zone_of_sensor_register(). This
allows better handling of multiple thermal zones for later multi-sensors
support.

Also change the driver data to embed a new structure to make the
difference between legacy data (which needs to be cleaned) and
syscon-related data.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 128 ++++++++++++++++++++++++++++++++-------
 1 file changed, 107 insertions(+), 21 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index be346c6afde2..8a734264ecdd 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -64,6 +64,7 @@ struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
+	struct device *dev;
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
@@ -95,6 +96,26 @@ struct armada_thermal_data {
 	unsigned int syscon_status_off;
 };
 
+struct armada_drvdata {
+	enum drvtype {
+		LEGACY,
+		SYSCON
+	} type;
+	union {
+		struct armada_thermal_priv *priv;
+		struct thermal_zone_device *tz;
+	} data;
+};
+
+/*
+ * struct armada_thermal_sensor - hold the information of one thermal sensor
+ * @thermal: pointer to the local private structure
+ * @tzd: pointer to the thermal zone device
+ */
+struct armada_thermal_sensor {
+	struct armada_thermal_priv *priv;
+};
+
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
@@ -243,16 +264,14 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
-static int armada_get_temp(struct thermal_zone_device *thermal,
-			   int *temp)
+static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 {
-	struct armada_thermal_priv *priv = thermal->devdata;
 	u32 reg, div;
 	s64 sample, b, m;
 
 	/* Valid check */
 	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
-		dev_err(&thermal->device,
+		dev_err(priv->dev,
 			"Temperature sensor reading not valid\n");
 		return -EIO;
 	}
@@ -278,7 +297,39 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 	return 0;
 }
 
-static struct thermal_zone_device_ops ops = {
+static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
+				  int *temp)
+{
+	struct armada_thermal_priv *priv = thermal->devdata;
+	long temperature;
+	int ret;
+
+	/* Do the actual reading */
+	ret = armada_read_sensor(priv, &temperature);
+	*temp = temperature;
+
+	return ret;
+}
+
+static struct thermal_zone_device_ops legacy_ops = {
+	.get_temp = armada_get_temp_legacy,
+};
+
+static int armada_get_temp(void *_sensor, int *temp)
+{
+	struct armada_thermal_sensor *sensor = _sensor;
+	struct armada_thermal_priv *priv = sensor->priv;
+	long temperature;
+	int ret;
+
+	/* Do the actual reading */
+	ret = armada_read_sensor(priv, &temperature);
+	*temp = temperature;
+
+	return ret;
+}
+
+static struct thermal_zone_of_device_ops of_ops = {
 	.get_temp = armada_get_temp,
 };
 
@@ -480,7 +531,9 @@ static void armada_set_sane_name(struct platform_device *pdev,
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
-	struct thermal_zone_device *thermal;
+	struct thermal_zone_device *tz;
+	struct armada_thermal_sensor *sensors;
+	struct armada_drvdata *drvdata;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
 	int ret;
@@ -493,11 +546,13 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
 	priv->data = (struct armada_thermal_data *)match->data;
 
-	/* Ensure device name is correct for the thermal core */
-	armada_set_sane_name(pdev, priv);
-
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). Then, bindings moved to cover
@@ -510,35 +565,66 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	 * is to define an overall system controller and put the thermal node
 	 * into it, which requires the use of regmaps across all the driver.
 	 */
-	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node)))
+	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) {
+		/* Ensure device name is correct for the thermal core */
+		armada_set_sane_name(pdev, priv);
+
 		ret = armada_thermal_probe_legacy(pdev, priv);
-	else
-		ret = armada_thermal_probe_syscon(pdev, priv);
+		if (ret)
+			return ret;
 
+		priv->data->init(pdev, priv);
+
+		tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
+						  &legacy_ops, NULL, 0, 0);
+		if (IS_ERR(tz)) {
+			dev_err(&pdev->dev,
+				"Failed to register thermal zone device\n");
+			return PTR_ERR(tz);
+		}
+
+		drvdata->type = LEGACY;
+		drvdata->data.tz = tz;
+		platform_set_drvdata(pdev, drvdata);
+
+		return 0;
+	}
+
+	ret = armada_thermal_probe_syscon(pdev, priv);
 	if (ret)
 		return ret;
 
 	priv->data->init(pdev, priv);
 
-	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
-					       &ops, NULL, 0, 0);
-	if (IS_ERR(thermal)) {
+	sensors = devm_kzalloc(&pdev->dev, sizeof(struct armada_thermal_sensor),
+			       GFP_KERNEL);
+	if (!sensors)
+		return -ENOMEM;
+
+	sensors->priv = priv;
+
+	tz = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, sensors,
+						  &of_ops);
+	if (IS_ERR(tz)) {
 		dev_err(&pdev->dev,
-			"Failed to register thermal zone device\n");
-		return PTR_ERR(thermal);
+			"Failed to register thermal sensor (err: %ld)\n",
+			PTR_ERR(tz));
+		return PTR_ERR(tz);
 	}
 
-	platform_set_drvdata(pdev, thermal);
+	drvdata->type = SYSCON;
+	drvdata->data.priv = priv;
+	platform_set_drvdata(pdev, drvdata);
 
 	return 0;
 }
 
 static int armada_thermal_exit(struct platform_device *pdev)
 {
-	struct thermal_zone_device *armada_thermal =
-		platform_get_drvdata(pdev);
+	struct armada_drvdata *drvdata = platform_get_drvdata(pdev);
 
-	thermal_zone_device_unregister(armada_thermal);
+	if (drvdata->type == LEGACY)
+		thermal_zone_device_unregister(drvdata->data.tz);
 
 	return 0;
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 08/27] thermal: armada: use the resource managed registration helper alternative
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Current use of thermal_zone_device_register() triggers a warning at boot
and should be replaced by devm_thermal_zone_of_sensor_register(). This
allows better handling of multiple thermal zones for later multi-sensors
support.

Also change the driver data to embed a new structure to make the
difference between legacy data (which needs to be cleaned) and
syscon-related data.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 128 ++++++++++++++++++++++++++++++++-------
 1 file changed, 107 insertions(+), 21 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index be346c6afde2..8a734264ecdd 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -64,6 +64,7 @@ struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
+	struct device *dev;
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct armada_thermal_data *data;
@@ -95,6 +96,26 @@ struct armada_thermal_data {
 	unsigned int syscon_status_off;
 };
 
+struct armada_drvdata {
+	enum drvtype {
+		LEGACY,
+		SYSCON
+	} type;
+	union {
+		struct armada_thermal_priv *priv;
+		struct thermal_zone_device *tz;
+	} data;
+};
+
+/*
+ * struct armada_thermal_sensor - hold the information of one thermal sensor
+ * @thermal: pointer to the local private structure
+ * @tzd: pointer to the thermal zone device
+ */
+struct armada_thermal_sensor {
+	struct armada_thermal_priv *priv;
+};
+
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
@@ -243,16 +264,14 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
-static int armada_get_temp(struct thermal_zone_device *thermal,
-			   int *temp)
+static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 {
-	struct armada_thermal_priv *priv = thermal->devdata;
 	u32 reg, div;
 	s64 sample, b, m;
 
 	/* Valid check */
 	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
-		dev_err(&thermal->device,
+		dev_err(priv->dev,
 			"Temperature sensor reading not valid\n");
 		return -EIO;
 	}
@@ -278,7 +297,39 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 	return 0;
 }
 
-static struct thermal_zone_device_ops ops = {
+static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
+				  int *temp)
+{
+	struct armada_thermal_priv *priv = thermal->devdata;
+	long temperature;
+	int ret;
+
+	/* Do the actual reading */
+	ret = armada_read_sensor(priv, &temperature);
+	*temp = temperature;
+
+	return ret;
+}
+
+static struct thermal_zone_device_ops legacy_ops = {
+	.get_temp = armada_get_temp_legacy,
+};
+
+static int armada_get_temp(void *_sensor, int *temp)
+{
+	struct armada_thermal_sensor *sensor = _sensor;
+	struct armada_thermal_priv *priv = sensor->priv;
+	long temperature;
+	int ret;
+
+	/* Do the actual reading */
+	ret = armada_read_sensor(priv, &temperature);
+	*temp = temperature;
+
+	return ret;
+}
+
+static struct thermal_zone_of_device_ops of_ops = {
 	.get_temp = armada_get_temp,
 };
 
@@ -480,7 +531,9 @@ static void armada_set_sane_name(struct platform_device *pdev,
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
-	struct thermal_zone_device *thermal;
+	struct thermal_zone_device *tz;
+	struct armada_thermal_sensor *sensors;
+	struct armada_drvdata *drvdata;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
 	int ret;
@@ -493,11 +546,13 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
 	priv->data = (struct armada_thermal_data *)match->data;
 
-	/* Ensure device name is correct for the thermal core */
-	armada_set_sane_name(pdev, priv);
-
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). Then, bindings moved to cover
@@ -510,35 +565,66 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	 * is to define an overall system controller and put the thermal node
 	 * into it, which requires the use of regmaps across all the driver.
 	 */
-	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node)))
+	if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) {
+		/* Ensure device name is correct for the thermal core */
+		armada_set_sane_name(pdev, priv);
+
 		ret = armada_thermal_probe_legacy(pdev, priv);
-	else
-		ret = armada_thermal_probe_syscon(pdev, priv);
+		if (ret)
+			return ret;
 
+		priv->data->init(pdev, priv);
+
+		tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
+						  &legacy_ops, NULL, 0, 0);
+		if (IS_ERR(tz)) {
+			dev_err(&pdev->dev,
+				"Failed to register thermal zone device\n");
+			return PTR_ERR(tz);
+		}
+
+		drvdata->type = LEGACY;
+		drvdata->data.tz = tz;
+		platform_set_drvdata(pdev, drvdata);
+
+		return 0;
+	}
+
+	ret = armada_thermal_probe_syscon(pdev, priv);
 	if (ret)
 		return ret;
 
 	priv->data->init(pdev, priv);
 
-	thermal = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
-					       &ops, NULL, 0, 0);
-	if (IS_ERR(thermal)) {
+	sensors = devm_kzalloc(&pdev->dev, sizeof(struct armada_thermal_sensor),
+			       GFP_KERNEL);
+	if (!sensors)
+		return -ENOMEM;
+
+	sensors->priv = priv;
+
+	tz = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, sensors,
+						  &of_ops);
+	if (IS_ERR(tz)) {
 		dev_err(&pdev->dev,
-			"Failed to register thermal zone device\n");
-		return PTR_ERR(thermal);
+			"Failed to register thermal sensor (err: %ld)\n",
+			PTR_ERR(tz));
+		return PTR_ERR(tz);
 	}
 
-	platform_set_drvdata(pdev, thermal);
+	drvdata->type = SYSCON;
+	drvdata->data.priv = priv;
+	platform_set_drvdata(pdev, drvdata);
 
 	return 0;
 }
 
 static int armada_thermal_exit(struct platform_device *pdev)
 {
-	struct thermal_zone_device *armada_thermal =
-		platform_get_drvdata(pdev);
+	struct armada_drvdata *drvdata = platform_get_drvdata(pdev);
 
-	thermal_zone_device_unregister(armada_thermal);
+	if (drvdata->type == LEGACY)
+		thermal_zone_device_unregister(drvdata->data.tz);
 
 	return 0;
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 09/27] thermal: armada: add multi-channel sensors support
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

MVEBU thermal IP supports multiple channels. Each channel may have
several sensors but for now each channel is wired to only one thermal
sensor. The first channel always points to the so called internal
sensor, within the thermal IP. There is usually one more channel (with
one sensor each time) per CPU. The code has been written to support
possible evolutions of the ap806 IP that would embed more CPUs and thus
more channels to select. Each channel should be referenced in the device
tree as an independent thermal zone.

Add the possibility to read each of these sensors through sysfs by
registering all the sensors (translated in "thermal_zone"). Also add a
mutex on these accesses to avoid read conflicts (only one channel/sensor
may be selected and read at a time).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 130 +++++++++++++++++++++++++++++++++------
 1 file changed, 111 insertions(+), 19 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 8a734264ecdd..2b11bf929b64 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -49,8 +49,13 @@
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
 #define CONTROL0_TSEN_AVG_BYPASS	BIT(6)
+#define CONTROL0_TSEN_CHAN_SHIFT	13
+#define CONTROL0_TSEN_CHAN_MASK		0xF
 #define CONTROL0_TSEN_OSR_SHIFT		24
 #define CONTROL0_TSEN_OSR_MAX		0x3
+#define CONTROL0_TSEN_MODE_SHIFT	30
+#define CONTROL0_TSEN_MODE_EXTERNAL	0x2
+#define CONTROL0_TSEN_MODE_MASK		0x3
 
 #define CONTROL1_TSEN_AVG_SHIFT		0
 #define CONTROL1_TSEN_AVG_MASK		0x7
@@ -67,7 +72,9 @@ struct armada_thermal_priv {
 	struct device *dev;
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
+	struct mutex update_lock;
 	struct armada_thermal_data *data;
+	int current_channel;
 };
 
 struct armada_thermal_data {
@@ -94,6 +101,9 @@ struct armada_thermal_data {
 	unsigned int syscon_control0_off;
 	unsigned int syscon_control1_off;
 	unsigned int syscon_status_off;
+
+	/* One sensor is in the thermal IC, the others are in the CPUs if any */
+	unsigned int cpu_nr;
 };
 
 struct armada_drvdata {
@@ -111,9 +121,11 @@ struct armada_drvdata {
  * struct armada_thermal_sensor - hold the information of one thermal sensor
  * @thermal: pointer to the local private structure
  * @tzd: pointer to the thermal zone device
+ * @id: identifier of the thermal sensor
  */
 struct armada_thermal_sensor {
 	struct armada_thermal_priv *priv;
+	int id;
 };
 
 static void armadaxp_init(struct platform_device *pdev,
@@ -181,14 +193,15 @@ static void armada375_init(struct platform_device *pdev,
 	msleep(50);
 }
 
-static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
+static int armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
-	regmap_read_poll_timeout(priv->syscon, priv->data->syscon_status_off,
-				 reg, reg & priv->data->is_valid_bit,
-				 STATUS_POLL_PERIOD_US,
-				 STATUS_POLL_TIMEOUT_US);
+	return regmap_read_poll_timeout(priv->syscon,
+					priv->data->syscon_status_off, reg,
+					reg & priv->data->is_valid_bit,
+					STATUS_POLL_PERIOD_US,
+					STATUS_POLL_TIMEOUT_US);
 }
 
 static void armada380_init(struct platform_device *pdev,
@@ -264,6 +277,58 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
+/* There is currently no board with more than one sensor per channel */
+static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 ctrl0;
+
+	if (channel < 0 || channel > priv->data->cpu_nr)
+		return -EINVAL;
+
+	if (priv->current_channel == channel)
+		return 0;
+
+	/* Stop the measurements */
+	regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
+	ctrl0 &= ~CONTROL0_TSEN_START;
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+
+	/* Reset the mode, internal sensor will be automatically selected */
+	ctrl0 &= ~(CONTROL0_TSEN_MODE_MASK << CONTROL0_TSEN_MODE_SHIFT);
+
+	/* Other channels are external and should be selected accordingly */
+	if (channel) {
+		/* Change the mode to external */
+		ctrl0 |= CONTROL0_TSEN_MODE_EXTERNAL <<
+			 CONTROL0_TSEN_MODE_SHIFT;
+		/* Select the sensor */
+		ctrl0 &= ~(CONTROL0_TSEN_CHAN_MASK << CONTROL0_TSEN_CHAN_SHIFT);
+		ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT;
+	}
+
+	/* Actually set the mode/channel */
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+	priv->current_channel = channel;
+
+	/* Re-start the measurements */
+	ctrl0 |= CONTROL0_TSEN_START;
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+
+	/*
+	 * The IP has a latency of ~15ms, so after updating the selected source,
+	 * we must absolutely wait for the sensor validity bit to ensure we read
+	 * actual data.
+	 */
+	if (armada_wait_sensor_validity(priv)) {
+		dev_err(priv->dev,
+			"Temperature sensor reading not valid\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 {
 	u32 reg, div;
@@ -322,10 +387,23 @@ static int armada_get_temp(void *_sensor, int *temp)
 	long temperature;
 	int ret;
 
+	mutex_lock(&priv->update_lock);
+
+	/* Select the desired channel */
+	ret = armada_select_channel(priv, sensor->id);
+	if (ret)
+		goto unlock_mutex;
+
 	/* Do the actual reading */
 	ret = armada_read_sensor(priv, &temperature);
+	if (ret)
+		goto unlock_mutex;
+
 	*temp = temperature;
 
+unlock_mutex:
+	mutex_unlock(&priv->update_lock);
+
 	return ret;
 }
 
@@ -400,6 +478,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.syscon_control0_off = 0x84,
 	.syscon_control1_off = 0x88,
 	.syscon_status_off = 0x8C,
+	.cpu_nr = 4,
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
@@ -532,10 +611,11 @@ static void armada_set_sane_name(struct platform_device *pdev,
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	struct thermal_zone_device *tz;
-	struct armada_thermal_sensor *sensors;
+	struct armada_thermal_sensor *sensor;
 	struct armada_drvdata *drvdata;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
+	int sensor_id;
 	int ret;
 
 	match = of_match_device(armada_thermal_id_table, &pdev->dev);
@@ -553,6 +633,8 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	priv->dev = &pdev->dev;
 	priv->data = (struct armada_thermal_data *)match->data;
 
+	mutex_init(&priv->update_lock);
+
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). Then, bindings moved to cover
@@ -594,22 +676,32 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	priv->current_channel = -1;
 	priv->data->init(pdev, priv);
 
-	sensors = devm_kzalloc(&pdev->dev, sizeof(struct armada_thermal_sensor),
-			       GFP_KERNEL);
-	if (!sensors)
-		return -ENOMEM;
+	/*
+	 * There is one channel for the IC and one per CPU (if any), each
+	 * channel has one sensor.
+	 */
+	for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) {
+		sensor = devm_kzalloc(&pdev->dev,
+				      sizeof(struct armada_thermal_sensor),
+				      GFP_KERNEL);
+		if (!sensor)
+			return -ENOMEM;
 
-	sensors->priv = priv;
-
-	tz = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, sensors,
-						  &of_ops);
-	if (IS_ERR(tz)) {
-		dev_err(&pdev->dev,
-			"Failed to register thermal sensor (err: %ld)\n",
-			PTR_ERR(tz));
-		return PTR_ERR(tz);
+		/* Register the sensor */
+		sensor->priv = priv;
+		sensor->id = sensor_id;
+		tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
+							  sensor->id, sensor,
+							  &of_ops);
+		if (IS_ERR(tz)) {
+			dev_info(&pdev->dev, "Thermal sensor %d unavailable\n",
+				 sensor_id);
+			devm_kfree(&pdev->dev, sensor);
+			continue;
+		}
 	}
 
 	drvdata->type = SYSCON;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 09/27] thermal: armada: add multi-channel sensors support
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

MVEBU thermal IP supports multiple channels. Each channel may have
several sensors but for now each channel is wired to only one thermal
sensor. The first channel always points to the so called internal
sensor, within the thermal IP. There is usually one more channel (with
one sensor each time) per CPU. The code has been written to support
possible evolutions of the ap806 IP that would embed more CPUs and thus
more channels to select. Each channel should be referenced in the device
tree as an independent thermal zone.

Add the possibility to read each of these sensors through sysfs by
registering all the sensors (translated in "thermal_zone"). Also add a
mutex on these accesses to avoid read conflicts (only one channel/sensor
may be selected and read at a time).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 130 +++++++++++++++++++++++++++++++++------
 1 file changed, 111 insertions(+), 19 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 8a734264ecdd..2b11bf929b64 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -49,8 +49,13 @@
 #define CONTROL0_TSEN_RESET		BIT(1)
 #define CONTROL0_TSEN_ENABLE		BIT(2)
 #define CONTROL0_TSEN_AVG_BYPASS	BIT(6)
+#define CONTROL0_TSEN_CHAN_SHIFT	13
+#define CONTROL0_TSEN_CHAN_MASK		0xF
 #define CONTROL0_TSEN_OSR_SHIFT		24
 #define CONTROL0_TSEN_OSR_MAX		0x3
+#define CONTROL0_TSEN_MODE_SHIFT	30
+#define CONTROL0_TSEN_MODE_EXTERNAL	0x2
+#define CONTROL0_TSEN_MODE_MASK		0x3
 
 #define CONTROL1_TSEN_AVG_SHIFT		0
 #define CONTROL1_TSEN_AVG_MASK		0x7
@@ -67,7 +72,9 @@ struct armada_thermal_priv {
 	struct device *dev;
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
+	struct mutex update_lock;
 	struct armada_thermal_data *data;
+	int current_channel;
 };
 
 struct armada_thermal_data {
@@ -94,6 +101,9 @@ struct armada_thermal_data {
 	unsigned int syscon_control0_off;
 	unsigned int syscon_control1_off;
 	unsigned int syscon_status_off;
+
+	/* One sensor is in the thermal IC, the others are in the CPUs if any */
+	unsigned int cpu_nr;
 };
 
 struct armada_drvdata {
@@ -111,9 +121,11 @@ struct armada_drvdata {
  * struct armada_thermal_sensor - hold the information of one thermal sensor
  * @thermal: pointer to the local private structure
  * @tzd: pointer to the thermal zone device
+ * @id: identifier of the thermal sensor
  */
 struct armada_thermal_sensor {
 	struct armada_thermal_priv *priv;
+	int id;
 };
 
 static void armadaxp_init(struct platform_device *pdev,
@@ -181,14 +193,15 @@ static void armada375_init(struct platform_device *pdev,
 	msleep(50);
 }
 
-static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
+static int armada_wait_sensor_validity(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
-	regmap_read_poll_timeout(priv->syscon, priv->data->syscon_status_off,
-				 reg, reg & priv->data->is_valid_bit,
-				 STATUS_POLL_PERIOD_US,
-				 STATUS_POLL_TIMEOUT_US);
+	return regmap_read_poll_timeout(priv->syscon,
+					priv->data->syscon_status_off, reg,
+					reg & priv->data->is_valid_bit,
+					STATUS_POLL_PERIOD_US,
+					STATUS_POLL_TIMEOUT_US);
 }
 
 static void armada380_init(struct platform_device *pdev,
@@ -264,6 +277,58 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
+/* There is currently no board with more than one sensor per channel */
+static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 ctrl0;
+
+	if (channel < 0 || channel > priv->data->cpu_nr)
+		return -EINVAL;
+
+	if (priv->current_channel == channel)
+		return 0;
+
+	/* Stop the measurements */
+	regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
+	ctrl0 &= ~CONTROL0_TSEN_START;
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+
+	/* Reset the mode, internal sensor will be automatically selected */
+	ctrl0 &= ~(CONTROL0_TSEN_MODE_MASK << CONTROL0_TSEN_MODE_SHIFT);
+
+	/* Other channels are external and should be selected accordingly */
+	if (channel) {
+		/* Change the mode to external */
+		ctrl0 |= CONTROL0_TSEN_MODE_EXTERNAL <<
+			 CONTROL0_TSEN_MODE_SHIFT;
+		/* Select the sensor */
+		ctrl0 &= ~(CONTROL0_TSEN_CHAN_MASK << CONTROL0_TSEN_CHAN_SHIFT);
+		ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT;
+	}
+
+	/* Actually set the mode/channel */
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+	priv->current_channel = channel;
+
+	/* Re-start the measurements */
+	ctrl0 |= CONTROL0_TSEN_START;
+	regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
+
+	/*
+	 * The IP has a latency of ~15ms, so after updating the selected source,
+	 * we must absolutely wait for the sensor validity bit to ensure we read
+	 * actual data.
+	 */
+	if (armada_wait_sensor_validity(priv)) {
+		dev_err(priv->dev,
+			"Temperature sensor reading not valid\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 {
 	u32 reg, div;
@@ -322,10 +387,23 @@ static int armada_get_temp(void *_sensor, int *temp)
 	long temperature;
 	int ret;
 
+	mutex_lock(&priv->update_lock);
+
+	/* Select the desired channel */
+	ret = armada_select_channel(priv, sensor->id);
+	if (ret)
+		goto unlock_mutex;
+
 	/* Do the actual reading */
 	ret = armada_read_sensor(priv, &temperature);
+	if (ret)
+		goto unlock_mutex;
+
 	*temp = temperature;
 
+unlock_mutex:
+	mutex_unlock(&priv->update_lock);
+
 	return ret;
 }
 
@@ -400,6 +478,7 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.syscon_control0_off = 0x84,
 	.syscon_control1_off = 0x88,
 	.syscon_status_off = 0x8C,
+	.cpu_nr = 4,
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
@@ -532,10 +611,11 @@ static void armada_set_sane_name(struct platform_device *pdev,
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	struct thermal_zone_device *tz;
-	struct armada_thermal_sensor *sensors;
+	struct armada_thermal_sensor *sensor;
 	struct armada_drvdata *drvdata;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
+	int sensor_id;
 	int ret;
 
 	match = of_match_device(armada_thermal_id_table, &pdev->dev);
@@ -553,6 +633,8 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	priv->dev = &pdev->dev;
 	priv->data = (struct armada_thermal_data *)match->data;
 
+	mutex_init(&priv->update_lock);
+
 	/*
 	 * Legacy DT bindings only described "control1" register (also referred
 	 * as "control MSB" on old documentation). Then, bindings moved to cover
@@ -594,22 +676,32 @@ static int armada_thermal_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	priv->current_channel = -1;
 	priv->data->init(pdev, priv);
 
-	sensors = devm_kzalloc(&pdev->dev, sizeof(struct armada_thermal_sensor),
-			       GFP_KERNEL);
-	if (!sensors)
-		return -ENOMEM;
+	/*
+	 * There is one channel for the IC and one per CPU (if any), each
+	 * channel has one sensor.
+	 */
+	for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) {
+		sensor = devm_kzalloc(&pdev->dev,
+				      sizeof(struct armada_thermal_sensor),
+				      GFP_KERNEL);
+		if (!sensor)
+			return -ENOMEM;
 
-	sensors->priv = priv;
-
-	tz = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, sensors,
-						  &of_ops);
-	if (IS_ERR(tz)) {
-		dev_err(&pdev->dev,
-			"Failed to register thermal sensor (err: %ld)\n",
-			PTR_ERR(tz));
-		return PTR_ERR(tz);
+		/* Register the sensor */
+		sensor->priv = priv;
+		sensor->id = sensor_id;
+		tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
+							  sensor->id, sensor,
+							  &of_ops);
+		if (IS_ERR(tz)) {
+			dev_info(&pdev->dev, "Thermal sensor %d unavailable\n",
+				 sensor_id);
+			devm_kfree(&pdev->dev, sensor);
+			continue;
+		}
 	}
 
 	drvdata->type = SYSCON;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 10/27] thermal: armada: remove sensors validity from the IP initialization
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

When using new bindings with multiple sensors, sensor validity is
checked twice because sensor selection also checks for the validity.

Remove the redundant call from the IP initialization helper and move it
to the legacy probe section where it is still needed.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 2b11bf929b64..3d5b29133d3a 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -221,9 +221,6 @@ static void armada380_init(struct platform_device *pdev,
 	reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
 	reg |= CONTROL0_TSEN_TC_TRIM_VAL;
 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
-
-	/* Wait the sensors to be valid or the core will warn the user */
-	armada_wait_sensor_validity(priv);
 }
 
 static void armada_ap806_init(struct platform_device *pdev,
@@ -243,9 +240,6 @@ static void armada_ap806_init(struct platform_device *pdev,
 	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
 
 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
-
-	/* Wait the sensors to be valid or the core will warn the user */
-	armada_wait_sensor_validity(priv);
 }
 
 static void armada_cp110_init(struct platform_device *pdev,
@@ -657,6 +651,9 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 		priv->data->init(pdev, priv);
 
+		/* Wait the sensors to be valid */
+		armada_wait_sensor_validity(priv);
+
 		tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 						  &legacy_ops, NULL, 0, 0);
 		if (IS_ERR(tz)) {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 10/27] thermal: armada: remove sensors validity from the IP initialization
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

When using new bindings with multiple sensors, sensor validity is
checked twice because sensor selection also checks for the validity.

Remove the redundant call from the IP initialization helper and move it
to the legacy probe section where it is still needed.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 2b11bf929b64..3d5b29133d3a 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -221,9 +221,6 @@ static void armada380_init(struct platform_device *pdev,
 	reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
 	reg |= CONTROL0_TSEN_TC_TRIM_VAL;
 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
-
-	/* Wait the sensors to be valid or the core will warn the user */
-	armada_wait_sensor_validity(priv);
 }
 
 static void armada_ap806_init(struct platform_device *pdev,
@@ -243,9 +240,6 @@ static void armada_ap806_init(struct platform_device *pdev,
 	reg &= ~CONTROL0_TSEN_AVG_BYPASS;
 
 	regmap_write(priv->syscon, data->syscon_control0_off, reg);
-
-	/* Wait the sensors to be valid or the core will warn the user */
-	armada_wait_sensor_validity(priv);
 }
 
 static void armada_cp110_init(struct platform_device *pdev,
@@ -657,6 +651,9 @@ static int armada_thermal_probe(struct platform_device *pdev)
 
 		priv->data->init(pdev, priv);
 
+		/* Wait the sensors to be valid */
+		armada_wait_sensor_validity(priv);
+
 		tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
 						  &legacy_ops, NULL, 0, 0);
 		if (IS_ERR(tz)) {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 11/27] thermal: armada: move validity check out of the read function
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Sensor selection when using multiple sensors already checks for the
sensor validity. Move it to the legacy ->get_temp() hook, where it is
still needed.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 3d5b29133d3a..4e9f947a0f5f 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -328,13 +328,6 @@ static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 	u32 reg, div;
 	s64 sample, b, m;
 
-	/* Valid check */
-	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
-		dev_err(priv->dev,
-			"Temperature sensor reading not valid\n");
-		return -EIO;
-	}
-
 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
 	if (priv->data->signed_sample)
@@ -363,6 +356,13 @@ static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
 	long temperature;
 	int ret;
 
+	/* Valid check */
+	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
+		dev_err(priv->dev,
+			"Temperature sensor reading not valid\n");
+		return -EIO;
+	}
+
 	/* Do the actual reading */
 	ret = armada_read_sensor(priv, &temperature);
 	*temp = temperature;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 11/27] thermal: armada: move validity check out of the read function
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Sensor selection when using multiple sensors already checks for the
sensor validity. Move it to the legacy ->get_temp() hook, where it is
still needed.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 3d5b29133d3a..4e9f947a0f5f 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -328,13 +328,6 @@ static int armada_read_sensor(struct armada_thermal_priv *priv, long *temp)
 	u32 reg, div;
 	s64 sample, b, m;
 
-	/* Valid check */
-	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
-		dev_err(priv->dev,
-			"Temperature sensor reading not valid\n");
-		return -EIO;
-	}
-
 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
 	if (priv->data->signed_sample)
@@ -363,6 +356,13 @@ static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
 	long temperature;
 	int ret;
 
+	/* Valid check */
+	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
+		dev_err(priv->dev,
+			"Temperature sensor reading not valid\n");
+		return -EIO;
+	}
+
 	/* Do the actual reading */
 	ret = armada_read_sensor(priv, &temperature);
 	*temp = temperature;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 12/27] thermal: armada: get rid of the ->is_valid() pointer
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

The implementation of armada_is_valid() is very simple and is the same
across all the versions of the IP since the ->is_valid_bit has been
introduced. Simplify the structure by getting rid of the function
pointer and calling directly the function.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 4e9f947a0f5f..66324fc853a3 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -82,9 +82,6 @@ struct armada_thermal_data {
 	void (*init)(struct platform_device *pdev,
 		     struct armada_thermal_priv *priv);
 
-	/* Test for a valid sensor value (optional) */
-	bool (*is_valid)(struct armada_thermal_priv *);
-
 	/* Formula coeficients: temp = (b - m * reg) / div */
 	s64 coef_b;
 	s64 coef_m;
@@ -266,6 +263,9 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
+	if (!priv->data->is_valid_bit)
+		return true;
+
 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 
 	return reg & priv->data->is_valid_bit;
@@ -357,7 +357,7 @@ static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
 	int ret;
 
 	/* Valid check */
-	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
+	if (armada_is_valid(priv)) {
 		dev_err(priv->dev,
 			"Temperature sensor reading not valid\n");
 		return -EIO;
@@ -417,7 +417,6 @@ static const struct armada_thermal_data armadaxp_data = {
 };
 
 static const struct armada_thermal_data armada370_data = {
-	.is_valid = armada_is_valid,
 	.init = armada370_init,
 	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
@@ -430,7 +429,6 @@ static const struct armada_thermal_data armada370_data = {
 };
 
 static const struct armada_thermal_data armada375_data = {
-	.is_valid = armada_is_valid,
 	.init = armada375_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
@@ -444,7 +442,6 @@ static const struct armada_thermal_data armada375_data = {
 };
 
 static const struct armada_thermal_data armada380_data = {
-	.is_valid = armada_is_valid,
 	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
@@ -459,7 +456,6 @@ static const struct armada_thermal_data armada380_data = {
 };
 
 static const struct armada_thermal_data armada_ap806_data = {
-	.is_valid = armada_is_valid,
 	.init = armada_ap806_init,
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
@@ -476,7 +472,6 @@ static const struct armada_thermal_data armada_ap806_data = {
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
-	.is_valid = armada_is_valid,
 	.init = armada_cp110_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 12/27] thermal: armada: get rid of the ->is_valid() pointer
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

The implementation of armada_is_valid() is very simple and is the same
across all the versions of the IP since the ->is_valid_bit has been
introduced. Simplify the structure by getting rid of the function
pointer and calling directly the function.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 4e9f947a0f5f..66324fc853a3 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -82,9 +82,6 @@ struct armada_thermal_data {
 	void (*init)(struct platform_device *pdev,
 		     struct armada_thermal_priv *priv);
 
-	/* Test for a valid sensor value (optional) */
-	bool (*is_valid)(struct armada_thermal_priv *);
-
 	/* Formula coeficients: temp = (b - m * reg) / div */
 	s64 coef_b;
 	s64 coef_m;
@@ -266,6 +263,9 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
 	u32 reg;
 
+	if (!priv->data->is_valid_bit)
+		return true;
+
 	regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
 
 	return reg & priv->data->is_valid_bit;
@@ -357,7 +357,7 @@ static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
 	int ret;
 
 	/* Valid check */
-	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
+	if (armada_is_valid(priv)) {
 		dev_err(priv->dev,
 			"Temperature sensor reading not valid\n");
 		return -EIO;
@@ -417,7 +417,6 @@ static const struct armada_thermal_data armadaxp_data = {
 };
 
 static const struct armada_thermal_data armada370_data = {
-	.is_valid = armada_is_valid,
 	.init = armada370_init,
 	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
@@ -430,7 +429,6 @@ static const struct armada_thermal_data armada370_data = {
 };
 
 static const struct armada_thermal_data armada375_data = {
-	.is_valid = armada_is_valid,
 	.init = armada375_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
@@ -444,7 +442,6 @@ static const struct armada_thermal_data armada375_data = {
 };
 
 static const struct armada_thermal_data armada380_data = {
-	.is_valid = armada_is_valid,
 	.init = armada380_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
@@ -459,7 +456,6 @@ static const struct armada_thermal_data armada380_data = {
 };
 
 static const struct armada_thermal_data armada_ap806_data = {
-	.is_valid = armada_is_valid,
 	.init = armada_ap806_init,
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
@@ -476,7 +472,6 @@ static const struct armada_thermal_data armada_ap806_data = {
 };
 
 static const struct armada_thermal_data armada_cp110_data = {
-	.is_valid = armada_is_valid,
 	.init = armada_cp110_init,
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/27] thermal: armada: add overheat interrupt support
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

The IP can manage to trigger interrupts on overheat situation from all
the sensors.

However, the interrupt source changes along with the last selected
source (ie. the last read sensor), which is an inconsistent behavior.
Avoid possible glitches by always selecting back only one channel which
will then be referenced as the "overheat_sensor" (arbitrarily: the first
in the DT which has a critical trip point filled in).

It is possible that the scan of all thermal zone nodes did not bring a
critical trip point from which the overheat interrupt could be
configured. In this case just complain but do not fail the probe.

Also disable sensor switch during overheat situations because changing
the channel while the system is too hot could clear the overheat state
by changing the source while the temperature is still very high.

Even if the overheat state is not declared, overheat interrupt must be
cleared by reading the DFX interrupt cause _after_ the temperature has
fallen down to the low threshold, otherwise future possible interrupts
would not be served. A work polls the corresponding register until the
overheat flag gets cleared in this case.

Suggested-by: David Sniatkiwicz <davidsn@marvell.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 335 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 335 insertions(+)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 66324fc853a3..6cef29d51fb0 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -24,8 +24,14 @@
 #include <linux/of_device.h>
 #include <linux/thermal.h>
 #include <linux/iopoll.h>
+#include <linux/interrupt.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/workqueue.h>
+
+#include "thermal_core.h"
+
+#define TO_MCELSIUS(c)			(c * 1000)
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -61,9 +67,13 @@
 #define CONTROL1_TSEN_AVG_MASK		0x7
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
+#define CONTROL1_TSEN_INT_EN		BIT(25)
+#define CONTROL1_TSEN_SELECT_OFF	21
+#define CONTROL1_TSEN_SELECT_MASK	0x3
 
 #define STATUS_POLL_PERIOD_US		1000
 #define STATUS_POLL_TIMEOUT_US		100000
+#define OVERHEAT_INT_POLL_DELAY		(1 * HZ)
 
 struct armada_thermal_data;
 
@@ -73,8 +83,15 @@ struct armada_thermal_priv {
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct mutex update_lock;
+	struct thermal_zone_device *overheat_sensor;
 	struct armada_thermal_data *data;
 	int current_channel;
+	struct delayed_work wait_end_overheat_work;
+	bool overheat_int_enabled;
+	long current_threshold;
+	long current_hysteresis;
+	bool overheat_situation;
+	int interrupt_source;
 };
 
 struct armada_thermal_data {
@@ -92,12 +109,20 @@ struct armada_thermal_data {
 	/* Register shift and mask to access the sensor temperature */
 	unsigned int temp_shift;
 	unsigned int temp_mask;
+	unsigned int thresh_shift;
+	unsigned int hyst_shift;
+	unsigned int hyst_mask;
 	u32 is_valid_bit;
 
 	/* Syscon access */
 	unsigned int syscon_control0_off;
 	unsigned int syscon_control1_off;
 	unsigned int syscon_status_off;
+	unsigned int dfx_irq_cause_off;
+	unsigned int dfx_irq_mask_off;
+	unsigned int dfx_overheat_irq;
+	unsigned int dfx_server_irq_mask_off;
+	unsigned int dfx_server_irq_en;
 
 	/* One sensor is in the thermal IC, the others are in the CPUs if any */
 	unsigned int cpu_nr;
@@ -125,6 +150,12 @@ struct armada_thermal_sensor {
 	int id;
 };
 
+struct armada_thermal_priv *work_to_thermal(struct work_struct *work)
+{
+	return container_of(work, struct armada_thermal_priv,
+			    wait_end_overheat_work.work);
+}
+
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
@@ -271,6 +302,44 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
+static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	/* Clear DFX temperature IRQ cause */
+	regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
+
+	/* Enable DFX Temperature IRQ */
+	regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+	reg |= data->dfx_overheat_irq;
+	regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+	/* Enable DFX server IRQ */
+	regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg);
+	reg |= data->dfx_server_irq_en;
+	regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg);
+
+	/* Enable overheat interrupt */
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
+	reg |= CONTROL1_TSEN_INT_EN;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
+	priv->overheat_int_enabled = true;
+}
+
+static void armada_disable_overheat_interrupt(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
+	reg &= ~CONTROL1_TSEN_INT_EN;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
+	priv->overheat_int_enabled = false;
+}
+
 /* There is currently no board with more than one sensor per channel */
 static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
 {
@@ -283,6 +352,14 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
 	if (priv->current_channel == channel)
 		return 0;
 
+	/*
+	 * Changing the channel while the system is too hot could clear the
+	 * overheat state by changing the source while the temperature is still
+	 * very high. Forbid any channel change in this situation.
+	 */
+	if (priv->overheat_situation)
+		return -EBUSY;
+
 	/* Stop the measurements */
 	regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
 	ctrl0 &= ~CONTROL0_TSEN_START;
@@ -378,11 +455,18 @@ static int armada_get_temp(void *_sensor, int *temp)
 {
 	struct armada_thermal_sensor *sensor = _sensor;
 	struct armada_thermal_priv *priv = sensor->priv;
+	bool toggle_int = priv->overheat_int_enabled &&
+			  !priv->overheat_situation &&
+			  sensor->id != priv->interrupt_source;
 	long temperature;
 	int ret;
 
 	mutex_lock(&priv->update_lock);
 
+	/* Disable the interrupt the time to read another sensor */
+	if (toggle_int)
+		armada_disable_overheat_interrupt(priv);
+
 	/* Select the desired channel */
 	ret = armada_select_channel(priv, sensor->id);
 	if (ret)
@@ -393,6 +477,14 @@ static int armada_get_temp(void *_sensor, int *temp)
 	if (ret)
 		goto unlock_mutex;
 
+	/* Select back the interrupt source channel */
+	ret = armada_select_channel(priv, priv->interrupt_source);
+	if (ret)
+		goto unlock_mutex;
+
+	if (toggle_int)
+		armada_enable_overheat_interrupt(priv);
+
 	*temp = temperature;
 
 unlock_mutex:
@@ -405,6 +497,162 @@ static struct thermal_zone_of_device_ops of_ops = {
 	.get_temp = armada_get_temp,
 };
 
+static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data,
+					  unsigned int temp_mc)
+{
+	s64 b = data->coef_b;
+	s64 m = data->coef_m;
+	s64 div = data->coef_div;
+	unsigned int sample;
+
+	if (data->inverted)
+		sample = div_s64(((temp_mc * div) + b), m);
+	else
+		sample = div_s64((b - (temp_mc * div)), m);
+
+	return sample & data->temp_mask;
+}
+
+static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data,
+					  unsigned int hyst_mc)
+{
+	/*
+	 * The documentation states:
+	 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
+	 * which is the mathematical derivation for:
+	 * 0x0 <=> 1.9°C, 0x1 <=> 3.8°C, 0x2 <=> 7.6°C, 0x3 <=> 15.2
+	 */
+	unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200};
+	int i;
+
+	/*
+	 * We will always take the smallest possible hysteresis to avoid risking
+	 * the hardware integrity by enlarging the threshold by +8°C in the
+	 * worst case.
+	 */
+	for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--)
+		if (hyst_mc >= hyst_levels_mc[i])
+			break;
+
+	return i & data->hyst_mask;
+}
+
+static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv,
+					   int thresh_mc, int hyst_mc)
+{
+	struct armada_thermal_data *data = priv->data;
+	unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc);
+	unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc);
+	u32 ctrl1;
+
+	regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1);
+
+	/* Set Threshold */
+	if (thresh_mc >= 0) {
+		ctrl1 &= ~(data->temp_mask << data->thresh_shift);
+		ctrl1 |= threshold << data->thresh_shift;
+		priv->current_threshold = thresh_mc;
+	}
+
+	/* Set Hysteresis */
+	if (hyst_mc >= 0) {
+		ctrl1 &= ~(data->hyst_mask << data->hyst_shift);
+		ctrl1 |= hysteresis << data->hyst_shift;
+		priv->current_hysteresis = hyst_mc;
+	}
+
+	regmap_write(priv->syscon, data->syscon_control1_off, ctrl1);
+}
+
+static bool armada_temp_is_over_threshold(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	/*
+	 * When an overheat interrupt occurs, poll DFX overheat IRQ cause
+	 * register until the right bit gets cleared.
+	 */
+	regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
+	if (reg & data->dfx_overheat_irq) {
+		/*
+		 * Threshold reached, as different CPs may share the same
+		 * interrupt, we need to mask the overheat interrupt until the
+		 * temperature climbs down to the low-threshold, otherwise if
+		 * another CP reaches its threshold temperature too, it will
+		 * re-trigger an interrupt for the CPs that are already over
+		 * heating.
+		 */
+		regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+		reg &= ~data->dfx_overheat_irq;
+		regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+		schedule_delayed_work(&priv->wait_end_overheat_work,
+				      OVERHEAT_INT_POLL_DELAY);
+
+		priv->overheat_situation = true;
+
+		return true;
+	}
+
+	/*
+	 * The temperature level is acceptable again, unmask the overheat
+	 * interrupt.
+	 */
+	regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+	reg |= data->dfx_overheat_irq;
+	regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+	priv->overheat_situation = false;
+
+	/* Notify the thermal core that the temperature is acceptable again */
+	thermal_zone_device_update(priv->overheat_sensor,
+				   THERMAL_EVENT_UNSPECIFIED);
+
+	return false;
+}
+
+/*
+ * Overheat interrupt must be cleared by reading the DFX interrupt cause after
+ * the temperature has fallen down to the low threshold, otherwise future
+ * interrupts will not be served. This work polls the corresponding register
+ * until the overheat flag gets cleared.
+ */
+static void armada_wait_end_overheat(struct work_struct *work)
+{
+	armada_temp_is_over_threshold(work_to_thermal(work));
+}
+
+static irqreturn_t armada_overheat_isr(int irq, void *blob)
+{
+	struct armada_thermal_priv *priv = (struct armada_thermal_priv *)blob;
+	u32 reg;
+	long temperature;
+
+	/*
+	 * As the interrupt line is shared between CPs, this handler will be
+	 * executed each time a CP triggers an overheat interrupt. Once the
+	 * interrupt is triggered for one CP, it is masked in the DFX register
+	 * until the temperature falls under the threshold, when it is unmasked.
+	 *
+	 * Check if the interrupt is masked, in this case it means the code is
+	 * running on the wrong CP and we should return IRQ_NONE.
+	 */
+	regmap_read(priv->syscon, priv->data->dfx_irq_mask_off, &reg);
+	if (!(reg & priv->data->dfx_overheat_irq))
+		return IRQ_NONE;
+
+	if (armada_temp_is_over_threshold(priv)) {
+		armada_read_sensor(priv, &temperature);
+
+		/* Notify the core about the unexpected heat level */
+		thermal_zone_device_update(priv->overheat_sensor,
+					   THERMAL_EVENT_UNSPECIFIED);
+	}
+
+	return IRQ_HANDLED;
+}
+
 static const struct armada_thermal_data armadaxp_data = {
 	.init = armadaxp_init,
 	.temp_shift = 10,
@@ -460,6 +708,9 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
+	.thresh_shift = 3,
+	.hyst_shift = 19,
+	.hyst_mask = 0x3,
 	.coef_b = -150000LL,
 	.coef_m = 423ULL,
 	.coef_div = 1,
@@ -468,6 +719,11 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.syscon_control0_off = 0x84,
 	.syscon_control1_off = 0x88,
 	.syscon_status_off = 0x8C,
+	.dfx_irq_cause_off = 0x108,
+	.dfx_irq_mask_off = 0x10C,
+	.dfx_overheat_irq = BIT(22),
+	.dfx_server_irq_mask_off = 0x104,
+	.dfx_server_irq_en = BIT(1),
 	.cpu_nr = 4,
 };
 
@@ -476,6 +732,9 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
+	.thresh_shift = 16,
+	.hyst_shift = 26,
+	.hyst_mask = 0x3,
 	.coef_b = 1172499100ULL,
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
@@ -483,6 +742,11 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.syscon_control0_off = 0x70,
 	.syscon_control1_off = 0x74,
 	.syscon_status_off = 0x78,
+	.dfx_irq_cause_off = 0x108,
+	.dfx_irq_mask_off = 0x10C,
+	.dfx_overheat_irq = BIT(20),
+	.dfx_server_irq_mask_off = 0x104,
+	.dfx_server_irq_en = BIT(1),
 };
 
 static const struct of_device_id armada_thermal_id_table[] = {
@@ -560,10 +824,28 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
 static int armada_thermal_probe_syscon(struct platform_device *pdev,
 				       struct armada_thermal_priv *priv)
 {
+	int irq, ret;
+
 	priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
 	if (IS_ERR(priv->syscon))
 		return PTR_ERR(priv->syscon);
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	/*
+	 * One SEI interrupt in the GIC can be triggered by each DFX server (one
+	 * per CP) upon hardware interrupt from the thermal IP itself.
+	 */
+	ret = devm_request_irq(&pdev->dev, irq, armada_overheat_isr, 0,
+			       NULL, priv);
+	if (ret)
+		return ret;
+
+	INIT_DELAYED_WORK(&priv->wait_end_overheat_work,
+			  armada_wait_end_overheat);
+
 	return 0;
 }
 
@@ -597,6 +879,47 @@ static void armada_set_sane_name(struct platform_device *pdev,
 	} while (insane_char);
 }
 
+/*
+ * The IP can manage to trigger interrupts on overheat situation from all the
+ * sensors. However, the interrupt source changes along with the last selected
+ * source (ie. the last read sensor), which is an inconsistent behavior. Avoid
+ * possible glitches by always selecting back only one channel (arbitrarily: the
+ * first in the DT which has a critical trip point). We also disable sensor
+ * switch during overheat situations.
+ */
+static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
+					 struct thermal_zone_device *tz)
+{
+	/* Retrieve the critical trip point to enable the overheat interrupt */
+	const struct thermal_trip *trips = of_thermal_get_trip_points(tz);
+	struct armada_thermal_sensor *sensor = tz->devdata;
+	int ret;
+	int i;
+
+	if (!trips)
+		return -EINVAL;
+
+	for (i = 0; i < of_thermal_get_ntrips(tz); i++)
+		if (trips[i].type == THERMAL_TRIP_CRITICAL)
+			break;
+
+	if (i == of_thermal_get_ntrips(tz))
+		return -EINVAL;
+
+	ret = armada_select_channel(priv, sensor->id);
+	if (ret)
+		return ret;
+
+	armada_set_overheat_thresholds(priv,
+				       trips[i].temperature,
+				       trips[i].hysteresis);
+	armada_enable_overheat_interrupt(priv);
+	priv->overheat_sensor = tz;
+	priv->interrupt_source = sensor->id;
+
+	return 0;
+}
+
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	struct thermal_zone_device *tz;
@@ -694,8 +1017,20 @@ static int armada_thermal_probe(struct platform_device *pdev)
 			devm_kfree(&pdev->dev, sensor);
 			continue;
 		}
+
+		/*
+		 * The first channel that has a critical trip point registered
+		 * in the DT will serve as interrupt source. Others possible
+		 * critical trip points will simply be ignored by the driver.
+		 */
+		if (!priv->overheat_sensor)
+			armada_configure_overheat_int(priv, tz);
 	}
 
+	/* Just complain if no overheat interrupt was set up */
+	if (!priv->overheat_sensor)
+		dev_warn(&pdev->dev, "Overheat interrupt feature disabled\n");
+
 	drvdata->type = SYSCON;
 	drvdata->data.priv = priv;
 	platform_set_drvdata(pdev, drvdata);
-- 
2.14.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/27] thermal: armada: add overheat interrupt support
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

The IP can manage to trigger interrupts on overheat situation from all
the sensors.

However, the interrupt source changes along with the last selected
source (ie. the last read sensor), which is an inconsistent behavior.
Avoid possible glitches by always selecting back only one channel which
will then be referenced as the "overheat_sensor" (arbitrarily: the first
in the DT which has a critical trip point filled in).

It is possible that the scan of all thermal zone nodes did not bring a
critical trip point from which the overheat interrupt could be
configured. In this case just complain but do not fail the probe.

Also disable sensor switch during overheat situations because changing
the channel while the system is too hot could clear the overheat state
by changing the source while the temperature is still very high.

Even if the overheat state is not declared, overheat interrupt must be
cleared by reading the DFX interrupt cause _after_ the temperature has
fallen down to the low threshold, otherwise future possible interrupts
would not be served. A work polls the corresponding register until the
overheat flag gets cleared in this case.

Suggested-by: David Sniatkiwicz <davidsn@marvell.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/thermal/armada_thermal.c | 335 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 335 insertions(+)

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 66324fc853a3..6cef29d51fb0 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -24,8 +24,14 @@
 #include <linux/of_device.h>
 #include <linux/thermal.h>
 #include <linux/iopoll.h>
+#include <linux/interrupt.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/workqueue.h>
+
+#include "thermal_core.h"
+
+#define TO_MCELSIUS(c)			(c * 1000)
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -61,9 +67,13 @@
 #define CONTROL1_TSEN_AVG_MASK		0x7
 #define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
+#define CONTROL1_TSEN_INT_EN		BIT(25)
+#define CONTROL1_TSEN_SELECT_OFF	21
+#define CONTROL1_TSEN_SELECT_MASK	0x3
 
 #define STATUS_POLL_PERIOD_US		1000
 #define STATUS_POLL_TIMEOUT_US		100000
+#define OVERHEAT_INT_POLL_DELAY		(1 * HZ)
 
 struct armada_thermal_data;
 
@@ -73,8 +83,15 @@ struct armada_thermal_priv {
 	struct regmap *syscon;
 	char zone_name[THERMAL_NAME_LENGTH];
 	struct mutex update_lock;
+	struct thermal_zone_device *overheat_sensor;
 	struct armada_thermal_data *data;
 	int current_channel;
+	struct delayed_work wait_end_overheat_work;
+	bool overheat_int_enabled;
+	long current_threshold;
+	long current_hysteresis;
+	bool overheat_situation;
+	int interrupt_source;
 };
 
 struct armada_thermal_data {
@@ -92,12 +109,20 @@ struct armada_thermal_data {
 	/* Register shift and mask to access the sensor temperature */
 	unsigned int temp_shift;
 	unsigned int temp_mask;
+	unsigned int thresh_shift;
+	unsigned int hyst_shift;
+	unsigned int hyst_mask;
 	u32 is_valid_bit;
 
 	/* Syscon access */
 	unsigned int syscon_control0_off;
 	unsigned int syscon_control1_off;
 	unsigned int syscon_status_off;
+	unsigned int dfx_irq_cause_off;
+	unsigned int dfx_irq_mask_off;
+	unsigned int dfx_overheat_irq;
+	unsigned int dfx_server_irq_mask_off;
+	unsigned int dfx_server_irq_en;
 
 	/* One sensor is in the thermal IC, the others are in the CPUs if any */
 	unsigned int cpu_nr;
@@ -125,6 +150,12 @@ struct armada_thermal_sensor {
 	int id;
 };
 
+struct armada_thermal_priv *work_to_thermal(struct work_struct *work)
+{
+	return container_of(work, struct armada_thermal_priv,
+			    wait_end_overheat_work.work);
+}
+
 static void armadaxp_init(struct platform_device *pdev,
 			  struct armada_thermal_priv *priv)
 {
@@ -271,6 +302,44 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
 	return reg & priv->data->is_valid_bit;
 }
 
+static void armada_enable_overheat_interrupt(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	/* Clear DFX temperature IRQ cause */
+	regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
+
+	/* Enable DFX Temperature IRQ */
+	regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+	reg |= data->dfx_overheat_irq;
+	regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+	/* Enable DFX server IRQ */
+	regmap_read(priv->syscon, data->dfx_server_irq_mask_off, &reg);
+	reg |= data->dfx_server_irq_en;
+	regmap_write(priv->syscon, data->dfx_server_irq_mask_off, reg);
+
+	/* Enable overheat interrupt */
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
+	reg |= CONTROL1_TSEN_INT_EN;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
+	priv->overheat_int_enabled = true;
+}
+
+static void armada_disable_overheat_interrupt(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	regmap_read(priv->syscon, data->syscon_control1_off, &reg);
+	reg &= ~CONTROL1_TSEN_INT_EN;
+	regmap_write(priv->syscon, data->syscon_control1_off, reg);
+
+	priv->overheat_int_enabled = false;
+}
+
 /* There is currently no board with more than one sensor per channel */
 static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
 {
@@ -283,6 +352,14 @@ static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
 	if (priv->current_channel == channel)
 		return 0;
 
+	/*
+	 * Changing the channel while the system is too hot could clear the
+	 * overheat state by changing the source while the temperature is still
+	 * very high. Forbid any channel change in this situation.
+	 */
+	if (priv->overheat_situation)
+		return -EBUSY;
+
 	/* Stop the measurements */
 	regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
 	ctrl0 &= ~CONTROL0_TSEN_START;
@@ -378,11 +455,18 @@ static int armada_get_temp(void *_sensor, int *temp)
 {
 	struct armada_thermal_sensor *sensor = _sensor;
 	struct armada_thermal_priv *priv = sensor->priv;
+	bool toggle_int = priv->overheat_int_enabled &&
+			  !priv->overheat_situation &&
+			  sensor->id != priv->interrupt_source;
 	long temperature;
 	int ret;
 
 	mutex_lock(&priv->update_lock);
 
+	/* Disable the interrupt the time to read another sensor */
+	if (toggle_int)
+		armada_disable_overheat_interrupt(priv);
+
 	/* Select the desired channel */
 	ret = armada_select_channel(priv, sensor->id);
 	if (ret)
@@ -393,6 +477,14 @@ static int armada_get_temp(void *_sensor, int *temp)
 	if (ret)
 		goto unlock_mutex;
 
+	/* Select back the interrupt source channel */
+	ret = armada_select_channel(priv, priv->interrupt_source);
+	if (ret)
+		goto unlock_mutex;
+
+	if (toggle_int)
+		armada_enable_overheat_interrupt(priv);
+
 	*temp = temperature;
 
 unlock_mutex:
@@ -405,6 +497,162 @@ static struct thermal_zone_of_device_ops of_ops = {
 	.get_temp = armada_get_temp,
 };
 
+static unsigned int armada_mc_to_reg_temp(struct armada_thermal_data *data,
+					  unsigned int temp_mc)
+{
+	s64 b = data->coef_b;
+	s64 m = data->coef_m;
+	s64 div = data->coef_div;
+	unsigned int sample;
+
+	if (data->inverted)
+		sample = div_s64(((temp_mc * div) + b), m);
+	else
+		sample = div_s64((b - (temp_mc * div)), m);
+
+	return sample & data->temp_mask;
+}
+
+static unsigned int armada_mc_to_reg_hyst(struct armada_thermal_data *data,
+					  unsigned int hyst_mc)
+{
+	/*
+	 * The documentation states:
+	 * high/low watermark = threshold +/- 0.4761 * 2^(hysteresis + 2)
+	 * which is the mathematical derivation for:
+	 * 0x0 <=> 1.9?C, 0x1 <=> 3.8?C, 0x2 <=> 7.6?C, 0x3 <=> 15.2
+	 */
+	unsigned int hyst_levels_mc[] = {1900, 3800, 7600, 15200};
+	int i;
+
+	/*
+	 * We will always take the smallest possible hysteresis to avoid risking
+	 * the hardware integrity by enlarging the threshold by +8?C in the
+	 * worst case.
+	 */
+	for (i = ARRAY_SIZE(hyst_levels_mc) - 1; i > 0; i--)
+		if (hyst_mc >= hyst_levels_mc[i])
+			break;
+
+	return i & data->hyst_mask;
+}
+
+static void armada_set_overheat_thresholds(struct armada_thermal_priv *priv,
+					   int thresh_mc, int hyst_mc)
+{
+	struct armada_thermal_data *data = priv->data;
+	unsigned int threshold = armada_mc_to_reg_temp(data, thresh_mc);
+	unsigned int hysteresis = armada_mc_to_reg_hyst(data, hyst_mc);
+	u32 ctrl1;
+
+	regmap_read(priv->syscon, data->syscon_control1_off, &ctrl1);
+
+	/* Set Threshold */
+	if (thresh_mc >= 0) {
+		ctrl1 &= ~(data->temp_mask << data->thresh_shift);
+		ctrl1 |= threshold << data->thresh_shift;
+		priv->current_threshold = thresh_mc;
+	}
+
+	/* Set Hysteresis */
+	if (hyst_mc >= 0) {
+		ctrl1 &= ~(data->hyst_mask << data->hyst_shift);
+		ctrl1 |= hysteresis << data->hyst_shift;
+		priv->current_hysteresis = hyst_mc;
+	}
+
+	regmap_write(priv->syscon, data->syscon_control1_off, ctrl1);
+}
+
+static bool armada_temp_is_over_threshold(struct armada_thermal_priv *priv)
+{
+	struct armada_thermal_data *data = priv->data;
+	u32 reg;
+
+	/*
+	 * When an overheat interrupt occurs, poll DFX overheat IRQ cause
+	 * register until the right bit gets cleared.
+	 */
+	regmap_read(priv->syscon, data->dfx_irq_cause_off, &reg);
+	if (reg & data->dfx_overheat_irq) {
+		/*
+		 * Threshold reached, as different CPs may share the same
+		 * interrupt, we need to mask the overheat interrupt until the
+		 * temperature climbs down to the low-threshold, otherwise if
+		 * another CP reaches its threshold temperature too, it will
+		 * re-trigger an interrupt for the CPs that are already over
+		 * heating.
+		 */
+		regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+		reg &= ~data->dfx_overheat_irq;
+		regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+		schedule_delayed_work(&priv->wait_end_overheat_work,
+				      OVERHEAT_INT_POLL_DELAY);
+
+		priv->overheat_situation = true;
+
+		return true;
+	}
+
+	/*
+	 * The temperature level is acceptable again, unmask the overheat
+	 * interrupt.
+	 */
+	regmap_read(priv->syscon, data->dfx_irq_mask_off, &reg);
+	reg |= data->dfx_overheat_irq;
+	regmap_write(priv->syscon, data->dfx_irq_mask_off, reg);
+
+	priv->overheat_situation = false;
+
+	/* Notify the thermal core that the temperature is acceptable again */
+	thermal_zone_device_update(priv->overheat_sensor,
+				   THERMAL_EVENT_UNSPECIFIED);
+
+	return false;
+}
+
+/*
+ * Overheat interrupt must be cleared by reading the DFX interrupt cause after
+ * the temperature has fallen down to the low threshold, otherwise future
+ * interrupts will not be served. This work polls the corresponding register
+ * until the overheat flag gets cleared.
+ */
+static void armada_wait_end_overheat(struct work_struct *work)
+{
+	armada_temp_is_over_threshold(work_to_thermal(work));
+}
+
+static irqreturn_t armada_overheat_isr(int irq, void *blob)
+{
+	struct armada_thermal_priv *priv = (struct armada_thermal_priv *)blob;
+	u32 reg;
+	long temperature;
+
+	/*
+	 * As the interrupt line is shared between CPs, this handler will be
+	 * executed each time a CP triggers an overheat interrupt. Once the
+	 * interrupt is triggered for one CP, it is masked in the DFX register
+	 * until the temperature falls under the threshold, when it is unmasked.
+	 *
+	 * Check if the interrupt is masked, in this case it means the code is
+	 * running on the wrong CP and we should return IRQ_NONE.
+	 */
+	regmap_read(priv->syscon, priv->data->dfx_irq_mask_off, &reg);
+	if (!(reg & priv->data->dfx_overheat_irq))
+		return IRQ_NONE;
+
+	if (armada_temp_is_over_threshold(priv)) {
+		armada_read_sensor(priv, &temperature);
+
+		/* Notify the core about the unexpected heat level */
+		thermal_zone_device_update(priv->overheat_sensor,
+					   THERMAL_EVENT_UNSPECIFIED);
+	}
+
+	return IRQ_HANDLED;
+}
+
 static const struct armada_thermal_data armadaxp_data = {
 	.init = armadaxp_init,
 	.temp_shift = 10,
@@ -460,6 +708,9 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.is_valid_bit = BIT(16),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
+	.thresh_shift = 3,
+	.hyst_shift = 19,
+	.hyst_mask = 0x3,
 	.coef_b = -150000LL,
 	.coef_m = 423ULL,
 	.coef_div = 1,
@@ -468,6 +719,11 @@ static const struct armada_thermal_data armada_ap806_data = {
 	.syscon_control0_off = 0x84,
 	.syscon_control1_off = 0x88,
 	.syscon_status_off = 0x8C,
+	.dfx_irq_cause_off = 0x108,
+	.dfx_irq_mask_off = 0x10C,
+	.dfx_overheat_irq = BIT(22),
+	.dfx_server_irq_mask_off = 0x104,
+	.dfx_server_irq_en = BIT(1),
 	.cpu_nr = 4,
 };
 
@@ -476,6 +732,9 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
+	.thresh_shift = 16,
+	.hyst_shift = 26,
+	.hyst_mask = 0x3,
 	.coef_b = 1172499100ULL,
 	.coef_m = 2000096ULL,
 	.coef_div = 4201,
@@ -483,6 +742,11 @@ static const struct armada_thermal_data armada_cp110_data = {
 	.syscon_control0_off = 0x70,
 	.syscon_control1_off = 0x74,
 	.syscon_status_off = 0x78,
+	.dfx_irq_cause_off = 0x108,
+	.dfx_irq_mask_off = 0x10C,
+	.dfx_overheat_irq = BIT(20),
+	.dfx_server_irq_mask_off = 0x104,
+	.dfx_server_irq_en = BIT(1),
 };
 
 static const struct of_device_id armada_thermal_id_table[] = {
@@ -560,10 +824,28 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
 static int armada_thermal_probe_syscon(struct platform_device *pdev,
 				       struct armada_thermal_priv *priv)
 {
+	int irq, ret;
+
 	priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
 	if (IS_ERR(priv->syscon))
 		return PTR_ERR(priv->syscon);
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	/*
+	 * One SEI interrupt in the GIC can be triggered by each DFX server (one
+	 * per CP) upon hardware interrupt from the thermal IP itself.
+	 */
+	ret = devm_request_irq(&pdev->dev, irq, armada_overheat_isr, 0,
+			       NULL, priv);
+	if (ret)
+		return ret;
+
+	INIT_DELAYED_WORK(&priv->wait_end_overheat_work,
+			  armada_wait_end_overheat);
+
 	return 0;
 }
 
@@ -597,6 +879,47 @@ static void armada_set_sane_name(struct platform_device *pdev,
 	} while (insane_char);
 }
 
+/*
+ * The IP can manage to trigger interrupts on overheat situation from all the
+ * sensors. However, the interrupt source changes along with the last selected
+ * source (ie. the last read sensor), which is an inconsistent behavior. Avoid
+ * possible glitches by always selecting back only one channel (arbitrarily: the
+ * first in the DT which has a critical trip point). We also disable sensor
+ * switch during overheat situations.
+ */
+static int armada_configure_overheat_int(struct armada_thermal_priv *priv,
+					 struct thermal_zone_device *tz)
+{
+	/* Retrieve the critical trip point to enable the overheat interrupt */
+	const struct thermal_trip *trips = of_thermal_get_trip_points(tz);
+	struct armada_thermal_sensor *sensor = tz->devdata;
+	int ret;
+	int i;
+
+	if (!trips)
+		return -EINVAL;
+
+	for (i = 0; i < of_thermal_get_ntrips(tz); i++)
+		if (trips[i].type == THERMAL_TRIP_CRITICAL)
+			break;
+
+	if (i == of_thermal_get_ntrips(tz))
+		return -EINVAL;
+
+	ret = armada_select_channel(priv, sensor->id);
+	if (ret)
+		return ret;
+
+	armada_set_overheat_thresholds(priv,
+				       trips[i].temperature,
+				       trips[i].hysteresis);
+	armada_enable_overheat_interrupt(priv);
+	priv->overheat_sensor = tz;
+	priv->interrupt_source = sensor->id;
+
+	return 0;
+}
+
 static int armada_thermal_probe(struct platform_device *pdev)
 {
 	struct thermal_zone_device *tz;
@@ -694,8 +1017,20 @@ static int armada_thermal_probe(struct platform_device *pdev)
 			devm_kfree(&pdev->dev, sensor);
 			continue;
 		}
+
+		/*
+		 * The first channel that has a critical trip point registered
+		 * in the DT will serve as interrupt source. Others possible
+		 * critical trip points will simply be ignored by the driver.
+		 */
+		if (!priv->overheat_sensor)
+			armada_configure_overheat_int(priv, tz);
 	}
 
+	/* Just complain if no overheat interrupt was set up */
+	if (!priv->overheat_sensor)
+		dev_warn(&pdev->dev, "Overheat interrupt feature disabled\n");
+
 	drvdata->type = SYSCON;
 	drvdata->data.priv = priv;
 	platform_set_drvdata(pdev, drvdata);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 14/27] dt-bindings: cp110: rename cp110 syscon file
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

There is no need to give numbers to system controllers inside the
documentation as the syscons use the same compatibles. Furthermore, this
approach does not scale very well and would force the creation of a new
file each time a new syscon is added in the device tree.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (100%)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
similarity index 100%
rename from Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
rename to Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
-- 
2.14.1

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 14/27] dt-bindings: cp110: rename cp110 syscon file
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

There is no need to give numbers to system controllers inside the
documentation as the syscons use the same compatibles. Furthermore, this
approach does not scale very well and would force the creation of a new
file each time a new syscon is added in the device tree.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (100%)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
similarity index 100%
rename from Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
rename to Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
-- 
2.14.1

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 15/27] dt-bindings: ap806: prepare the syscon file to list other syscons nodes
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

There are multiple system controllers in AP806. Because all syscon nodes
use the same compatible, it is pertinent to use this same file to list
IPs inside it. Thus, change the header to be more generic.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/ap806-system-controller.txt           | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index 0b887440e08a..a856eb9a4e05 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -2,14 +2,14 @@ Marvell Armada AP806 System Controller
 ======================================
 
 The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K
-SoCs. It contains a system controller, which provides a number
-registers giving access to numerous features: clocks, pin-muxing and
-many other SoC configuration items. This DT binding allows to describe
-this system controller.
+SoCs. It contains system controllers, which provide several registers
+giving access to numerous features: clocks, pin-muxing and many other
+SoC configuration items. This DT binding allows to describe these
+system controllers.
 
 For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
-  - reg: register area of the AP806 system controller
+ - reg: register area of the AP806 system controller
 
 Clocks:
 -------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 15/27] dt-bindings: ap806: prepare the syscon file to list other syscons nodes
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

There are multiple system controllers in AP806. Because all syscon nodes
use the same compatible, it is pertinent to use this same file to list
IPs inside it. Thus, change the header to be more generic.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/ap806-system-controller.txt           | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index 0b887440e08a..a856eb9a4e05 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -2,14 +2,14 @@ Marvell Armada AP806 System Controller
 ======================================
 
 The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K
-SoCs. It contains a system controller, which provides a number
-registers giving access to numerous features: clocks, pin-muxing and
-many other SoC configuration items. This DT binding allows to describe
-this system controller.
+SoCs. It contains system controllers, which provide several registers
+giving access to numerous features: clocks, pin-muxing and many other
+SoC configuration items. This DT binding allows to describe these
+system controllers.
 
 For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
-  - reg: register area of the AP806 system controller
+ - reg: register area of the AP806 system controller
 
 Clocks:
 -------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

There are multiple system controllers in CP110. Because all syscon nodes
use the same compatible, it is pertinent to use this same file to list
IPs inside it. Thus, change the header to be more generic, and align
with AP806 file.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 29cdbae6c5ac..56e7fb1153e7 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -1,15 +1,15 @@
-Marvell Armada CP110 System Controller 0
-========================================
+Marvell Armada CP110 System Controller
+======================================
 
 The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
-SoCs. It contains two sets of system control registers, System
-Controller 0 and System Controller 1. This Device Tree binding allows
-to describe the first system controller, which provides registers to
-configure various aspects of the SoC.
+SoCs. It contains system controllers, which provide several registers
+giving access to numerous features: clocks, pin-muxing and many other
+SoC configuration items. This DT binding allows to describe these
+system controllers.
 
 For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
- - reg: register area of the CP110 system controller 0
+ - reg: register area of the CP110 system controller
 
 Clocks:
 -------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

There are multiple system controllers in CP110. Because all syscon nodes
use the same compatible, it is pertinent to use this same file to list
IPs inside it. Thus, change the header to be more generic, and align
with AP806 file.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 29cdbae6c5ac..56e7fb1153e7 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -1,15 +1,15 @@
-Marvell Armada CP110 System Controller 0
-========================================
+Marvell Armada CP110 System Controller
+======================================
 
 The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
-SoCs. It contains two sets of system control registers, System
-Controller 0 and System Controller 1. This Device Tree binding allows
-to describe the first system controller, which provides registers to
-configure various aspects of the SoC.
+SoCs. It contains system controllers, which provide several registers
+giving access to numerous features: clocks, pin-muxing and many other
+SoC configuration items. This DT binding allows to describe these
+system controllers.
 
 For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
- - reg: register area of the CP110 system controller 0
+ - reg: register area of the CP110 system controller
 
 Clocks:
 -------
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Explain the thermal bindings now that the thermal IP is described being
inside of a system controller. Add a reference to the thermal-zone node.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index a856eb9a4e05..c95f3ac5c728 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -11,6 +11,9 @@ For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
  - reg: register area of the AP806 system controller
 
+SYSTEM CONTROLLER 0
+===================
+
 Clocks:
 -------
 
@@ -98,3 +101,43 @@ ap_syscon: system-controller@6f4000 {
 		gpio-ranges = <&ap_pinctrl 0 0 19>;
 	};
 };
+
+SYSTEM CONTROLLER 1
+===================
+
+Thermal:
+--------
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/thermal/thermal.txt
+
+The thermal IP can probe the temperature all around the processor. It
+may feature several channels, each of them wired to one sensor.
+
+It is possible to setup an overheat interrupt by giving at least one
+critical point to any subnode of the thermal-zone node.
+
+Required properties:
+- compatible: "marvell,armada-ap806-thermal"
+
+Optional properties:
+- interrupt-parent/interrupts: overheat interrupt handle. Should point to
+  line 18 of the SEI irqchip.
+  See interrupt-controller/interrupts.txt
+- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
+  to this IP and represents the channel ID. There is one sensor per
+  channel. O refers to the thermal IP internal channel, while positive
+  IDs refer to each CPU.
+
+Example:
+ap_syscon1: system-controller@6f8000 {
+	compatible = "syscon", "simple-mfd";
+	reg = <0x6f8000 0x1000>;
+
+	ap_thermal: ap-thermal {
+		compatible = "marvell,armada-ap806-thermal";
+		interrupt-parent = <&sei>;
+		interrupts = <18>;
+		#thermal-sensor-cells = <1>;
+	};
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Explain the thermal bindings now that the thermal IP is described being
inside of a system controller. Add a reference to the thermal-zone node.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index a856eb9a4e05..c95f3ac5c728 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -11,6 +11,9 @@ For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
  - reg: register area of the AP806 system controller
 
+SYSTEM CONTROLLER 0
+===================
+
 Clocks:
 -------
 
@@ -98,3 +101,43 @@ ap_syscon: system-controller at 6f4000 {
 		gpio-ranges = <&ap_pinctrl 0 0 19>;
 	};
 };
+
+SYSTEM CONTROLLER 1
+===================
+
+Thermal:
+--------
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/thermal/thermal.txt
+
+The thermal IP can probe the temperature all around the processor. It
+may feature several channels, each of them wired to one sensor.
+
+It is possible to setup an overheat interrupt by giving at least one
+critical point to any subnode of the thermal-zone node.
+
+Required properties:
+- compatible: "marvell,armada-ap806-thermal"
+
+Optional properties:
+- interrupt-parent/interrupts: overheat interrupt handle. Should point to
+  line 18 of the SEI irqchip.
+  See interrupt-controller/interrupts.txt
+- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
+  to this IP and represents the channel ID. There is one sensor per
+  channel. O refers to the thermal IP internal channel, while positive
+  IDs refer to each CPU.
+
+Example:
+ap_syscon1: system-controller at 6f8000 {
+	compatible = "syscon", "simple-mfd";
+	reg = <0x6f8000 0x1000>;
+
+	ap_thermal: ap-thermal {
+		compatible = "marvell,armada-ap806-thermal";
+		interrupt-parent = <&sei>;
+		interrupts = <18>;
+		#thermal-sensor-cells = <1>;
+	};
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 18/27] dt-bindings: cp110: update documentation since DT de-duplication
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

CP110 master/slave DT files have been merged in a DT de-duplication work
merged in v4.16. Update the syscon documentation accordingly to match
the current state of the DT nodes.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/cp110-system-controller.txt           | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 56e7fb1153e7..54b0d64ce819 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -163,26 +163,26 @@ Required properties:
 
 Example:
 
-cpm_syscon0: system-controller@440000 {
+CP110_LABEL(syscon0): system-controller@440000 {
 	compatible = "syscon", "simple-mfd";
 	reg = <0x440000 0x1000>;
 
-	cpm_clk: clock {
+	CP110_LABEL(clk): clock {
 		compatible = "marvell,cp110-clock";
 		#clock-cells = <2>;
 	};
 
-	cpm_pinctrl: pinctrl {
+	CP110_LABEL(pinctrl): pinctrl {
 		compatible = "marvell,armada-8k-cpm-pinctrl";
 	};
 
-	cpm_gpio1: gpio@100 {
+	CP110_LABEL(gpio1): gpio@100 {
 		compatible = "marvell,armada-8k-gpio";
 		offset = <0x100>;
 		ngpios = <32>;
 		gpio-controller;
 		#gpio-cells = <2>;
-		gpio-ranges = <&cpm_pinctrl 0 0 32>;
+		gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
 	};
 
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 18/27] dt-bindings: cp110: update documentation since DT de-duplication
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

CP110 master/slave DT files have been merged in a DT de-duplication work
merged in v4.16. Update the syscon documentation accordingly to match
the current state of the DT nodes.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../bindings/arm/marvell/cp110-system-controller.txt           | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 56e7fb1153e7..54b0d64ce819 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -163,26 +163,26 @@ Required properties:
 
 Example:
 
-cpm_syscon0: system-controller at 440000 {
+CP110_LABEL(syscon0): system-controller at 440000 {
 	compatible = "syscon", "simple-mfd";
 	reg = <0x440000 0x1000>;
 
-	cpm_clk: clock {
+	CP110_LABEL(clk): clock {
 		compatible = "marvell,cp110-clock";
 		#clock-cells = <2>;
 	};
 
-	cpm_pinctrl: pinctrl {
+	CP110_LABEL(pinctrl): pinctrl {
 		compatible = "marvell,armada-8k-cpm-pinctrl";
 	};
 
-	cpm_gpio1: gpio at 100 {
+	CP110_LABEL(gpio1): gpio at 100 {
 		compatible = "marvell,armada-8k-gpio";
 		offset = <0x100>;
 		ngpios = <32>;
 		gpio-controller;
 		#gpio-cells = <2>;
-		gpio-ranges = <&cpm_pinctrl 0 0 32>;
+		gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
 	};
 
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 19/27] dt-bindings: cp110: add the thermal node in the syscon file
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Explain the thermal bindings now that the thermal IP is described being
inside of a system controller. Add a reference to the thermal-zone node.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../arm/marvell/cp110-system-controller.txt        | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 54b0d64ce819..e372c21d2a57 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -11,6 +11,9 @@ For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
  - reg: register area of the CP110 system controller
 
+SYSTEM CONTROLLER 0
+===================
+
 Clocks:
 -------
 
@@ -186,3 +189,42 @@ CP110_LABEL(syscon0): system-controller@440000 {
 	};
 
 };
+
+SYSTEM CONTROLLER 1
+===================
+
+Thermal:
+--------
+
+The thermal IP can probe the temperature all around the processor. It
+may feature several channels, each of them wired to one sensor.
+
+It is possible to setup an overheat interrupt by giving at least one
+critical point to any subnode of the thermal-zone node.
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/thermal/thermal.txt
+
+Required properties:
+- compatible: "marvell,armada-cp110-thermal"
+
+Optional properties:
+- interrupt-parent/interrupts: overheat interrupt handle. Should point to
+  line 37 of the SEI irqchip (shared between CPs).
+  See interrupt-controller/interrupts.txt
+- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
+  to this IP and represents the channel ID. There is one sensor per
+  channel. O refers to the thermal IP internal channel.
+
+Example:
+CP110_LABEL(syscon1): system-controller@6f8000 {
+	compatible = "syscon", "simple-mfd";
+	reg = <0x6f8000 0x1000>;
+
+	CP110_LABEL(thermal): ap-thermal {
+		compatible = "marvell,armada-cp110-thermal";
+		interrupt-parent = <&sei>;
+		interrupts = <37>;
+		#thermal-sensor-cells = <1>;
+	};
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 19/27] dt-bindings: cp110: add the thermal node in the syscon file
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Explain the thermal bindings now that the thermal IP is described being
inside of a system controller. Add a reference to the thermal-zone node.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../arm/marvell/cp110-system-controller.txt        | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
index 54b0d64ce819..e372c21d2a57 100644
--- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
@@ -11,6 +11,9 @@ For the top level node:
  - compatible: must be: "syscon", "simple-mfd";
  - reg: register area of the CP110 system controller
 
+SYSTEM CONTROLLER 0
+===================
+
 Clocks:
 -------
 
@@ -186,3 +189,42 @@ CP110_LABEL(syscon0): system-controller at 440000 {
 	};
 
 };
+
+SYSTEM CONTROLLER 1
+===================
+
+Thermal:
+--------
+
+The thermal IP can probe the temperature all around the processor. It
+may feature several channels, each of them wired to one sensor.
+
+It is possible to setup an overheat interrupt by giving at least one
+critical point to any subnode of the thermal-zone node.
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/thermal/thermal.txt
+
+Required properties:
+- compatible: "marvell,armada-cp110-thermal"
+
+Optional properties:
+- interrupt-parent/interrupts: overheat interrupt handle. Should point to
+  line 37 of the SEI irqchip (shared between CPs).
+  See interrupt-controller/interrupts.txt
+- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
+  to this IP and represents the channel ID. There is one sensor per
+  channel. O refers to the thermal IP internal channel.
+
+Example:
+CP110_LABEL(syscon1): system-controller at 6f8000 {
+	compatible = "syscon", "simple-mfd";
+	reg = <0x6f8000 0x1000>;
+
+	CP110_LABEL(thermal): ap-thermal {
+		compatible = "marvell,armada-cp110-thermal";
+		interrupt-parent = <&sei>;
+		interrupts = <37>;
+		#thermal-sensor-cells = <1>;
+	};
+};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 20/27] dt-bindings: thermal: armada: add reference to new bindings
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

New bindings (with the syscon and the overheat interrupt) are available
for AP806 and CP110 compatibles. Add a reference to these files from the
original documentation.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 Documentation/devicetree/bindings/thermal/armada-thermal.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
index e0d013a2e66d..f3b441100890 100644
--- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
@@ -10,6 +10,11 @@ Required properties:
     * marvell,armada-ap806-thermal
     * marvell,armada-cp110-thermal
 
+Note: these bindings are deprecated for AP806/CP110 and should instead
+follow the rules described in:
+Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+
 - reg: Device's register space.
   Two entries are expected, see the examples below. The first one points
   to the status register (4B). The second one points to the control
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 20/27] dt-bindings: thermal: armada: add reference to new bindings
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

New bindings (with the syscon and the overheat interrupt) are available
for AP806 and CP110 compatibles. Add a reference to these files from the
original documentation.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 Documentation/devicetree/bindings/thermal/armada-thermal.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
index e0d013a2e66d..f3b441100890 100644
--- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
@@ -10,6 +10,11 @@ Required properties:
     * marvell,armada-ap806-thermal
     * marvell,armada-cp110-thermal
 
+Note: these bindings are deprecated for AP806/CP110 and should instead
+follow the rules described in:
+Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
+
 - reg: Device's register space.
   Two entries are expected, see the examples below. The first one points
   to the status register (4B). The second one points to the control
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 21/27] arm64: dts: marvell: rename ap806 syscon node
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

In CP files, the syscons are called CP110_LABEL(syscon<x>) in case of
future additions. Use the same logic here to prepare the addition of a
second syscon to access both the thermal IP, the DFX server registers
and later probably other registers within this same memory area.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../devicetree/bindings/arm/marvell/ap806-system-controller.txt         | 2 +-
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi                           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index c95f3ac5c728..3e1ceba1ab84 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -79,7 +79,7 @@ Required properties:
 - offset: offset address inside the syscon block
 
 Example:
-ap_syscon: system-controller@6f4000 {
+ap_syscon0: system-controller@6f4000 {
 	compatible = "syscon", "simple-mfd";
 	reg = <0x6f4000 0x1000>;
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index ebda3edeceed..71208aba4468 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -238,7 +238,7 @@
 				status = "disabled";
 			};
 
-			ap_syscon: system-controller@6f4000 {
+			ap_syscon0: system-controller@6f4000 {
 				compatible = "syscon", "simple-mfd";
 				reg = <0x6f4000 0x2000>;
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 21/27] arm64: dts: marvell: rename ap806 syscon node
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

In CP files, the syscons are called CP110_LABEL(syscon<x>) in case of
future additions. Use the same logic here to prepare the addition of a
second syscon to access both the thermal IP, the DFX server registers
and later probably other registers within this same memory area.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../devicetree/bindings/arm/marvell/ap806-system-controller.txt         | 2 +-
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi                           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
index c95f3ac5c728..3e1ceba1ab84 100644
--- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
@@ -79,7 +79,7 @@ Required properties:
 - offset: offset address inside the syscon block
 
 Example:
-ap_syscon: system-controller at 6f4000 {
+ap_syscon0: system-controller at 6f4000 {
 	compatible = "syscon", "simple-mfd";
 	reg = <0x6f4000 0x1000>;
 
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index ebda3edeceed..71208aba4468 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -238,7 +238,7 @@
 				status = "disabled";
 			};
 
-			ap_syscon: system-controller at 6f4000 {
+			ap_syscon0: system-controller at 6f4000 {
 				compatible = "syscon", "simple-mfd";
 				reg = <0x6f4000 0x2000>;
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 22/27] arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

New bindings impose to declare the thermal IP from within a new syscon.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 11 +++++++----
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 15 +++++++++------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 71208aba4468..b173d21f2216 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -266,10 +266,13 @@
 				};
 			};
 
-			ap_thermal: thermal@6f808c {
-				compatible = "marvell,armada-ap806-thermal";
-				reg = <0x6f808c 0x4>,
-				      <0x6f8084 0x8>;
+			ap_syscon1: system-controller@6f8000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x6f8000 0x1000>;
+
+				ap_thermal: ap-thermal {
+					compatible = "marvell,armada-ap806-thermal";
+				};
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 8e989c721b4c..514780980847 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -170,12 +170,6 @@
 			interrupts = <77 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		CP110_LABEL(thermal): thermal@400078 {
-			compatible = "marvell,armada-cp110-thermal";
-			reg = <0x400078 0x4>,
-			<0x400070 0x8>;
-		};
-
 		CP110_LABEL(syscon0): system-controller@440000 {
 			compatible = "syscon", "simple-mfd";
 			reg = <0x440000 0x2000>;
@@ -216,6 +210,15 @@
 			};
 		};
 
+		CP110_LABEL(syscon1): system-controller@400000 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x400000 0x1000>;
+
+			CP110_LABEL(thermal): thermal@400070 {
+				compatible = "marvell,armada-cp110-thermal";
+			};
+		};
+
 		CP110_LABEL(usb3_0): usb3@500000 {
 			compatible = "marvell,armada-8k-xhci",
 			"generic-xhci";
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 22/27] arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

New bindings impose to declare the thermal IP from within a new syscon.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 11 +++++++----
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 15 +++++++++------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 71208aba4468..b173d21f2216 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -266,10 +266,13 @@
 				};
 			};
 
-			ap_thermal: thermal at 6f808c {
-				compatible = "marvell,armada-ap806-thermal";
-				reg = <0x6f808c 0x4>,
-				      <0x6f8084 0x8>;
+			ap_syscon1: system-controller at 6f8000 {
+				compatible = "syscon", "simple-mfd";
+				reg = <0x6f8000 0x1000>;
+
+				ap_thermal: ap-thermal {
+					compatible = "marvell,armada-ap806-thermal";
+				};
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 8e989c721b4c..514780980847 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -170,12 +170,6 @@
 			interrupts = <77 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		CP110_LABEL(thermal): thermal at 400078 {
-			compatible = "marvell,armada-cp110-thermal";
-			reg = <0x400078 0x4>,
-			<0x400070 0x8>;
-		};
-
 		CP110_LABEL(syscon0): system-controller at 440000 {
 			compatible = "syscon", "simple-mfd";
 			reg = <0x440000 0x2000>;
@@ -216,6 +210,15 @@
 			};
 		};
 
+		CP110_LABEL(syscon1): system-controller at 400000 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x400000 0x1000>;
+
+			CP110_LABEL(thermal): thermal at 400070 {
+				compatible = "marvell,armada-cp110-thermal";
+			};
+		};
+
 		CP110_LABEL(usb3_0): usb3 at 500000 {
 			compatible = "marvell,armada-8k-xhci",
 			"generic-xhci";
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 23/27] arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Add a thermal-zone node and fill in all the sensors available in an
ap806 (one in the IC plus one per CPU).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 60 +++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index b173d21f2216..a6fee3ccbc11 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
 
 /dts-v1/;
 
@@ -272,8 +273,67 @@
 
 				ap_thermal: ap-thermal {
 					compatible = "marvell,armada-ap806-thermal";
+					#thermal-sensor-cells = <1>;
 				};
 			};
 		};
 	};
+
+	/*
+	 * The thermal IP features one internal sensor plus, if applicable, one
+	 * remote channel wired to one sensor per CPU.
+	 *
+	 * The cooling maps are always empty as there are no cooling devices.
+	 */
+	thermal-zones {
+		ap_thermal_ic: ap-thermal-ic {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 0>;
+
+			trips {	};
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu1: ap-thermal-cpu1 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 1>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu2: ap-thermal-cpu2 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 2>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu3: ap-thermal-cpu3 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 3>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu4: ap-thermal-cpu4 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 4>;
+
+			trips { };
+			cooling-maps { };
+		};
+	};
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 23/27] arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add a thermal-zone node and fill in all the sensors available in an
ap806 (one in the IC plus one per CPU).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 60 +++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index b173d21f2216..a6fee3ccbc11 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
 
 /dts-v1/;
 
@@ -272,8 +273,67 @@
 
 				ap_thermal: ap-thermal {
 					compatible = "marvell,armada-ap806-thermal";
+					#thermal-sensor-cells = <1>;
 				};
 			};
 		};
 	};
+
+	/*
+	 * The thermal IP features one internal sensor plus, if applicable, one
+	 * remote channel wired to one sensor per CPU.
+	 *
+	 * The cooling maps are always empty as there are no cooling devices.
+	 */
+	thermal-zones {
+		ap_thermal_ic: ap-thermal-ic {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 0>;
+
+			trips {	};
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu1: ap-thermal-cpu1 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 1>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu2: ap-thermal-cpu2 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 2>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu3: ap-thermal-cpu3 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 3>;
+
+			trips { };
+			cooling-maps { };
+		};
+
+		ap_thermal_cpu4: ap-thermal-cpu4 {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&ap_thermal 4>;
+
+			trips { };
+			cooling-maps { };
+		};
+	};
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 24/27] arm64: dts: marvell: add macro to make distinction between node names
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Because the label is different between CPs, the full path of a node is
unique. However, when referring to the end of the path only (the node
name), this name is not unique anymore.

The *thermal_zone_of_sensor_register() functions of the thermal core
present this limitation and prevent having a thermal-zone per CP.

Add a macro to make the distinction between node names to solve this
situation.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-common.dtsi b/arch/arm64/boot/dts/marvell/armada-common.dtsi
index d5e8aedec188..b29c6405d214 100644
--- a/arch/arm64/boot/dts/marvell/armada-common.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-common.dtsi
@@ -7,4 +7,5 @@
 #define PASTER(x, y) x ## y
 #define EVALUATOR(x, y) PASTER(x, y)
 #define CP110_LABEL(name) EVALUATOR(CP110_NAME, EVALUATOR(_, name))
+#define CP110_NODE_NAME(name) EVALUATOR(CP110_NAME, EVALUATOR(-, name))
 #define ADDRESSIFY(addr) EVALUATOR(0x, addr)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 24/27] arm64: dts: marvell: add macro to make distinction between node names
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Because the label is different between CPs, the full path of a node is
unique. However, when referring to the end of the path only (the node
name), this name is not unique anymore.

The *thermal_zone_of_sensor_register() functions of the thermal core
present this limitation and prevent having a thermal-zone per CP.

Add a macro to make the distinction between node names to solve this
situation.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-common.dtsi b/arch/arm64/boot/dts/marvell/armada-common.dtsi
index d5e8aedec188..b29c6405d214 100644
--- a/arch/arm64/boot/dts/marvell/armada-common.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-common.dtsi
@@ -7,4 +7,5 @@
 #define PASTER(x, y) x ## y
 #define EVALUATOR(x, y) PASTER(x, y)
 #define CP110_LABEL(name) EVALUATOR(CP110_NAME, EVALUATOR(_, name))
+#define CP110_NODE_NAME(name) EVALUATOR(CP110_NAME, EVALUATOR(-, name))
 #define ADDRESSIFY(addr) EVALUATOR(0x, addr)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 25/27] arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Add a thermal-zone node and fill in all the sensors available in a
cp110 (only one in the thermal IP).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 514780980847..8d0fc1bfe291 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 #include "armada-common.dtsi"
 
@@ -19,6 +20,23 @@
 	 * save one indentation level
 	 */
 	CP110_NAME: CP110_NAME { };
+
+	/*
+	 * CPs only have one sensor in the thermal IC.
+	 *
+	 * The cooling maps are empty as there are no cooling devices.
+	 */
+	thermal-zones {
+		CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&CP110_LABEL(thermal) 0>;
+
+			trips {	};
+			cooling-maps { };
+		};
+	};
 };
 
 &CP110_NAME {
@@ -216,6 +234,7 @@
 
 			CP110_LABEL(thermal): thermal@400070 {
 				compatible = "marvell,armada-cp110-thermal";
+				#thermal-sensor-cells = <1>;
 			};
 		};
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 25/27] arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add a thermal-zone node and fill in all the sensors available in a
cp110 (only one in the thermal IP).

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 514780980847..8d0fc1bfe291 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 #include "armada-common.dtsi"
 
@@ -19,6 +20,23 @@
 	 * save one indentation level
 	 */
 	CP110_NAME: CP110_NAME { };
+
+	/*
+	 * CPs only have one sensor in the thermal IC.
+	 *
+	 * The cooling maps are empty as there are no cooling devices.
+	 */
+	thermal-zones {
+		CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
+			polling-delay-passive = <1000>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&CP110_LABEL(thermal) 0>;
+
+			trips {	};
+			cooling-maps { };
+		};
+	};
 };
 
 &CP110_NAME {
@@ -216,6 +234,7 @@
 
 			CP110_LABEL(thermal): thermal at 400070 {
 				compatible = "marvell,armada-cp110-thermal";
+				#thermal-sensor-cells = <1>;
 			};
 		};
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 26/27] arm64: dts: marvell: add interrupt support to ap806 thermal node
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Add interrupt properties in the thermal node as well as a critical trip
point in the thermal-zone.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index a6fee3ccbc11..d5a7448896b2 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -273,6 +273,8 @@
 
 				ap_thermal: ap-thermal {
 					compatible = "marvell,armada-ap806-thermal";
+					interrupt-parent = <&sei_wired_controller>;
+					interrupts = <18>;
 					#thermal-sensor-cells = <1>;
 				};
 			};
@@ -283,16 +285,26 @@
 	 * The thermal IP features one internal sensor plus, if applicable, one
 	 * remote channel wired to one sensor per CPU.
 	 *
+	 * Only one thermal zone per AP/CP may trigger interrupts at a time, the
+	 * first one that will have a critical trip point will be chosen.
+	 *
 	 * The cooling maps are always empty as there are no cooling devices.
 	 */
 	thermal-zones {
 		ap_thermal_ic: ap-thermal-ic {
-			polling-delay-passive = <1000>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>; /* Interrupt driven */
+			polling-delay = <0>; /* Interrupt driven */
 
 			thermal-sensors = <&ap_thermal 0>;
 
-			trips {	};
+			trips {
+				ap_crit: ap-crit {
+					temperature = <100000>; /* mC degrees */
+					hysteresis = <2000>; /* mC degrees */
+					type = "critical";
+				};
+			};
+
 			cooling-maps { };
 		};
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 26/27] arm64: dts: marvell: add interrupt support to ap806 thermal node
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add interrupt properties in the thermal node as well as a critical trip
point in the thermal-zone.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index a6fee3ccbc11..d5a7448896b2 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -273,6 +273,8 @@
 
 				ap_thermal: ap-thermal {
 					compatible = "marvell,armada-ap806-thermal";
+					interrupt-parent = <&sei_wired_controller>;
+					interrupts = <18>;
 					#thermal-sensor-cells = <1>;
 				};
 			};
@@ -283,16 +285,26 @@
 	 * The thermal IP features one internal sensor plus, if applicable, one
 	 * remote channel wired to one sensor per CPU.
 	 *
+	 * Only one thermal zone per AP/CP may trigger interrupts at a time, the
+	 * first one that will have a critical trip point will be chosen.
+	 *
 	 * The cooling maps are always empty as there are no cooling devices.
 	 */
 	thermal-zones {
 		ap_thermal_ic: ap-thermal-ic {
-			polling-delay-passive = <1000>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>; /* Interrupt driven */
+			polling-delay = <0>; /* Interrupt driven */
 
 			thermal-sensors = <&ap_thermal 0>;
 
-			trips {	};
+			trips {
+				ap_crit: ap-crit {
+					temperature = <100000>; /* mC degrees */
+					hysteresis = <2000>; /* mC degrees */
+					type = "critical";
+				};
+			};
+
 			cooling-maps { };
 		};
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 27/27] arm64: dts: marvell: add interrupt support to cp110 thermal node
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-04-21 15:12   ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: Gregory Clement, Jason Cooper, Andrew Lunn,
	Sebastian Hesselbarth, Zhang Rui, Eduardo Valentin
  Cc: Mark Rutland, devicetree, linux-pm, Antoine Tenart,
	Catalin Marinas, Will Deacon, Maxime Chevallier, Nadav Haklai,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Miquel Raynal,
	linux-arm-kernel

Add interrupt properties in the thermal node as well as a critical trip
point in the thermal-zone.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 8d0fc1bfe291..06f265d61352 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -28,12 +28,19 @@
 	 */
 	thermal-zones {
 		CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
-			polling-delay-passive = <1000>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>; /* Interrupt driven */
+			polling-delay = <0>; /* Interrupt driven */
 
 			thermal-sensors = <&CP110_LABEL(thermal) 0>;
 
-			trips {	};
+			trips {
+				CP110_LABEL(crit): crit {
+					temperature = <100000>; /* mC degrees */
+					hysteresis = <2000>; /* mC degrees */
+					type = "critical";
+				};
+			};
+
 			cooling-maps { };
 		};
 	};
@@ -177,7 +184,7 @@
 				compatible = "marvell,cp110-icu-sei";
 				#interrupt-cells = <2>;
 				interrupt-controller;
-				msi-parent = <&sei>;
+				msi-parent = <&sei_msi_controller>;
 			};
 		};
 
@@ -234,6 +241,8 @@
 
 			CP110_LABEL(thermal): thermal@400070 {
 				compatible = "marvell,armada-cp110-thermal";
+				interrupts-extended =
+					<&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
 				#thermal-sensor-cells = <1>;
 			};
 		};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 27/27] arm64: dts: marvell: add interrupt support to cp110 thermal node
@ 2018-04-21 15:12   ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-21 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add interrupt properties in the thermal node as well as a critical trip
point in the thermal-zone.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
index 8d0fc1bfe291..06f265d61352 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110.dtsi
@@ -28,12 +28,19 @@
 	 */
 	thermal-zones {
 		CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
-			polling-delay-passive = <1000>;
-			polling-delay = <1000>;
+			polling-delay-passive = <0>; /* Interrupt driven */
+			polling-delay = <0>; /* Interrupt driven */
 
 			thermal-sensors = <&CP110_LABEL(thermal) 0>;
 
-			trips {	};
+			trips {
+				CP110_LABEL(crit): crit {
+					temperature = <100000>; /* mC degrees */
+					hysteresis = <2000>; /* mC degrees */
+					type = "critical";
+				};
+			};
+
 			cooling-maps { };
 		};
 	};
@@ -177,7 +184,7 @@
 				compatible = "marvell,cp110-icu-sei";
 				#interrupt-cells = <2>;
 				interrupt-controller;
-				msi-parent = <&sei>;
+				msi-parent = <&sei_msi_controller>;
 			};
 		};
 
@@ -234,6 +241,8 @@
 
 			CP110_LABEL(thermal): thermal at 400070 {
 				compatible = "marvell,armada-cp110-thermal";
+				interrupts-extended =
+					<&CP110_LABEL(icu_sei) 116 IRQ_TYPE_LEVEL_HIGH>;
 				#thermal-sensor-cells = <1>;
 			};
 		};
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* Re: [PATCH 14/27] dt-bindings: cp110: rename cp110 syscon file
  2018-04-21 15:12   ` Miquel Raynal
@ 2018-04-27 20:51     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 20:51 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

On Sat, Apr 21, 2018 at 05:12:42PM +0200, Miquel Raynal wrote:
> There is no need to give numbers to system controllers inside the
> documentation as the syscons use the same compatibles. Furthermore, this
> approach does not scale very well and would force the creation of a new
> file each time a new syscon is added in the device tree.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} | 0
>  1 file changed, 0 insertions(+), 0 deletions(-)
>  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (100%)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 14/27] dt-bindings: cp110: rename cp110 syscon file
@ 2018-04-27 20:51     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 21, 2018 at 05:12:42PM +0200, Miquel Raynal wrote:
> There is no need to give numbers to system controllers inside the
> documentation as the syscons use the same compatibles. Furthermore, this
> approach does not scale very well and would force the creation of a new
> file each time a new syscon is added in the device tree.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} | 0
>  1 file changed, 0 insertions(+), 0 deletions(-)
>  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (100%)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
  2018-04-21 15:12   ` Miquel Raynal
@ 2018-04-27 21:06     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:06 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

On Sat, Apr 21, 2018 at 05:12:44PM +0200, Miquel Raynal wrote:
> There are multiple system controllers in CP110. Because all syscon nodes
> use the same compatible, it is pertinent to use this same file to list
> IPs inside it. Thus, change the header to be more generic, and align
> with AP806 file.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> index 29cdbae6c5ac..56e7fb1153e7 100644
> --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> @@ -1,15 +1,15 @@
> -Marvell Armada CP110 System Controller 0
> -========================================
> +Marvell Armada CP110 System Controller
> +======================================
>  
>  The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
> -SoCs. It contains two sets of system control registers, System
> -Controller 0 and System Controller 1. This Device Tree binding allows
> -to describe the first system controller, which provides registers to
> -configure various aspects of the SoC.
> +SoCs. It contains system controllers, which provide several registers

Is this really multiple discrete blocks?

> +giving access to numerous features: clocks, pin-muxing and many other
> +SoC configuration items. This DT binding allows to describe these
> +system controllers.
>  
>  For the top level node:
>   - compatible: must be: "syscon", "simple-mfd";
> - - reg: register area of the CP110 system controller 0
> + - reg: register area of the CP110 system controller
>  
>  Clocks:
>  -------
> -- 
> 2.14.1
> 

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
@ 2018-04-27 21:06     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 21, 2018 at 05:12:44PM +0200, Miquel Raynal wrote:
> There are multiple system controllers in CP110. Because all syscon nodes
> use the same compatible, it is pertinent to use this same file to list
> IPs inside it. Thus, change the header to be more generic, and align
> with AP806 file.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> index 29cdbae6c5ac..56e7fb1153e7 100644
> --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> @@ -1,15 +1,15 @@
> -Marvell Armada CP110 System Controller 0
> -========================================
> +Marvell Armada CP110 System Controller
> +======================================
>  
>  The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
> -SoCs. It contains two sets of system control registers, System
> -Controller 0 and System Controller 1. This Device Tree binding allows
> -to describe the first system controller, which provides registers to
> -configure various aspects of the SoC.
> +SoCs. It contains system controllers, which provide several registers

Is this really multiple discrete blocks?

> +giving access to numerous features: clocks, pin-muxing and many other
> +SoC configuration items. This DT binding allows to describe these
> +system controllers.
>  
>  For the top level node:
>   - compatible: must be: "syscon", "simple-mfd";
> - - reg: register area of the CP110 system controller 0
> + - reg: register area of the CP110 system controller
>  
>  Clocks:
>  -------
> -- 
> 2.14.1
> 

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
  2018-04-21 15:12   ` Miquel Raynal
@ 2018-04-27 21:07     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:07 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> Explain the thermal bindings now that the thermal IP is described being
> inside of a system controller. Add a reference to the thermal-zone node.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> index a856eb9a4e05..c95f3ac5c728 100644
> --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> @@ -11,6 +11,9 @@ For the top level node:
>   - compatible: must be: "syscon", "simple-mfd";
>   - reg: register area of the AP806 system controller
>  
> +SYSTEM CONTROLLER 0
> +===================
> +
>  Clocks:
>  -------
>  
> @@ -98,3 +101,43 @@ ap_syscon: system-controller@6f4000 {
>  		gpio-ranges = <&ap_pinctrl 0 0 19>;
>  	};
>  };
> +
> +SYSTEM CONTROLLER 1
> +===================
> +
> +Thermal:
> +--------
> +
> +For common binding part and usage, refer to
> +Documentation/devicetree/bindings/thermal/thermal.txt
> +
> +The thermal IP can probe the temperature all around the processor. It
> +may feature several channels, each of them wired to one sensor.
> +
> +It is possible to setup an overheat interrupt by giving at least one
> +critical point to any subnode of the thermal-zone node.
> +
> +Required properties:
> +- compatible: "marvell,armada-ap806-thermal"
> +
> +Optional properties:
> +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> +  line 18 of the SEI irqchip.
> +  See interrupt-controller/interrupts.txt
> +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> +  to this IP and represents the channel ID. There is one sensor per
> +  channel. O refers to the thermal IP internal channel, while positive
> +  IDs refer to each CPU.
> +
> +Example:
> +ap_syscon1: system-controller@6f8000 {
> +	compatible = "syscon", "simple-mfd";
> +	reg = <0x6f8000 0x1000>;
> +
> +	ap_thermal: ap-thermal {
> +		compatible = "marvell,armada-ap806-thermal";

Is there a register range associated with the thermal functions?

> +		interrupt-parent = <&sei>;
> +		interrupts = <18>;
> +		#thermal-sensor-cells = <1>;
> +	};
> +};
> -- 
> 2.14.1
> 

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
@ 2018-04-27 21:07     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> Explain the thermal bindings now that the thermal IP is described being
> inside of a system controller. Add a reference to the thermal-zone node.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> index a856eb9a4e05..c95f3ac5c728 100644
> --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> @@ -11,6 +11,9 @@ For the top level node:
>   - compatible: must be: "syscon", "simple-mfd";
>   - reg: register area of the AP806 system controller
>  
> +SYSTEM CONTROLLER 0
> +===================
> +
>  Clocks:
>  -------
>  
> @@ -98,3 +101,43 @@ ap_syscon: system-controller at 6f4000 {
>  		gpio-ranges = <&ap_pinctrl 0 0 19>;
>  	};
>  };
> +
> +SYSTEM CONTROLLER 1
> +===================
> +
> +Thermal:
> +--------
> +
> +For common binding part and usage, refer to
> +Documentation/devicetree/bindings/thermal/thermal.txt
> +
> +The thermal IP can probe the temperature all around the processor. It
> +may feature several channels, each of them wired to one sensor.
> +
> +It is possible to setup an overheat interrupt by giving at least one
> +critical point to any subnode of the thermal-zone node.
> +
> +Required properties:
> +- compatible: "marvell,armada-ap806-thermal"
> +
> +Optional properties:
> +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> +  line 18 of the SEI irqchip.
> +  See interrupt-controller/interrupts.txt
> +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> +  to this IP and represents the channel ID. There is one sensor per
> +  channel. O refers to the thermal IP internal channel, while positive
> +  IDs refer to each CPU.
> +
> +Example:
> +ap_syscon1: system-controller at 6f8000 {
> +	compatible = "syscon", "simple-mfd";
> +	reg = <0x6f8000 0x1000>;
> +
> +	ap_thermal: ap-thermal {
> +		compatible = "marvell,armada-ap806-thermal";

Is there a register range associated with the thermal functions?

> +		interrupt-parent = <&sei>;
> +		interrupts = <18>;
> +		#thermal-sensor-cells = <1>;
> +	};
> +};
> -- 
> 2.14.1
> 

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 18/27] dt-bindings: cp110: update documentation since DT de-duplication
  2018-04-21 15:12   ` Miquel Raynal
@ 2018-04-27 21:08     ` Rob Herring
  -1 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:08 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

On Sat, Apr 21, 2018 at 05:12:46PM +0200, Miquel Raynal wrote:
> CP110 master/slave DT files have been merged in a DT de-duplication work
> merged in v4.16. Update the syscon documentation accordingly to match
> the current state of the DT nodes.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../bindings/arm/marvell/cp110-system-controller.txt           | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 18/27] dt-bindings: cp110: update documentation since DT de-duplication
@ 2018-04-27 21:08     ` Rob Herring
  0 siblings, 0 replies; 76+ messages in thread
From: Rob Herring @ 2018-04-27 21:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 21, 2018 at 05:12:46PM +0200, Miquel Raynal wrote:
> CP110 master/slave DT files have been merged in a DT de-duplication work
> merged in v4.16. Update the syscon documentation accordingly to match
> the current state of the DT nodes.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> ---
>  .../bindings/arm/marvell/cp110-system-controller.txt           | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
  2018-04-27 21:07     ` Rob Herring
@ 2018-04-28 11:07       ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-28 11:07 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

Hi Rob,

On Fri, 27 Apr 2018 16:07:22 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> > Explain the thermal bindings now that the thermal IP is described being
> > inside of a system controller. Add a reference to the thermal-zone node.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > index a856eb9a4e05..c95f3ac5c728 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > @@ -11,6 +11,9 @@ For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> >   - reg: register area of the AP806 system controller
> >  
> > +SYSTEM CONTROLLER 0
> > +===================
> > +
> >  Clocks:
> >  -------
> >  
> > @@ -98,3 +101,43 @@ ap_syscon: system-controller@6f4000 {
> >  		gpio-ranges = <&ap_pinctrl 0 0 19>;
> >  	};
> >  };
> > +
> > +SYSTEM CONTROLLER 1
> > +===================
> > +
> > +Thermal:
> > +--------
> > +
> > +For common binding part and usage, refer to
> > +Documentation/devicetree/bindings/thermal/thermal.txt
> > +
> > +The thermal IP can probe the temperature all around the processor. It
> > +may feature several channels, each of them wired to one sensor.
> > +
> > +It is possible to setup an overheat interrupt by giving at least one
> > +critical point to any subnode of the thermal-zone node.
> > +
> > +Required properties:
> > +- compatible: "marvell,armada-ap806-thermal"
> > +
> > +Optional properties:
> > +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> > +  line 18 of the SEI irqchip.
> > +  See interrupt-controller/interrupts.txt
> > +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> > +  to this IP and represents the channel ID. There is one sensor per
> > +  channel. O refers to the thermal IP internal channel, while positive
> > +  IDs refer to each CPU.
> > +
> > +Example:
> > +ap_syscon1: system-controller@6f8000 {
> > +	compatible = "syscon", "simple-mfd";
> > +	reg = <0x6f8000 0x1000>;
> > +
> > +	ap_thermal: ap-thermal {
> > +		compatible = "marvell,armada-ap806-thermal";  
> 
> Is there a register range associated with the thermal functions?

Yes, I will add it.

Thanks,
Miquèl

> 
> > +		interrupt-parent = <&sei>;
> > +		interrupts = <18>;
> > +		#thermal-sensor-cells = <1>;
> > +	};
> > +};
> > -- 
> > 2.14.1
> >   

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
@ 2018-04-28 11:07       ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-28 11:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On Fri, 27 Apr 2018 16:07:22 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> > Explain the thermal bindings now that the thermal IP is described being
> > inside of a system controller. Add a reference to the thermal-zone node.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > index a856eb9a4e05..c95f3ac5c728 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > @@ -11,6 +11,9 @@ For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> >   - reg: register area of the AP806 system controller
> >  
> > +SYSTEM CONTROLLER 0
> > +===================
> > +
> >  Clocks:
> >  -------
> >  
> > @@ -98,3 +101,43 @@ ap_syscon: system-controller at 6f4000 {
> >  		gpio-ranges = <&ap_pinctrl 0 0 19>;
> >  	};
> >  };
> > +
> > +SYSTEM CONTROLLER 1
> > +===================
> > +
> > +Thermal:
> > +--------
> > +
> > +For common binding part and usage, refer to
> > +Documentation/devicetree/bindings/thermal/thermal.txt
> > +
> > +The thermal IP can probe the temperature all around the processor. It
> > +may feature several channels, each of them wired to one sensor.
> > +
> > +It is possible to setup an overheat interrupt by giving at least one
> > +critical point to any subnode of the thermal-zone node.
> > +
> > +Required properties:
> > +- compatible: "marvell,armada-ap806-thermal"
> > +
> > +Optional properties:
> > +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> > +  line 18 of the SEI irqchip.
> > +  See interrupt-controller/interrupts.txt
> > +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> > +  to this IP and represents the channel ID. There is one sensor per
> > +  channel. O refers to the thermal IP internal channel, while positive
> > +  IDs refer to each CPU.
> > +
> > +Example:
> > +ap_syscon1: system-controller at 6f8000 {
> > +	compatible = "syscon", "simple-mfd";
> > +	reg = <0x6f8000 0x1000>;
> > +
> > +	ap_thermal: ap-thermal {
> > +		compatible = "marvell,armada-ap806-thermal";  
> 
> Is there a register range associated with the thermal functions?

Yes, I will add it.

Thanks,
Miqu?l

> 
> > +		interrupt-parent = <&sei>;
> > +		interrupts = <18>;
> > +		#thermal-sensor-cells = <1>;
> > +	};
> > +};
> > -- 
> > 2.14.1
> >   

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
  2018-04-27 21:06     ` Rob Herring
@ 2018-04-28 11:20       ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-28 11:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

Hi Rob,

On Fri, 27 Apr 2018 16:06:03 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:44PM +0200, Miquel Raynal wrote:
> > There are multiple system controllers in CP110. Because all syscon nodes
> > use the same compatible, it is pertinent to use this same file to list
> > IPs inside it. Thus, change the header to be more generic, and align
> > with AP806 file.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > index 29cdbae6c5ac..56e7fb1153e7 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > @@ -1,15 +1,15 @@
> > -Marvell Armada CP110 System Controller 0
> > -========================================
> > +Marvell Armada CP110 System Controller
> > +======================================
> >  
> >  The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
> > -SoCs. It contains two sets of system control registers, System
> > -Controller 0 and System Controller 1. This Device Tree binding allows
> > -to describe the first system controller, which provides registers to
> > -configure various aspects of the SoC.
> > +SoCs. It contains system controllers, which provide several registers  
> 
> Is this really multiple discrete blocks?

I can't tell for sure, but the specification clearly names the
#6f8000-#6f9000 region as "AP General Management Registers" and does
not refer in any manner to the other (already described) syscon at
#6f4000-#6f6000 which is used for clocks and pinctrl management
already.

> 
> > +giving access to numerous features: clocks, pin-muxing and many other
> > +SoC configuration items. This DT binding allows to describe these
> > +system controllers.
> >  
> >  For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> > - - reg: register area of the CP110 system controller 0
> > + - reg: register area of the CP110 system controller
> >  
> >  Clocks:
> >  -------
> > -- 
> > 2.14.1
> >   

Regards,
Miquèl


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 16/27] dt-bindings: cp110: prepare the syscon file to list other syscons nodes
@ 2018-04-28 11:20       ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-04-28 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

On Fri, 27 Apr 2018 16:06:03 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:44PM +0200, Miquel Raynal wrote:
> > There are multiple system controllers in CP110. Because all syscon nodes
> > use the same compatible, it is pertinent to use this same file to list
> > IPs inside it. Thus, change the header to be more generic, and align
> > with AP806 file.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../bindings/arm/marvell/cp110-system-controller.txt       | 14 +++++++-------
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > index 29cdbae6c5ac..56e7fb1153e7 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
> > @@ -1,15 +1,15 @@
> > -Marvell Armada CP110 System Controller 0
> > -========================================
> > +Marvell Armada CP110 System Controller
> > +======================================
> >  
> >  The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
> > -SoCs. It contains two sets of system control registers, System
> > -Controller 0 and System Controller 1. This Device Tree binding allows
> > -to describe the first system controller, which provides registers to
> > -configure various aspects of the SoC.
> > +SoCs. It contains system controllers, which provide several registers  
> 
> Is this really multiple discrete blocks?

I can't tell for sure, but the specification clearly names the
#6f8000-#6f9000 region as "AP General Management Registers" and does
not refer in any manner to the other (already described) syscon at
#6f4000-#6f6000 which is used for clocks and pinctrl management
already.

> 
> > +giving access to numerous features: clocks, pin-muxing and many other
> > +SoC configuration items. This DT binding allows to describe these
> > +system controllers.
> >  
> >  For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> > - - reg: register area of the CP110 system controller 0
> > + - reg: register area of the CP110 system controller
> >  
> >  Clocks:
> >  -------
> > -- 
> > 2.14.1
> >   

Regards,
Miqu?l

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
  2018-04-21 15:12 ` Miquel Raynal
@ 2018-05-16 17:28   ` Gregory CLEMENT
  -1 siblings, 0 replies; 76+ messages in thread
From: Gregory CLEMENT @ 2018-05-16 17:28 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, linux-pm,
	Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Zhang Rui,
	linux-arm-kernel, Sebastian Hesselbarth

Hi Miquel,
 
 On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> The only capability of the Armada thermal driver is currently just to
> read one sensor (the default one) per AP and one per CP.
>
> Actually, there is one sensor per core in the AP806 plus one sensor in
> the thermal IP itself. The CP110 just features one thermal sensor in its
> own thermal IP.
>
> Also, there is no need for the thermal core to poll the temperature of
> each sensor by software as this IP (at least for AP806 and CP110
> compatibles) features an hardware overheat interrupt.
>
> This series first improves the readability of this driver, then adds
> support for multi-channel thermal IPs, and finally adds support for the
> hardware overheat interrupt. The bindings and the device-trees are
> updated accordingly.
>
> Please note that the thermal IP raises SEI interrupts, from which the
> support as just been contributed and not merged yet. Applying the last
> DT patches referring to the 'sei' and 'icu_sei' nodes will require this
> feature [1] to have been accepted first.
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html
>
> Thank you,
> Miquèl
>
>
> Miquel Raynal (27):
>   thermal: armada: add a function that sanitizes the thermal zone name
>   thermal: armada: remove useless register accesses
>   thermal: armada: remove misleading comments
>   thermal: armada: rename the initialization routine
>   thermal: armada: dissociate a380 and cp110 ->init() hooks
>   thermal: armada: average over samples to avoid glitches
>   thermal: armada: convert driver to syscon register accesses
>   thermal: armada: use the resource managed registration helper
>     alternative
>   thermal: armada: add multi-channel sensors support
>   thermal: armada: remove sensors validity from the IP initialization
>   thermal: armada: move validity check out of the read function
>   thermal: armada: get rid of the ->is_valid() pointer
>   thermal: armada: add overheat interrupt support
>   dt-bindings: cp110: rename cp110 syscon file
>   dt-bindings: ap806: prepare the syscon file to list other syscons
>     nodes
>   dt-bindings: cp110: prepare the syscon file to list other syscons
>     nodes
>   dt-bindings: ap806: add the thermal node in the syscon file
>   dt-bindings: cp110: update documentation since DT de-duplication
>   dt-bindings: cp110: add the thermal node in the syscon file
>   dt-bindings: thermal: armada: add reference to new bindings
>   arm64: dts: marvell: rename ap806 syscon node
>   arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
>   arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
>   arm64: dts: marvell: add macro to make distinction between node names
>   arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
>   arm64: dts: marvell: add interrupt support to ap806 thermal node
>   arm64: dts: marvell: add interrupt support to cp110 thermal node
>
>  .../arm/marvell/ap806-system-controller.txt        |  55 +-
>  ...controller0.txt => cp110-system-controller.txt} |  66 +-
>  .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
>  arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
>  arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
>  arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
>  drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
>  7 files changed, 976 insertions(+), 156 deletions(-)
>  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)

What is the status of this series?
I am especially interested in the dt part.
Do you expect sending a new series modifying them?

Gregory

>
> -- 
> 2.14.1
>

-- 
Gregory Clement, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
@ 2018-05-16 17:28   ` Gregory CLEMENT
  0 siblings, 0 replies; 76+ messages in thread
From: Gregory CLEMENT @ 2018-05-16 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Miquel,
 
 On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> The only capability of the Armada thermal driver is currently just to
> read one sensor (the default one) per AP and one per CP.
>
> Actually, there is one sensor per core in the AP806 plus one sensor in
> the thermal IP itself. The CP110 just features one thermal sensor in its
> own thermal IP.
>
> Also, there is no need for the thermal core to poll the temperature of
> each sensor by software as this IP (at least for AP806 and CP110
> compatibles) features an hardware overheat interrupt.
>
> This series first improves the readability of this driver, then adds
> support for multi-channel thermal IPs, and finally adds support for the
> hardware overheat interrupt. The bindings and the device-trees are
> updated accordingly.
>
> Please note that the thermal IP raises SEI interrupts, from which the
> support as just been contributed and not merged yet. Applying the last
> DT patches referring to the 'sei' and 'icu_sei' nodes will require this
> feature [1] to have been accepted first.
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html
>
> Thank you,
> Miqu?l
>
>
> Miquel Raynal (27):
>   thermal: armada: add a function that sanitizes the thermal zone name
>   thermal: armada: remove useless register accesses
>   thermal: armada: remove misleading comments
>   thermal: armada: rename the initialization routine
>   thermal: armada: dissociate a380 and cp110 ->init() hooks
>   thermal: armada: average over samples to avoid glitches
>   thermal: armada: convert driver to syscon register accesses
>   thermal: armada: use the resource managed registration helper
>     alternative
>   thermal: armada: add multi-channel sensors support
>   thermal: armada: remove sensors validity from the IP initialization
>   thermal: armada: move validity check out of the read function
>   thermal: armada: get rid of the ->is_valid() pointer
>   thermal: armada: add overheat interrupt support
>   dt-bindings: cp110: rename cp110 syscon file
>   dt-bindings: ap806: prepare the syscon file to list other syscons
>     nodes
>   dt-bindings: cp110: prepare the syscon file to list other syscons
>     nodes
>   dt-bindings: ap806: add the thermal node in the syscon file
>   dt-bindings: cp110: update documentation since DT de-duplication
>   dt-bindings: cp110: add the thermal node in the syscon file
>   dt-bindings: thermal: armada: add reference to new bindings
>   arm64: dts: marvell: rename ap806 syscon node
>   arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
>   arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
>   arm64: dts: marvell: add macro to make distinction between node names
>   arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
>   arm64: dts: marvell: add interrupt support to ap806 thermal node
>   arm64: dts: marvell: add interrupt support to cp110 thermal node
>
>  .../arm/marvell/ap806-system-controller.txt        |  55 +-
>  ...controller0.txt => cp110-system-controller.txt} |  66 +-
>  .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
>  arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
>  arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
>  arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
>  drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
>  7 files changed, 976 insertions(+), 156 deletions(-)
>  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)

What is the status of this series?
I am especially interested in the dt part.
Do you expect sending a new series modifying them?

Gregory

>
> -- 
> 2.14.1
>

-- 
Gregory Clement, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
  2018-05-16 17:28   ` Gregory CLEMENT
@ 2018-05-18  9:49     ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-05-18  9:49 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, linux-pm,
	Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni, Zhang Rui,
	linux-arm-kernel, Sebastian Hesselbarth

Hi Zhang, Eduardo & Gregory,

On Wed, 16 May 2018 19:28:45 +0200, Gregory CLEMENT
<gregory.clement@bootlin.com> wrote:

> Hi Miquel,
>  
>  On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> 
> > The only capability of the Armada thermal driver is currently just to
> > read one sensor (the default one) per AP and one per CP.
> >
> > Actually, there is one sensor per core in the AP806 plus one sensor in
> > the thermal IP itself. The CP110 just features one thermal sensor in its
> > own thermal IP.
> >
> > Also, there is no need for the thermal core to poll the temperature of
> > each sensor by software as this IP (at least for AP806 and CP110
> > compatibles) features an hardware overheat interrupt.
> >
> > This series first improves the readability of this driver, then adds
> > support for multi-channel thermal IPs, and finally adds support for the
> > hardware overheat interrupt. The bindings and the device-trees are
> > updated accordingly.
> >
> > Please note that the thermal IP raises SEI interrupts, from which the
> > support as just been contributed and not merged yet. Applying the last
> > DT patches referring to the 'sei' and 'icu_sei' nodes will require this
> > feature [1] to have been accepted first.
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html
> >
> > Thank you,
> > Miquèl
> >
> >
> > Miquel Raynal (27):
> >   thermal: armada: add a function that sanitizes the thermal zone name
> >   thermal: armada: remove useless register accesses
> >   thermal: armada: remove misleading comments
> >   thermal: armada: rename the initialization routine
> >   thermal: armada: dissociate a380 and cp110 ->init() hooks
> >   thermal: armada: average over samples to avoid glitches
> >   thermal: armada: convert driver to syscon register accesses
> >   thermal: armada: use the resource managed registration helper
> >     alternative
> >   thermal: armada: add multi-channel sensors support
> >   thermal: armada: remove sensors validity from the IP initialization
> >   thermal: armada: move validity check out of the read function
> >   thermal: armada: get rid of the ->is_valid() pointer
> >   thermal: armada: add overheat interrupt support
> >   dt-bindings: cp110: rename cp110 syscon file
> >   dt-bindings: ap806: prepare the syscon file to list other syscons
> >     nodes
> >   dt-bindings: cp110: prepare the syscon file to list other syscons
> >     nodes
> >   dt-bindings: ap806: add the thermal node in the syscon file
> >   dt-bindings: cp110: update documentation since DT de-duplication
> >   dt-bindings: cp110: add the thermal node in the syscon file
> >   dt-bindings: thermal: armada: add reference to new bindings
> >   arm64: dts: marvell: rename ap806 syscon node
> >   arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
> >   arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
> >   arm64: dts: marvell: add macro to make distinction between node names
> >   arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
> >   arm64: dts: marvell: add interrupt support to ap806 thermal node
> >   arm64: dts: marvell: add interrupt support to cp110 thermal node
> >
> >  .../arm/marvell/ap806-system-controller.txt        |  55 +-
> >  ...controller0.txt => cp110-system-controller.txt} |  66 +-
> >  .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
> >  arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
> >  arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
> >  arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
> >  drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
> >  7 files changed, 976 insertions(+), 156 deletions(-)
> >  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)  
> 
> What is the status of this series?
> I am especially interested in the dt part.
> Do you expect sending a new series modifying them?

I have not received any feedback yet on the thermal part, bindings have
been partially acked by Rob (one request, I will probably add a reg
property in the AP node) so please do not take the DTS changes of
this iteration.

Zhang, Eduardo, could you please share the status of this series?

Thanks,
Miquèl


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
@ 2018-05-18  9:49     ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-05-18  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Zhang, Eduardo & Gregory,

On Wed, 16 May 2018 19:28:45 +0200, Gregory CLEMENT
<gregory.clement@bootlin.com> wrote:

> Hi Miquel,
>  
>  On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> 
> > The only capability of the Armada thermal driver is currently just to
> > read one sensor (the default one) per AP and one per CP.
> >
> > Actually, there is one sensor per core in the AP806 plus one sensor in
> > the thermal IP itself. The CP110 just features one thermal sensor in its
> > own thermal IP.
> >
> > Also, there is no need for the thermal core to poll the temperature of
> > each sensor by software as this IP (at least for AP806 and CP110
> > compatibles) features an hardware overheat interrupt.
> >
> > This series first improves the readability of this driver, then adds
> > support for multi-channel thermal IPs, and finally adds support for the
> > hardware overheat interrupt. The bindings and the device-trees are
> > updated accordingly.
> >
> > Please note that the thermal IP raises SEI interrupts, from which the
> > support as just been contributed and not merged yet. Applying the last
> > DT patches referring to the 'sei' and 'icu_sei' nodes will require this
> > feature [1] to have been accepted first.
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/572852.html
> >
> > Thank you,
> > Miqu?l
> >
> >
> > Miquel Raynal (27):
> >   thermal: armada: add a function that sanitizes the thermal zone name
> >   thermal: armada: remove useless register accesses
> >   thermal: armada: remove misleading comments
> >   thermal: armada: rename the initialization routine
> >   thermal: armada: dissociate a380 and cp110 ->init() hooks
> >   thermal: armada: average over samples to avoid glitches
> >   thermal: armada: convert driver to syscon register accesses
> >   thermal: armada: use the resource managed registration helper
> >     alternative
> >   thermal: armada: add multi-channel sensors support
> >   thermal: armada: remove sensors validity from the IP initialization
> >   thermal: armada: move validity check out of the read function
> >   thermal: armada: get rid of the ->is_valid() pointer
> >   thermal: armada: add overheat interrupt support
> >   dt-bindings: cp110: rename cp110 syscon file
> >   dt-bindings: ap806: prepare the syscon file to list other syscons
> >     nodes
> >   dt-bindings: cp110: prepare the syscon file to list other syscons
> >     nodes
> >   dt-bindings: ap806: add the thermal node in the syscon file
> >   dt-bindings: cp110: update documentation since DT de-duplication
> >   dt-bindings: cp110: add the thermal node in the syscon file
> >   dt-bindings: thermal: armada: add reference to new bindings
> >   arm64: dts: marvell: rename ap806 syscon node
> >   arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon
> >   arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
> >   arm64: dts: marvell: add macro to make distinction between node names
> >   arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
> >   arm64: dts: marvell: add interrupt support to ap806 thermal node
> >   arm64: dts: marvell: add interrupt support to cp110 thermal node
> >
> >  .../arm/marvell/ap806-system-controller.txt        |  55 +-
> >  ...controller0.txt => cp110-system-controller.txt} |  66 +-
> >  .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
> >  arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
> >  arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
> >  arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
> >  drivers/thermal/armada_thermal.c                   | 875 ++++++++++++++++++---
> >  7 files changed, 976 insertions(+), 156 deletions(-)
> >  rename Documentation/devicetree/bindings/arm/marvell/{cp110-system-controller0.txt => cp110-system-controller.txt} (83%)  
> 
> What is the status of this series?
> I am especially interested in the dt part.
> Do you expect sending a new series modifying them?

I have not received any feedback yet on the thermal part, bindings have
been partially acked by Rob (one request, I will probably add a reg
property in the AP node) so please do not take the DTS changes of
this iteration.

Zhang, Eduardo, could you please share the status of this series?

Thanks,
Miqu?l

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
  2018-04-27 21:07     ` Rob Herring
@ 2018-05-18  9:56       ` Miquel Raynal
  -1 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-05-18  9:56 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, Gregory Clement,
	linux-pm, Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Thomas Petazzoni, Zhang Rui, linux-arm-kernel,
	Sebastian Hesselbarth

Hi Rob,

Thanks for reviewing, one question below.

On Fri, 27 Apr 2018 16:07:22 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> > Explain the thermal bindings now that the thermal IP is described being
> > inside of a system controller. Add a reference to the thermal-zone node.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > index a856eb9a4e05..c95f3ac5c728 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > @@ -11,6 +11,9 @@ For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> >   - reg: register area of the AP806 system controller
> >  
> > +SYSTEM CONTROLLER 0
> > +===================
> > +
> >  Clocks:
> >  -------
> >  
> > @@ -98,3 +101,43 @@ ap_syscon: system-controller@6f4000 {
> >  		gpio-ranges = <&ap_pinctrl 0 0 19>;
> >  	};
> >  };
> > +
> > +SYSTEM CONTROLLER 1
> > +===================
> > +
> > +Thermal:
> > +--------
> > +
> > +For common binding part and usage, refer to
> > +Documentation/devicetree/bindings/thermal/thermal.txt
> > +
> > +The thermal IP can probe the temperature all around the processor. It
> > +may feature several channels, each of them wired to one sensor.
> > +
> > +It is possible to setup an overheat interrupt by giving at least one
> > +critical point to any subnode of the thermal-zone node.
> > +
> > +Required properties:
> > +- compatible: "marvell,armada-ap806-thermal"
> > +
> > +Optional properties:
> > +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> > +  line 18 of the SEI irqchip.
> > +  See interrupt-controller/interrupts.txt
> > +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> > +  to this IP and represents the channel ID. There is one sensor per
> > +  channel. O refers to the thermal IP internal channel, while positive
> > +  IDs refer to each CPU.
> > +
> > +Example:
> > +ap_syscon1: system-controller@6f8000 {
> > +	compatible = "syscon", "simple-mfd";
> > +	reg = <0x6f8000 0x1000>;
> > +
> > +	ap_thermal: ap-thermal {
> > +		compatible = "marvell,armada-ap806-thermal";  
> 
> Is there a register range associated with the thermal functions?

Indeed there is a small one (three registers) but we also need to access
some registers out of this area (so called the 'DFX' area, in this
syscon, to route correctly the interrupt) and I fear we'll need to
access others in the future. I choose to declare a syscon because this
area mixes a lot of misc registers.

So do you think I should declare these 3 registers area in a reg
property? Or keep the way I retrieved the offsets in the syscon:
defining offsets in the code?

> 
> > +		interrupt-parent = <&sei>;
> > +		interrupts = <18>;
> > +		#thermal-sensor-cells = <1>;
> > +	};
> > +};
> > -- 
> > 2.14.1
> >   

Thanks,
Miquèl

-- 
Miquel Raynal, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file
@ 2018-05-18  9:56       ` Miquel Raynal
  0 siblings, 0 replies; 76+ messages in thread
From: Miquel Raynal @ 2018-05-18  9:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

Thanks for reviewing, one question below.

On Fri, 27 Apr 2018 16:07:22 -0500, Rob Herring <robh@kernel.org> wrote:

> On Sat, Apr 21, 2018 at 05:12:45PM +0200, Miquel Raynal wrote:
> > Explain the thermal bindings now that the thermal IP is described being
> > inside of a system controller. Add a reference to the thermal-zone node.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> >  .../arm/marvell/ap806-system-controller.txt        | 43 ++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > index a856eb9a4e05..c95f3ac5c728 100644
> > --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
> > @@ -11,6 +11,9 @@ For the top level node:
> >   - compatible: must be: "syscon", "simple-mfd";
> >   - reg: register area of the AP806 system controller
> >  
> > +SYSTEM CONTROLLER 0
> > +===================
> > +
> >  Clocks:
> >  -------
> >  
> > @@ -98,3 +101,43 @@ ap_syscon: system-controller at 6f4000 {
> >  		gpio-ranges = <&ap_pinctrl 0 0 19>;
> >  	};
> >  };
> > +
> > +SYSTEM CONTROLLER 1
> > +===================
> > +
> > +Thermal:
> > +--------
> > +
> > +For common binding part and usage, refer to
> > +Documentation/devicetree/bindings/thermal/thermal.txt
> > +
> > +The thermal IP can probe the temperature all around the processor. It
> > +may feature several channels, each of them wired to one sensor.
> > +
> > +It is possible to setup an overheat interrupt by giving at least one
> > +critical point to any subnode of the thermal-zone node.
> > +
> > +Required properties:
> > +- compatible: "marvell,armada-ap806-thermal"
> > +
> > +Optional properties:
> > +- interrupt-parent/interrupts: overheat interrupt handle. Should point to
> > +  line 18 of the SEI irqchip.
> > +  See interrupt-controller/interrupts.txt
> > +- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
> > +  to this IP and represents the channel ID. There is one sensor per
> > +  channel. O refers to the thermal IP internal channel, while positive
> > +  IDs refer to each CPU.
> > +
> > +Example:
> > +ap_syscon1: system-controller at 6f8000 {
> > +	compatible = "syscon", "simple-mfd";
> > +	reg = <0x6f8000 0x1000>;
> > +
> > +	ap_thermal: ap-thermal {
> > +		compatible = "marvell,armada-ap806-thermal";  
> 
> Is there a register range associated with the thermal functions?

Indeed there is a small one (three registers) but we also need to access
some registers out of this area (so called the 'DFX' area, in this
syscon, to route correctly the interrupt) and I fear we'll need to
access others in the future. I choose to declare a syscon because this
area mixes a lot of misc registers.

So do you think I should declare these 3 registers area in a reg
property? Or keep the way I retrieved the offsets in the syscon:
defining offsets in the code?

> 
> > +		interrupt-parent = <&sei>;
> > +		interrupts = <18>;
> > +		#thermal-sensor-cells = <1>;
> > +	};
> > +};
> > -- 
> > 2.14.1
> >   

Thanks,
Miqu?l

-- 
Miquel Raynal, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
  2018-05-18  9:49     ` Miquel Raynal
@ 2018-05-21 13:01       ` Zhang Rui
  -1 siblings, 0 replies; 76+ messages in thread
From: Zhang Rui @ 2018-05-21 13:01 UTC (permalink / raw)
  To: Miquel Raynal, Gregory CLEMENT
  Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Nadav Haklai,
	devicetree, Antoine Tenart, Catalin Marinas, linux-pm,
	Will Deacon, Maxime Chevallier, Eduardo Valentin,
	David Sniatkiwicz, Rob Herring, Thomas Petazzoni,
	linux-arm-kernel, Sebastian Hesselbarth

On 五, 2018-05-18 at 11:49 +0200, Miquel Raynal wrote:
> Hi Zhang, Eduardo & Gregory,
> 
> On Wed, 16 May 2018 19:28:45 +0200, Gregory CLEMENT
> <gregory.clement@bootlin.com> wrote:
> 
> > 
> > Hi Miquel,
> >  
> >  On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com>
> > wrote:
> > 
> > > 
> > > The only capability of the Armada thermal driver is currently
> > > just to
> > > read one sensor (the default one) per AP and one per CP.
> > > 
> > > Actually, there is one sensor per core in the AP806 plus one
> > > sensor in
> > > the thermal IP itself. The CP110 just features one thermal sensor
> > > in its
> > > own thermal IP.
> > > 
> > > Also, there is no need for the thermal core to poll the
> > > temperature of
> > > each sensor by software as this IP (at least for AP806 and CP110
> > > compatibles) features an hardware overheat interrupt.
> > > 
> > > This series first improves the readability of this driver, then
> > > adds
> > > support for multi-channel thermal IPs, and finally adds support
> > > for the
> > > hardware overheat interrupt. The bindings and the device-trees
> > > are
> > > updated accordingly.
> > > 
> > > Please note that the thermal IP raises SEI interrupts, from which
> > > the
> > > support as just been contributed and not merged yet. Applying the
> > > last
> > > DT patches referring to the 'sei' and 'icu_sei' nodes will
> > > require this
> > > feature [1] to have been accepted first.
> > > 
> > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-Ap
> > > ril/572852.html
> > > 
> > > Thank you,
> > > Miquèl
> > > 
> > > 
> > > Miquel Raynal (27):
> > >   thermal: armada: add a function that sanitizes the thermal zone
> > > name
> > >   thermal: armada: remove useless register accesses
> > >   thermal: armada: remove misleading comments
> > >   thermal: armada: rename the initialization routine
> > >   thermal: armada: dissociate a380 and cp110 ->init() hooks
> > >   thermal: armada: average over samples to avoid glitches
> > >   thermal: armada: convert driver to syscon register accesses
> > >   thermal: armada: use the resource managed registration helper
> > >     alternative
> > >   thermal: armada: add multi-channel sensors support
> > >   thermal: armada: remove sensors validity from the IP
> > > initialization
> > >   thermal: armada: move validity check out of the read function
> > >   thermal: armada: get rid of the ->is_valid() pointer
> > >   thermal: armada: add overheat interrupt support
> > >   dt-bindings: cp110: rename cp110 syscon file
> > >   dt-bindings: ap806: prepare the syscon file to list other
> > > syscons
> > >     nodes
> > >   dt-bindings: cp110: prepare the syscon file to list other
> > > syscons
> > >     nodes
> > >   dt-bindings: ap806: add the thermal node in the syscon file
> > >   dt-bindings: cp110: update documentation since DT de-
> > > duplication
> > >   dt-bindings: cp110: add the thermal node in the syscon file
> > >   dt-bindings: thermal: armada: add reference to new bindings
> > >   arm64: dts: marvell: rename ap806 syscon node
> > >   arm64: dts: marvell: move AP806/CP110 thermal nodes into a new
> > > syscon
> > >   arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
> > >   arm64: dts: marvell: add macro to make distinction between node
> > > names
> > >   arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
> > >   arm64: dts: marvell: add interrupt support to ap806 thermal
> > > node
> > >   arm64: dts: marvell: add interrupt support to cp110 thermal
> > > node
> > > 
> > >  .../arm/marvell/ap806-system-controller.txt        |  55 +-
> > >  ...controller0.txt => cp110-system-controller.txt} |  66 +-
> > >  .../devicetree/bindings/thermal/armada-thermal.txt |   5 +
> > >  arch/arm64/boot/dts/marvell/armada-ap806.dtsi      |  85 +-
> > >  arch/arm64/boot/dts/marvell/armada-common.dtsi     |   1 +
> > >  arch/arm64/boot/dts/marvell/armada-cp110.dtsi      |  45 +-
> > >  drivers/thermal/armada_thermal.c                   | 875
> > > ++++++++++++++++++---
> > >  7 files changed, 976 insertions(+), 156 deletions(-)
> > >  rename Documentation/devicetree/bindings/arm/marvell/{cp110-
> > > system-controller0.txt => cp110-system-controller.txt} (83%)  
> > What is the status of this series?
> > I am especially interested in the dt part.
> > Do you expect sending a new series modifying them?
> I have not received any feedback yet on the thermal part, bindings
> have
> been partially acked by Rob (one request, I will probably add a reg
> property in the AP node) so please do not take the DTS changes of
> this iteration.
> 
> Zhang, Eduardo, could you please share the status of this series?
> 
hmmm, this should go through Eduardo' thermal-soc tree, thus I'd expect
Eduardo to review this patch set.

Eduardo, what's your comments for this series?

thanks,
rui

> Thanks,
> Miquèl
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver
@ 2018-05-21 13:01       ` Zhang Rui
  0 siblings, 0 replies; 76+ messages in thread
From: Zhang Rui @ 2018-05-21 13:01 UTC (permalink / raw)
  To: linux-arm-kernel

On ?, 2018-05-18 at 11:49 +0200, Miquel Raynal wrote:
> Hi Zhang, Eduardo & Gregory,
> 
> On Wed, 16 May 2018 19:28:45 +0200, Gregory CLEMENT
> <gregory.clement@bootlin.com> wrote:
> 
> > 
> > Hi Miquel,
> > ?
> > ?On sam., avril 21 2018, Miquel Raynal <miquel.raynal@bootlin.com>
> > wrote:
> > 
> > > 
> > > The only capability of the Armada thermal driver is currently
> > > just to
> > > read one sensor (the default one) per AP and one per CP.
> > > 
> > > Actually, there is one sensor per core in the AP806 plus one
> > > sensor in
> > > the thermal IP itself. The CP110 just features one thermal sensor
> > > in its
> > > own thermal IP.
> > > 
> > > Also, there is no need for the thermal core to poll the
> > > temperature of
> > > each sensor by software as this IP (at least for AP806 and CP110
> > > compatibles) features an hardware overheat interrupt.
> > > 
> > > This series first improves the readability of this driver, then
> > > adds
> > > support for multi-channel thermal IPs, and finally adds support
> > > for the
> > > hardware overheat interrupt. The bindings and the device-trees
> > > are
> > > updated accordingly.
> > > 
> > > Please note that the thermal IP raises SEI interrupts, from which
> > > the
> > > support as just been contributed and not merged yet. Applying the
> > > last
> > > DT patches referring to the 'sei' and 'icu_sei' nodes will
> > > require this
> > > feature [1] to have been accepted first.
> > > 
> > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-Ap
> > > ril/572852.html
> > > 
> > > Thank you,
> > > Miqu?l
> > > 
> > > 
> > > Miquel Raynal (27):
> > > ? thermal: armada: add a function that sanitizes the thermal zone
> > > name
> > > ? thermal: armada: remove useless register accesses
> > > ? thermal: armada: remove misleading comments
> > > ? thermal: armada: rename the initialization routine
> > > ? thermal: armada: dissociate a380 and cp110 ->init() hooks
> > > ? thermal: armada: average over samples to avoid glitches
> > > ? thermal: armada: convert driver to syscon register accesses
> > > ? thermal: armada: use the resource managed registration helper
> > > ????alternative
> > > ? thermal: armada: add multi-channel sensors support
> > > ? thermal: armada: remove sensors validity from the IP
> > > initialization
> > > ? thermal: armada: move validity check out of the read function
> > > ? thermal: armada: get rid of the ->is_valid() pointer
> > > ? thermal: armada: add overheat interrupt support
> > > ? dt-bindings: cp110: rename cp110 syscon file
> > > ? dt-bindings: ap806: prepare the syscon file to list other
> > > syscons
> > > ????nodes
> > > ? dt-bindings: cp110: prepare the syscon file to list other
> > > syscons
> > > ????nodes
> > > ? dt-bindings: ap806: add the thermal node in the syscon file
> > > ? dt-bindings: cp110: update documentation since DT de-
> > > duplication
> > > ? dt-bindings: cp110: add the thermal node in the syscon file
> > > ? dt-bindings: thermal: armada: add reference to new bindings
> > > ? arm64: dts: marvell: rename ap806 syscon node
> > > ? arm64: dts: marvell: move AP806/CP110 thermal nodes into a new
> > > syscon
> > > ? arm64: dts: marvell: add thermal-zone node in ap806 DTSI file
> > > ? arm64: dts: marvell: add macro to make distinction between node
> > > names
> > > ? arm64: dts: marvell: add thermal-zone node in cp110 DTSI file
> > > ? arm64: dts: marvell: add interrupt support to ap806 thermal
> > > node
> > > ? arm64: dts: marvell: add interrupt support to cp110 thermal
> > > node
> > > 
> > > ?.../arm/marvell/ap806-system-controller.txt????????|??55 +-
> > > ?...controller0.txt => cp110-system-controller.txt} |??66 +-
> > > ?.../devicetree/bindings/thermal/armada-thermal.txt |???5 +
> > > ?arch/arm64/boot/dts/marvell/armada-ap806.dtsi??????|??85 +-
> > > ?arch/arm64/boot/dts/marvell/armada-common.dtsi?????|???1 +
> > > ?arch/arm64/boot/dts/marvell/armada-cp110.dtsi??????|??45 +-
> > > ?drivers/thermal/armada_thermal.c???????????????????| 875
> > > ++++++++++++++++++---
> > > ?7 files changed, 976 insertions(+), 156 deletions(-)
> > > ?rename Documentation/devicetree/bindings/arm/marvell/{cp110-
> > > system-controller0.txt => cp110-system-controller.txt} (83%)??
> > What is the status of this series?
> > I am especially interested in the dt part.
> > Do you expect sending a new series modifying them?
> I have not received any feedback yet on the thermal part, bindings
> have
> been partially acked by Rob (one request, I will probably add a reg
> property in the AP node) so please do not take the DTS changes of
> this iteration.
> 
> Zhang, Eduardo, could you please share the status of this series?
> 
hmmm, this should go through Eduardo' thermal-soc tree, thus I'd expect
Eduardo to review this patch set.

Eduardo, what's your comments for this series?

thanks,
rui

> Thanks,
> Miqu?l
> 

^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2018-05-21 13:01 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-21 15:12 [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver Miquel Raynal
2018-04-21 15:12 ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 01/27] thermal: armada: add a function that sanitizes the thermal zone name Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 02/27] thermal: armada: remove useless register accesses Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 03/27] thermal: armada: remove misleading comments Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 04/27] thermal: armada: rename the initialization routine Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 05/27] thermal: armada: dissociate a380 and cp110 ->init() hooks Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 06/27] thermal: armada: average over samples to avoid glitches Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 07/27] thermal: armada: convert driver to syscon register accesses Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 08/27] thermal: armada: use the resource managed registration helper alternative Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 09/27] thermal: armada: add multi-channel sensors support Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 10/27] thermal: armada: remove sensors validity from the IP initialization Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 11/27] thermal: armada: move validity check out of the read function Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 12/27] thermal: armada: get rid of the ->is_valid() pointer Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 13/27] thermal: armada: add overheat interrupt support Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 14/27] dt-bindings: cp110: rename cp110 syscon file Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-27 20:51   ` Rob Herring
2018-04-27 20:51     ` Rob Herring
2018-04-21 15:12 ` [PATCH 15/27] dt-bindings: ap806: prepare the syscon file to list other syscons nodes Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 16/27] dt-bindings: cp110: " Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-27 21:06   ` Rob Herring
2018-04-27 21:06     ` Rob Herring
2018-04-28 11:20     ` Miquel Raynal
2018-04-28 11:20       ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 17/27] dt-bindings: ap806: add the thermal node in the syscon file Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-27 21:07   ` Rob Herring
2018-04-27 21:07     ` Rob Herring
2018-04-28 11:07     ` Miquel Raynal
2018-04-28 11:07       ` Miquel Raynal
2018-05-18  9:56     ` Miquel Raynal
2018-05-18  9:56       ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 18/27] dt-bindings: cp110: update documentation since DT de-duplication Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-27 21:08   ` Rob Herring
2018-04-27 21:08     ` Rob Herring
2018-04-21 15:12 ` [PATCH 19/27] dt-bindings: cp110: add the thermal node in the syscon file Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 20/27] dt-bindings: thermal: armada: add reference to new bindings Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 21/27] arm64: dts: marvell: rename ap806 syscon node Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 22/27] arm64: dts: marvell: move AP806/CP110 thermal nodes into a new syscon Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 23/27] arm64: dts: marvell: add thermal-zone node in ap806 DTSI file Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 24/27] arm64: dts: marvell: add macro to make distinction between node names Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 25/27] arm64: dts: marvell: add thermal-zone node in cp110 DTSI file Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 26/27] arm64: dts: marvell: add interrupt support to ap806 thermal node Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-04-21 15:12 ` [PATCH 27/27] arm64: dts: marvell: add interrupt support to cp110 " Miquel Raynal
2018-04-21 15:12   ` Miquel Raynal
2018-05-16 17:28 ` [PATCH 00/27] Add multi-channel and overheat IRQ support to Armada thermal driver Gregory CLEMENT
2018-05-16 17:28   ` Gregory CLEMENT
2018-05-18  9:49   ` Miquel Raynal
2018-05-18  9:49     ` Miquel Raynal
2018-05-21 13:01     ` Zhang Rui
2018-05-21 13:01       ` Zhang Rui

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.