Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/1] remove the "cpu_clk" from the GXBB/GXL/GXM driver
From: Martin Blumenstingl @ 2017-04-01 12:55 UTC (permalink / raw)
  To: linux-amlogic, jbrunet, narmstrong, linux-clk
  Cc: devicetree, khilman, carlo, sboyd, mturquette, linux-arm-kernel,
	Martin Blumenstingl

This is the updated version of my RFC patch from [0].

The quick summary for this patch is that the "cpu_clk" seems to have
been copied from the Meson8b clock driver when the GXBB clock driver
was initially added. However, on GXBB (and the other GX SoCs) the
actual CPU clock is provided by a SCPI DVFS clock.
More details can be found in the patch description itself.

This was tested on a Khadas VIM board (GXL S905X).


Changes since the RFC version:
- rebased to the "clk-meson" branch (e65ae3fb97b4 "dt-bindings: clock:
  gxbb-clkc: Add GXL compatible variant") and Jerome's audio clock
  patches (in version 2: [1])
- remove the now unused cpu_div_table (which was left over in the RFC
  version)
- slightly updated the comment for the now unused clock ID 1 in
  drivers/clk/meson/gxbb.h


[0] https://patchwork.kernel.org/patch/9644993/
[1] http://lists.infradead.org/pipermail/linux-amlogic/2017-March/003200.html

Martin Blumenstingl (1):
  clk: meson: gxbb: remove the "cpu_clk" from the GXBB and GXL driver

 drivers/clk/meson/gxbb.c              | 64 ++---------------------------------
 drivers/clk/meson/gxbb.h              |  2 +-
 include/dt-bindings/clock/gxbb-clkc.h |  1 -
 3 files changed, 4 insertions(+), 63 deletions(-)

-- 
2.12.1


^ permalink raw reply

* [PATCH 1/1] clk: meson: gxbb: remove the "cpu_clk" from the GXBB and GXL driver
From: Martin Blumenstingl @ 2017-04-01 12:55 UTC (permalink / raw)
  To: linux-amlogic, jbrunet, narmstrong, linux-clk
  Cc: devicetree, khilman, carlo, sboyd, mturquette, linux-arm-kernel,
	Martin Blumenstingl
In-Reply-To: <20170401125519.7339-1-martin.blumenstingl@googlemail.com>

It seems that the "cpu_clk" was carried over from the meson8b clock
controller driver. On Meson GX (GXBB/GXL/GXM) the registers which are
used by the cpu_clk have a different purpose (in other words: they don't
control the CPU clock anymore). HHI_SYS_CPU_CLK_CNTL1 bits 31:24 are
reserved according to the public S905 datasheet, while bit 23 is the
"A53_trace_clk_DIS" gate (which according to the datasheet should only
be used in case a silicon bug is discovered) and bits 22:20 are a
divider (A53_trace_clk). The meson clk-cpu code however expects that
bits 28:20 are reserved for a divider (according to the public S805
datasheet this "SCALE_DIV: This value represents an N+1 divider of the
input clock.").

The CPU clock on Meson GX SoCs is provided by the SCPI DVFS clock
driver instead. Two examples from a Meson GXL S905X SoC:
- vcpu (SCPI DVFS clock 0) rate: 1000000000 / cpu_clk rate: 708000000
- vcpu (SCPI DVFS clock 0) rate: 1512000000 / cpu_clk rate: 708000000

Unfortunately the CLKID_CPUCLK was already exported (but is currently
not used) to DT. Due to the removal of this clock definition there is
now a hole in the clk_hw_onecell_data (which is not a problem because
this case is already handled in gxbb_clkc_probe).

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 drivers/clk/meson/gxbb.c              | 64 ++---------------------------------
 drivers/clk/meson/gxbb.h              |  2 +-
 include/dt-bindings/clock/gxbb-clkc.h |  1 -
 3 files changed, 4 insertions(+), 63 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index ad5f027af1a2..7cf88ca9bdce 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -278,20 +278,6 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
 	{ /* sentinel */ },
 };
 
-static const struct clk_div_table cpu_div_table[] = {
-	{ .val = 1, .div = 1 },
-	{ .val = 2, .div = 2 },
-	{ .val = 3, .div = 3 },
-	{ .val = 2, .div = 4 },
-	{ .val = 3, .div = 6 },
-	{ .val = 4, .div = 8 },
-	{ .val = 5, .div = 10 },
-	{ .val = 6, .div = 12 },
-	{ .val = 7, .div = 14 },
-	{ .val = 8, .div = 16 },
-	{ /* sentinel */ },
-};
-
 static struct meson_clk_pll gxbb_fixed_pll = {
 	.m = {
 		.reg_off = HHI_MPLL_CNTL,
@@ -612,21 +598,10 @@ static struct meson_clk_mpll gxbb_mpll2 = {
 };
 
 /*
- * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
- * post-dividers and should be modeled with their respective PLLs via the
- * forthcoming coordinated clock rates feature
+ * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers
+ * and should be modeled with their respective PLLs via the forthcoming
+ * coordinated clock rates feature
  */
-static struct meson_clk_cpu gxbb_cpu_clk = {
-	.reg_off = HHI_SYS_CPU_CLK_CNTL1,
-	.div_table = cpu_div_table,
-	.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
-	.hw.init = &(struct clk_init_data){
-		.name = "cpu_clk",
-		.ops = &meson_clk_cpu_ops,
-		.parent_names = (const char *[]){ "sys_pll" },
-		.num_parents = 1,
-	},
-};
 
 static u32 mux_table_clk81[]	= { 6, 5, 7 };
 
@@ -1045,7 +1020,6 @@ static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4);
 static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
 	.hws = {
 		[CLKID_SYS_PLL]		    = &gxbb_sys_pll.hw,
-		[CLKID_CPUCLK]		    = &gxbb_cpu_clk.hw,
 		[CLKID_HDMI_PLL]	    = &gxbb_hdmi_pll.hw,
 		[CLKID_FIXED_PLL]	    = &gxbb_fixed_pll.hw,
 		[CLKID_FCLK_DIV2]	    = &gxbb_fclk_div2.hw,
@@ -1165,7 +1139,6 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
 static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 	.hws = {
 		[CLKID_SYS_PLL]		    = &gxbb_sys_pll.hw,
-		[CLKID_CPUCLK]		    = &gxbb_cpu_clk.hw,
 		[CLKID_HDMI_PLL]	    = &gxbb_hdmi_pll.hw,
 		[CLKID_FIXED_PLL]	    = &gxbb_fixed_pll.hw,
 		[CLKID_FCLK_DIV2]	    = &gxbb_fclk_div2.hw,
@@ -1430,7 +1403,6 @@ struct clkc_data {
 	unsigned int clk_dividers_count;
 	struct meson_clk_audio_divider *const *clk_audio_dividers;
 	unsigned int clk_audio_dividers_count;
-	struct meson_clk_cpu *cpu_clk;
 	struct clk_hw_onecell_data *hw_onecell_data;
 };
 
@@ -1447,7 +1419,6 @@ static const struct clkc_data gxbb_clkc_data = {
 	.clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
 	.clk_audio_dividers = gxbb_audio_dividers,
 	.clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
-	.cpu_clk = &gxbb_cpu_clk,
 	.hw_onecell_data = &gxbb_hw_onecell_data,
 };
 
@@ -1464,7 +1435,6 @@ static const struct clkc_data gxl_clkc_data = {
 	.clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
 	.clk_audio_dividers = gxbb_audio_dividers,
 	.clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
-	.cpu_clk = &gxbb_cpu_clk,
 	.hw_onecell_data = &gxl_hw_onecell_data,
 };
 
@@ -1479,8 +1449,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
 	const struct clkc_data *clkc_data;
 	void __iomem *clk_base;
 	int ret, clkid, i;
-	struct clk_hw *parent_hw;
-	struct clk *parent_clk;
 	struct device *dev = &pdev->dev;
 
 	clkc_data = of_device_get_match_data(&pdev->dev);
@@ -1502,9 +1470,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
 	for (i = 0; i < clkc_data->clk_mplls_count; i++)
 		clkc_data->clk_mplls[i]->base = clk_base;
 
-	/* Populate the base address for CPU clk */
-	clkc_data->cpu_clk->base = clk_base;
-
 	/* Populate base address for gates */
 	for (i = 0; i < clkc_data->clk_gates_count; i++)
 		clkc_data->clk_gates[i]->reg = clk_base +
@@ -1538,29 +1503,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
 			goto iounmap;
 	}
 
-	/*
-	 * Register CPU clk notifier
-	 *
-	 * FIXME this is wrong for a lot of reasons. First, the muxes should be
-	 * struct clk_hw objects. Second, we shouldn't program the muxes in
-	 * notifier handlers. The tricky programming sequence will be handled
-	 * by the forthcoming coordinated clock rates mechanism once that
-	 * feature is released.
-	 *
-	 * Furthermore, looking up the parent this way is terrible. At some
-	 * point we will stop allocating a default struct clk when registering
-	 * a new clk_hw, and this hack will no longer work. Releasing the ccr
-	 * feature before that time solves the problem :-)
-	 */
-	parent_hw = clk_hw_get_parent(&clkc_data->cpu_clk->hw);
-	parent_clk = parent_hw->clk;
-	ret = clk_notifier_register(parent_clk, &clkc_data->cpu_clk->clk_nb);
-	if (ret) {
-		pr_err("%s: failed to register clock notifier for cpu_clk\n",
-				__func__);
-		goto iounmap;
-	}
-
 	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
 			clkc_data->hw_onecell_data);
 
diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h
index 17c6aef033ff..36330c2d4433 100644
--- a/drivers/clk/meson/gxbb.h
+++ b/drivers/clk/meson/gxbb.h
@@ -171,7 +171,7 @@
  * to be exposed to client nodes in DT: include/dt-bindings/clock/gxbb-clkc.h
  */
 #define CLKID_SYS_PLL		  0
-/* CLKID_CPUCLK */
+/* ID 1 is unused (it was used by the non-existing CLKID_CPUCLK before) */
 /* CLKID_HDMI_PLL */
 #define CLKID_FIXED_PLL		  3
 /* CLKID_FCLK_DIV2 */
diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h
index 4516bc4253b5..54faf83a4851 100644
--- a/include/dt-bindings/clock/gxbb-clkc.h
+++ b/include/dt-bindings/clock/gxbb-clkc.h
@@ -5,7 +5,6 @@
 #ifndef __GXBB_CLKC_H
 #define __GXBB_CLKC_H
 
-#define CLKID_CPUCLK		1
 #define CLKID_HDMI_PLL		2
 #define CLKID_FCLK_DIV2		4
 #define CLKID_FCLK_DIV3		5
-- 
2.12.1


^ permalink raw reply related

* Re: [PATCH RFC 2/3] thermal: dove: convert to a thermal OF sensor device
From: Eduardo Valentin @ 2017-04-01 16:15 UTC (permalink / raw)
  To: Russell King
  Cc: Jason Cooper, Andrew Lunn, Sebastian Hesselbarth, Gregory Clement,
	Rob Herring, Mark Rutland, Zhang Rui, linux-arm-kernel,
	devicetree, linux-pm
In-Reply-To: <E1cn8qH-0002v6-SE@rmk-PC.armlinux.org.uk>

Russell,

On Sun, Mar 12, 2017 at 07:07:45PM +0000, Russell King wrote:
> Convert the dove thermal infrastructure to an OF sensor device, and add
> the thermal zones for the SoC, with a critical trip point of 120°C.
> This allows us to specify thermal zones and couple them to cooling
> devices in DT.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  arch/arm/boot/dts/dove.dtsi    | 17 +++++++++++++++++
>  drivers/thermal/dove_thermal.c | 33 +++++++++++++++++++++++++--------

I have no opposition to these changes. The only request, to avoid
conflicts, is to split the patch into driver and DTS changes. We have
been pushing these separately. DTS changes go via the arch tree. Drivers
changes goes via Rui/me.

You can add my:
Acked-by: Eduardo Valentin <edubezval@gmail.com>

On the DTSI patch.

^ permalink raw reply

* Re: [PATCH V12 0/4] thermal: bcm2835: add thermal driver for bcm2835 SoC
From: Eduardo Valentin @ 2017-04-01 16:33 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Zhang Rui, kernel, Eric Anholt, Rob Herring, Frank Rowand,
	Florian Fainelli, Rafał Miłecki, linux-rpi-kernel,
	devicetree, linux-pm
In-Reply-To: <1490990586-30898-1-git-send-email-stefan.wahren@i2se.com>

Hello Stefan,

On Fri, Mar 31, 2017 at 08:03:02PM +0000, Stefan Wahren wrote:
> This is an attempt to finish Martin's great work on the bcm2835
> thermal driver. It includes now all Eduardo's suggestions and the
> explanations from the Raspberry Pi forum [1].
> 
> ChangeLog:
> V1 -> V2: added specific settings depending on compatiblity
> added trip point based on register
> setting up ctrl-register if HW is not enabled by firmware
> as per recommendation of Eric (untested)
> check that clock frequency is in range
> (1.9 - 5MHz - as per comment in clk-bcm2835.c)
> V2 -> V4: moved back to thermal (not using bcm sub-directory)
> set polling interval to 1second (was 0ms, so interrupt driven)
> V5 -> V6: added correct depends in KConfig
> removed defined default for RESET_DELAY
> removed obvious comments
> clarify HW setup comments if not set up by FW already
> move clk_prepare_enable to an earlier stage and add error handling
> clarify warning when TS-clock runs out of recommended range
> clk_disable_unprepare added in bcm2835_thermal_remove
> added comment on recommended temperature ranges for SOC
> V6 -> V7: removed depends on ARCH_BCM2836 || ARCH_BCM2837 in Kconfig
> V7 -> V8: rebased
> V8 -> V9: moved to use the thermal framework offset and slope in
> thermal_zone_parameters as per request
> V9 -> V10: implement support for thermal zone descriptor, define offset and
> slope within DT, apply forum explanations, replace symbolic with octal
> permissions
> V10 -> V11: fix parse issue in bcm2837.dtsi, fix probing and remove unused tzp
> V11 -> V12: split of-thermal changes from this series since they aren't
> necessary, avoid double definition of matching table
> 
> [1] - https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=160289&p=1040448
> 
> Stefan Wahren (4):
>   dt-bindings: Add thermal zone to bcm2835-thermal example
>   ARM: dts: bcm283x: Add CPU thermal zone with 1 trip point
>   ARM64: dts: bcm2837: Define CPU thermal coefficients
>   thermal: bcm2835: add thermal driver for bcm2835 SoC

Thanks for the patience and for cleaning the driver. I added patches 1
and 4 into my -linus branch for the next merge window. DTS(i) changes
should go via your arch tree.

BR,

^ permalink raw reply

* Re: [PATCH V12 2/4] ARM: dts: bcm283x: Add CPU thermal zone with 1 trip point
From: Eduardo Valentin @ 2017-04-01 16:37 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Zhang Rui, kernel, Eric Anholt, Rob Herring, Frank Rowand,
	Florian Fainelli, Rafał Miłecki, linux-rpi-kernel,
	devicetree, linux-pm
In-Reply-To: <1490990586-30898-3-git-send-email-stefan.wahren@i2se.com>

On Fri, Mar 31, 2017 at 08:03:04PM +0000, Stefan Wahren wrote:
> As suggested by Eduardo Valentin this adds the thermal zone for
> the bcm2835 SoC with its single thermal sensor. We start with
> the criticial trip point and leave the cooling devices empty
> since we don't have any at the moment. Since the coefficients
> could vary depending on the SoC we need to define them separate.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>

Acked-by: Eduardo Valentin <edubezval@gmail.com>

^ permalink raw reply

* Re: [PATCH V12 3/4] ARM64: dts: bcm2837: Define CPU thermal coefficients
From: Eduardo Valentin @ 2017-04-01 16:37 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Zhang Rui, kernel, Eric Anholt, Rob Herring, Frank Rowand,
	Florian Fainelli, Rafał Miłecki, linux-rpi-kernel,
	devicetree, linux-pm
In-Reply-To: <1490990586-30898-4-git-send-email-stefan.wahren@i2se.com>

On Fri, Mar 31, 2017 at 08:03:05PM +0000, Stefan Wahren wrote:
> This defines the bcm2837 SoC specific thermal coefficients in
> order to initialize the thermal driver correctly.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>

Acked-by: Eduardo Valentin <edubezval@gmail.com>

^ permalink raw reply

* Re: [PATCH V4 1/2] dt-bindings: thermal: add support for Broadcom's Northstar thermal
From: Eduardo Valentin @ 2017-04-01 19:51 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Zhang Rui, Rob Herring, Mark Rutland, Stephen Warren, Lee Jones,
	Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list, linux-pm, devicetree, linux-rpi-kernel,
	linux-arm-kernel, Rafał Miłecki
In-Reply-To: <20170331201124.656-1-zajec5@gmail.com>

Rafal,

On Fri, Mar 31, 2017 at 10:11:23PM +0200, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This commit documents binding for thermal used in Northstar family SoCs.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
> V3: Add thermal-zones to the example
>     Rob: Because of this update, I didn't include Acked-by I got for V2
> ---
>  .../devicetree/bindings/thermal/brcm,ns-thermal    | 26 ++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> 
> diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> new file mode 100644
> index 000000000000..c561c7349f17
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> @@ -0,0 +1,26 @@
> +* Broadcom Northstar Thermal
> +
> +This binding describes thermal sensor that is part of Northstar's DMU (Device
> +Management Unit).
> +
> +Required properties:
> +- compatible : Must be "brcm,ns-thermal"
> +- reg : iomem address range of PVTMON registers
> +- #thermal-sensor-cells : Should be <0>
> +
> +Example:
> +
> +thermal: thermal@1800c2c0 {
> +	compatible = "brcm,ns-thermal";
> +	reg = <0x1800c2c0 0x10>;
> +	#thermal-sensor-cells = <0>;
> +};
> +
> +thermal-zones {
> +	cpu_thermal: cpu-thermal {
> +		polling-delay-passive = <0>;
> +		polling-delay = <1000>;
> +		coefficients = <(-556) 418000>;
> +		thermal-sensors = <&thermal>;

You need to define trips and cooling devices here. Otherwise, makes
little sense to have this device in thermal subsystem. Here is an
example of minimal set:
https://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git/commit/?h=linus&id=1e2ac9821de6a85d3e8358f238436708d1d46869

The above has no passive action. It is just gonna shutdown the system if
temperature crosses a threshold. 

But, a typical cooling device would be CPU frequency throttling. Do you have
that up and running in your routers?

> +	};
> +};
> -- 
> 2.11.0
> 

^ permalink raw reply

* Re: [PATCH V4 2/2] thermal: broadcom: add Northstar thermal driver
From: Eduardo Valentin @ 2017-04-01 19:54 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Zhang Rui, Rob Herring, Mark Rutland, Stephen Warren, Lee Jones,
	Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list, linux-pm, devicetree, linux-rpi-kernel,
	linux-arm-kernel, Rafał Miłecki, Jon Mason
In-Reply-To: <20170331201124.656-2-zajec5@gmail.com>

On Fri, Mar 31, 2017 at 10:11:24PM +0200, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> Northstar is a SoC family commonly used in home routers. This commit
> adds a driver for checking CPU temperature. As Northstar Plus seems to
> also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> ---

This driver looks fine from what concerns the of thermal usage.
I had only one request on the DT bindings example. I believe better to
get the example fixed so bad DTs does not get copied.


> V2: Make it iProc specific as NSP can also use this driver
>     Select proper symbols in config ARCH_BCM_IPROC
>     Define PVTMON register bits
>     Update code selecting temperature monitor mode
>     Thank you Jon!
> V3: More details in help message for BCM_NS_THERMAL
>     Use slope & offset
>     Drop arch code change (I'll be submitted using a proper tree)
>     Thank you Eduardo!
> V4: Comment operations on PVTMON_CONTROL0 register
> ---
>  drivers/thermal/Kconfig               |   5 ++
>  drivers/thermal/Makefile              |   1 +
>  drivers/thermal/broadcom/Kconfig      |   8 +++
>  drivers/thermal/broadcom/Makefile     |   1 +
>  drivers/thermal/broadcom/ns-thermal.c | 105 ++++++++++++++++++++++++++++++++++

Also, I have just merged a BRCM driver. Does it make sense to move it
here too?

It does not need to be a blocking request for this driver though.

>  5 files changed, 120 insertions(+)
>  create mode 100644 drivers/thermal/broadcom/Kconfig
>  create mode 100644 drivers/thermal/broadcom/Makefile
>  create mode 100644 drivers/thermal/broadcom/ns-thermal.c
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 776b34396144..008e173ec825 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -392,6 +392,11 @@ config MTK_THERMAL
>  	  Enable this option if you want to have support for thermal management
>  	  controller present in Mediatek SoCs
>  
> +menu "Broadcom thermal drivers"
> +depends on ARCH_BCM || COMPILE_TEST
> +source "drivers/thermal/broadcom/Kconfig"
> +endmenu
> +
>  menu "Texas Instruments thermal drivers"
>  depends on ARCH_HAS_BANDGAP || COMPILE_TEST
>  depends on HAS_IOMEM
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 7adae2029355..549d81b6363c 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -27,6 +27,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL)	+= clock_cooling.o
>  thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
>  
>  # platform thermal drivers
> +obj-y				+= broadcom/
>  obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM)	+= qcom-spmi-temp-alarm.o
>  obj-$(CONFIG_SPEAR_THERMAL)	+= spear_thermal.o
>  obj-$(CONFIG_ROCKCHIP_THERMAL)	+= rockchip_thermal.o
> diff --git a/drivers/thermal/broadcom/Kconfig b/drivers/thermal/broadcom/Kconfig
> new file mode 100644
> index 000000000000..f0dea8a8e002
> --- /dev/null
> +++ b/drivers/thermal/broadcom/Kconfig
> @@ -0,0 +1,8 @@
> +config BCM_NS_THERMAL
> +	tristate "Northstar thermal driver"
> +	depends on ARCH_BCM_IPROC || COMPILE_TEST
> +	help
> +	  Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
> +	  BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
> +	  with a thermal sensor that allows checking CPU temperature. This
> +	  driver provides support for it.
> diff --git a/drivers/thermal/broadcom/Makefile b/drivers/thermal/broadcom/Makefile
> new file mode 100644
> index 000000000000..059df9a0ed69
> --- /dev/null
> +++ b/drivers/thermal/broadcom/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_BCM_NS_THERMAL)		+= ns-thermal.o
> diff --git a/drivers/thermal/broadcom/ns-thermal.c b/drivers/thermal/broadcom/ns-thermal.c
> new file mode 100644
> index 000000000000..eab96b3572b9
> --- /dev/null
> +++ b/drivers/thermal/broadcom/ns-thermal.c
> @@ -0,0 +1,105 @@
> +/*
> + * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/thermal.h>
> +
> +#define PVTMON_CONTROL0					0x00
> +#define PVTMON_CONTROL0_SEL_MASK			0x0000000e
> +#define PVTMON_CONTROL0_SEL_TEMP_MONITOR		0x00000000
> +#define PVTMON_CONTROL0_SEL_TEST_MODE			0x0000000e
> +#define PVTMON_STATUS					0x08
> +
> +struct ns_thermal {
> +	struct thermal_zone_device *tz;
> +	void __iomem *pvtmon;
> +};
> +
> +static int ns_thermal_get_temp(void *data, int *temp)
> +{
> +	struct ns_thermal *ns_thermal = data;
> +	int offset = thermal_zone_get_offset(ns_thermal->tz);
> +	int slope = thermal_zone_get_slope(ns_thermal->tz);
> +	u32 val;
> +
> +	val = readl(ns_thermal->pvtmon + PVTMON_CONTROL0);
> +	if ((val & PVTMON_CONTROL0_SEL_MASK) != PVTMON_CONTROL0_SEL_TEMP_MONITOR) {
> +		/* Clear current mode selection */
> +		val &= ~PVTMON_CONTROL0_SEL_MASK;
> +
> +		/* Set temp monitor mode (it's the default actually) */
> +		val |= PVTMON_CONTROL0_SEL_TEMP_MONITOR;
> +
> +		writel(val, ns_thermal->pvtmon + PVTMON_CONTROL0);
> +	}
> +
> +	val = readl(ns_thermal->pvtmon + PVTMON_STATUS);
> +	*temp = slope * val + offset;
> +
> +	return 0;
> +}
> +
> +const struct thermal_zone_of_device_ops ns_thermal_ops = {
> +	.get_temp = ns_thermal_get_temp,
> +};
> +
> +static int ns_thermal_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct ns_thermal *ns_thermal;
> +
> +	ns_thermal = devm_kzalloc(dev, sizeof(*ns_thermal), GFP_KERNEL);
> +	if (!ns_thermal)
> +		return -ENOMEM;
> +
> +	ns_thermal->pvtmon = of_iomap(dev_of_node(dev), 0);
> +	if (WARN_ON(!ns_thermal->pvtmon))
> +		return -ENOENT;
> +
> +	ns_thermal->tz = devm_thermal_zone_of_sensor_register(dev, 0,
> +							      ns_thermal,
> +							      &ns_thermal_ops);
> +	if (IS_ERR(ns_thermal->tz)) {
> +		iounmap(ns_thermal->pvtmon);
> +		return PTR_ERR(ns_thermal->tz);
> +	}
> +
> +	platform_set_drvdata(pdev, ns_thermal);
> +
> +	return 0;
> +}
> +
> +static int ns_thermal_remove(struct platform_device *pdev)
> +{
> +	struct ns_thermal *ns_thermal = platform_get_drvdata(pdev);
> +
> +	iounmap(ns_thermal->pvtmon);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id ns_thermal_of_match[] = {
> +	{ .compatible = "brcm,ns-thermal", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, ns_thermal_of_match);
> +
> +static struct platform_driver ns_thermal_driver = {
> +	.probe		= ns_thermal_probe,
> +	.remove		= ns_thermal_remove,
> +	.driver = {
> +		.name = "ns-thermal",
> +		.of_match_table = ns_thermal_of_match,
> +	},
> +};
> +module_platform_driver(ns_thermal_driver);
> +
> +MODULE_DESCRIPTION("Northstar thermal driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.11.0
> 

^ permalink raw reply

* Re: [PATCH V7 6/7] thermal: da9062/61: Thermal junction temperature monitoring driver
From: Eduardo Valentin @ 2017-04-01 19:59 UTC (permalink / raw)
  To: Steve Twiss
  Cc: LINUX-KERNEL, LINUX-PM, Zhang Rui, DEVICETREE, Dmitry Torokhov,
	Guenter Roeck, LINUX-INPUT, LINUX-WATCHDOG, Lee Jones,
	Liam Girdwood, Lukasz Luba, Mark Brown, Mark Rutland, Rob Herring,
	Support Opensource, Wim Van Sebroeck
In-Reply-To: <2c1ee249b6746ae3914041a4fc106c89a561f7de.1490712213.git.stwiss.opensource@diasemi.com>

Hello,

On Tue, Mar 28, 2017 at 03:43:33PM +0100, Steve Twiss wrote:
> From: Steve Twiss <stwiss.opensource@diasemi.com>
> 
> Add junction temperature monitoring supervisor device driver, compatible
> with the DA9062 and DA9061 PMICs. A MODULE_DEVICE_TABLE() macro is added.
> 
> If the PMIC's internal junction temperature rises above T_WARN (125 degC)
> an interrupt is issued. This T_WARN level is defined as the
> THERMAL_TRIP_HOT trip-wire inside the device driver.
> 
> The thermal triggering mechanism is interrupt based and happens when the
> temperature rises above a given threshold level. The component cannot
> return an exact temperature, it only has knowledge if the temperature is
> above or below a given threshold value. A status bit must be polled to
> detect when the temperature falls below that threshold level again. A
> kernel work queue is configured to repeatedly poll and detect when the
> temperature falls below this trip-wire, between 1 and 10 second intervals
> (defaulting at 3 seconds).
> 
> This scheme is provided as an example. It would be expected that any
> final implementation will also include a notify() function and any of these
> settings could be altered to match the application where appropriate.
> 
> When over-temperature is reached, the interrupt from the DA9061/2 will be
> repeatedly triggered. The IRQ is therefore disabled when the first
> over-temperature event happens and the status bit is polled using a
> work-queue until it becomes false.
> 
> This strategy is designed to allow the periodic transmission of uevents
> (HOT trip point) as the first level of temperature supervision method. It
> is intended for non-invasive temperature control, where the necessary
> measures for cooling the system down are left to the host software. Once
> the temperature falls again, the IRQ is re-enabled so a new critical
> over-temperature event can be detected.
> 
> Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
> Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>

I have had a look on the history of this driver on its previous
versions, and I do not think I have any other point to request on it.
Obviously, I still need to state that I do not like its oddness as it is
not really benefiting much of the thermal control implemented on the
thermal subsystem.

What is the plan for this series? Am I expected to get this driver
through thermal tree ? Or is this series going into a one shot?

If option 1 is the expected, would the driver need to get its
mfd parent merged first?
> 
> ---
> This patch applies against linux-next and v4.11-rc3
> 
> v6 -> v7
>  - NO CODE CHANGE
>  - Compile tested ARCH=x86_64
> 
> v5 -> v6
>  - Patch renamed from [PATCH V5 7/8] to [PATCH V6 6/7]
>  - Rebased from v4.9 to v4.11-rc3
>  - Modify Copyright to match Dialog latest legal statement
>  - Various checkpatch warnings (from --strict) have been fixed
>  - Added COMPILE_TEST to Kconfig
> 
> v4 -> v5
>  - Rebased from v4.8 to v4.9
>  - Updates from comments by Eduardo Valentin
>  - Replace vendor defined dlg,tjunc-temp-polling-period-ms with standard
>    thermal core polling-delay-passive as part of the device tree
>    initialisation
>  - Change to the commit message content and device driver source code to
>    include an explanation of the repeated uevent strategy for monitoring
>    over-temperature
>  - Rename warning threshold name from TEMP_WARN to T_WARN to match the
>    latest datasheet naming convention
>  - Added reviewed-by Lukasz Luba to commit message
> 
> v3 -> v4
>  - Patch renamed from [PATCH V3 8/9] to [PATCH V4 7/8]
>  - Reordering of cancel_delayed_work_sync() in remove function
>  - dev_warn() message for out-of-range polling period requests
>  - Explanatory comment for expected values defined for
>    DEFAULT_POLLING_MS_PERIOD, MAX_POLLING_MS_PERIOD and
>    MIN_POLLING_MS_PERIOD
> 
> v2 -> v3
>  - Patch renamed from [PATCH V2 09/10] to [PATCH V3 8/9]
>  - Addition of MODULE_DEVICE_TABLE macro to allow modinfo additions
> 
> v1 -> v2
>  - Patch renamed from [PATCH V1 05/10] to [PATCH V2 09/10] -- these
>    changes were made to fix checkpatch warnings caused by the patch
>    set dependency order
>  - List the header files in alphabetical order
>  - Remove "GPL v2" and replace with MODULE_LICENSE("GPL") to match the
>    copyright "GNU Public License v2 or later" option in the header
>    comment for this file. See the allowed identifiers in the file
>    include/linux/module.h +170
>  - Remove notify function "da9062_thermal_notify" function.
>  - MODULE_AUTHOR() macros removes Company Name and just gives Name in
>    accordance with include/linux/module.h +200
>  - Remove the compatible "dlg,da9061-thermal" option in the of_device_id
>    struct table. This patch now assumes the use of a DA9062 fallback
>    compatible string in the DTS when using the DA9061 thermal component
>    of the DA9061 device.
>  - Re-ordered some assignments earlier in the probe() for thermal->hw,
>    thermal->polling_period, thermal->mode, thermal->dev
>  - Added further information in the patch description to explain the use
>    of the device driver's built-in work-queue.
> 
> Regards,
> Steve Twiss, Dialog Semiconductor
> 
> 
>  drivers/thermal/Kconfig          |  10 ++
>  drivers/thermal/Makefile         |   1 +
>  drivers/thermal/da9062-thermal.c | 315 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 326 insertions(+)
>  create mode 100644 drivers/thermal/da9062-thermal.c
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 776b3439..a784b02 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -303,6 +303,16 @@ config DB8500_CPUFREQ_COOLING
>  	  bound cpufreq cooling device turns active to set CPU frequency low to
>  	  cool down the CPU.
>  
> +config DA9062_THERMAL
> +	tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
> +	depends on MFD_DA9062 || COMPILE_TEST
> +	depends on OF
> +	help
> +	  Enable this for the Dialog Semiconductor thermal sensor driver.
> +	  This will report PMIC junction over-temperature for one thermal trip
> +	  zone.
> +	  Compatible with the DA9062 and DA9061 PMICs.
> +
>  config INTEL_POWERCLAMP
>  	tristate "Intel PowerClamp idle injection driver"
>  	depends on THERMAL
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 7adae20..297849e 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -42,6 +42,7 @@ obj-$(CONFIG_IMX_THERMAL)	+= imx_thermal.o
>  obj-$(CONFIG_MAX77620_THERMAL)	+= max77620_thermal.o
>  obj-$(CONFIG_QORIQ_THERMAL)	+= qoriq_thermal.o
>  obj-$(CONFIG_DB8500_CPUFREQ_COOLING)	+= db8500_cpufreq_cooling.o
> +obj-$(CONFIG_DA9062_THERMAL)	+= da9062-thermal.o
>  obj-$(CONFIG_INTEL_POWERCLAMP)	+= intel_powerclamp.o
>  obj-$(CONFIG_X86_PKG_TEMP_THERMAL)	+= x86_pkg_temp_thermal.o
>  obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE)	+= intel_soc_dts_iosf.o
> diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c
> new file mode 100644
> index 0000000..dd8dd94
> --- /dev/null
> +++ b/drivers/thermal/da9062-thermal.c
> @@ -0,0 +1,315 @@
> +/*
> + * Thermal device driver for DA9062 and DA9061
> + * Copyright (C) 2017  Dialog Semiconductor
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +/* When over-temperature is reached, an interrupt from the device will be
> + * triggered. Following this event the interrupt will be disabled and
> + * periodic transmission of uevents (HOT trip point) should define the
> + * first level of temperature supervision. It is expected that any final
> + * implementation of the thermal driver will include a .notify() function
> + * to implement these uevents to userspace.
> + *
> + * These uevents are intended to indicate non-invasive temperature control
> + * of the system, where the necessary measures for cooling are the
> + * responsibility of the host software. Once the temperature falls again,
> + * the IRQ is re-enabled so the start of a new over-temperature event can
> + * be detected without constant software monitoring.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/thermal.h>
> +#include <linux/workqueue.h>
> +
> +#include <linux/mfd/da9062/core.h>
> +#include <linux/mfd/da9062/registers.h>
> +
> +/* Minimum, maximum and default polling millisecond periods are provided
> + * here as an example. It is expected that any final implementation to also
> + * include a modification of these settings to match the required
> + * application.
> + */
> +#define DA9062_DEFAULT_POLLING_MS_PERIOD	3000
> +#define DA9062_MAX_POLLING_MS_PERIOD		10000
> +#define DA9062_MIN_POLLING_MS_PERIOD		1000
> +
> +#define DA9062_MILLI_CELSIUS(t)			((t) * 1000)
> +
> +struct da9062_thermal_config {
> +	const char *name;
> +};
> +
> +struct da9062_thermal {
> +	struct da9062 *hw;
> +	struct delayed_work work;
> +	struct thermal_zone_device *zone;
> +	enum thermal_device_mode mode;
> +	struct mutex lock; /* protection for da9062_thermal temperature */
> +	int temperature;
> +	int irq;
> +	const struct da9062_thermal_config *config;
> +	struct device *dev;
> +};
> +
> +static void da9062_thermal_poll_on(struct work_struct *work)
> +{
> +	struct da9062_thermal *thermal = container_of(work,
> +						struct da9062_thermal,
> +						work.work);
> +	unsigned long delay;
> +	unsigned int val;
> +	int ret;
> +
> +	/* clear E_TEMP */
> +	ret = regmap_write(thermal->hw->regmap,
> +			   DA9062AA_EVENT_B,
> +			   DA9062AA_E_TEMP_MASK);
> +	if (ret < 0) {
> +		dev_err(thermal->dev,
> +			"Cannot clear the TJUNC temperature status\n");
> +		goto err_enable_irq;
> +	}
> +
> +	/* Now read E_TEMP again: it is acting like a status bit.
> +	 * If over-temperature, then this status will be true.
> +	 * If not over-temperature, this status will be false.
> +	 */
> +	ret = regmap_read(thermal->hw->regmap,
> +			  DA9062AA_EVENT_B,
> +			  &val);
> +	if (ret < 0) {
> +		dev_err(thermal->dev,
> +			"Cannot check the TJUNC temperature status\n");
> +		goto err_enable_irq;
> +	}
> +
> +	if (val & DA9062AA_E_TEMP_MASK) {
> +		mutex_lock(&thermal->lock);
> +		thermal->temperature = DA9062_MILLI_CELSIUS(125);
> +		mutex_unlock(&thermal->lock);
> +		thermal_zone_device_update(thermal->zone,
> +					   THERMAL_EVENT_UNSPECIFIED);
> +
> +		delay = msecs_to_jiffies(thermal->zone->passive_delay);
> +		schedule_delayed_work(&thermal->work, delay);
> +		return;
> +	}
> +
> +	mutex_lock(&thermal->lock);
> +	thermal->temperature = DA9062_MILLI_CELSIUS(0);
> +	mutex_unlock(&thermal->lock);
> +	thermal_zone_device_update(thermal->zone,
> +				   THERMAL_EVENT_UNSPECIFIED);
> +
> +err_enable_irq:
> +	enable_irq(thermal->irq);
> +}
> +
> +static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
> +{
> +	struct da9062_thermal *thermal = data;
> +
> +	disable_irq_nosync(thermal->irq);
> +	schedule_delayed_work(&thermal->work, 0);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int da9062_thermal_get_mode(struct thermal_zone_device *z,
> +				   enum thermal_device_mode *mode)
> +{
> +	struct da9062_thermal *thermal = z->devdata;
> +	*mode = thermal->mode;
> +	return 0;
> +}
> +
> +static int da9062_thermal_get_trip_type(struct thermal_zone_device *z,
> +					int trip,
> +					enum thermal_trip_type *type)
> +{
> +	struct da9062_thermal *thermal = z->devdata;
> +
> +	switch (trip) {
> +	case 0:
> +		*type = THERMAL_TRIP_HOT;
> +		break;
> +	default:
> +		dev_err(thermal->dev,
> +			"Driver does not support more than 1 trip-wire\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int da9062_thermal_get_trip_temp(struct thermal_zone_device *z,
> +					int trip,
> +					int *temp)
> +{
> +	struct da9062_thermal *thermal = z->devdata;
> +
> +	switch (trip) {
> +	case 0:
> +		*temp = DA9062_MILLI_CELSIUS(125);
> +		break;
> +	default:
> +		dev_err(thermal->dev,
> +			"Driver does not support more than 1 trip-wire\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int da9062_thermal_get_temp(struct thermal_zone_device *z,
> +				   int *temp)
> +{
> +	struct da9062_thermal *thermal = z->devdata;
> +
> +	mutex_lock(&thermal->lock);
> +	*temp = thermal->temperature;
> +	mutex_unlock(&thermal->lock);
> +
> +	return 0;
> +}
> +
> +static struct thermal_zone_device_ops da9062_thermal_ops = {
> +	.get_temp	= da9062_thermal_get_temp,
> +	.get_mode	= da9062_thermal_get_mode,
> +	.get_trip_type	= da9062_thermal_get_trip_type,
> +	.get_trip_temp	= da9062_thermal_get_trip_temp,
> +};
> +
> +static const struct da9062_thermal_config da9062_config = {
> +	.name = "da9062-thermal",
> +};
> +
> +static const struct of_device_id da9062_compatible_reg_id_table[] = {
> +	{ .compatible = "dlg,da9062-thermal", .data = &da9062_config },
> +	{ },
> +};
> +
> +MODULE_DEVICE_TABLE(of, da9062_compatible_reg_id_table);
> +
> +static int da9062_thermal_probe(struct platform_device *pdev)
> +{
> +	struct da9062 *chip = dev_get_drvdata(pdev->dev.parent);
> +	struct da9062_thermal *thermal;
> +	unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
> +	const struct of_device_id *match;
> +	int ret = 0;
> +
> +	match = of_match_node(da9062_compatible_reg_id_table,
> +			      pdev->dev.of_node);
> +	if (!match)
> +		return -ENXIO;
> +
> +	if (pdev->dev.of_node) {
> +		if (!of_property_read_u32(pdev->dev.of_node,
> +					  "polling-delay-passive",
> +					  &pp_tmp)) {
> +			if (pp_tmp < DA9062_MIN_POLLING_MS_PERIOD ||
> +			    pp_tmp > DA9062_MAX_POLLING_MS_PERIOD) {
> +				dev_warn(&pdev->dev,
> +					 "Out-of-range polling period %d ms\n",
> +					 pp_tmp);
> +				pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
> +			}
> +		}
> +	}
> +
> +	thermal = devm_kzalloc(&pdev->dev, sizeof(struct da9062_thermal),
> +			       GFP_KERNEL);
> +	if (!thermal) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	thermal->config = match->data;
> +	thermal->hw = chip;
> +	thermal->mode = THERMAL_DEVICE_ENABLED;
> +	thermal->dev = &pdev->dev;
> +
> +	INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
> +	mutex_init(&thermal->lock);
> +
> +	thermal->zone = thermal_zone_device_register(thermal->config->name,
> +					1, 0, thermal,
> +					&da9062_thermal_ops, NULL, pp_tmp,
> +					0);
> +	if (IS_ERR(thermal->zone)) {
> +		dev_err(&pdev->dev, "Cannot register thermal zone device\n");
> +		ret = PTR_ERR(thermal->zone);
> +		goto err;
> +	}
> +
> +	dev_dbg(&pdev->dev,
> +		"TJUNC temperature polling period set at %d ms\n",
> +		thermal->zone->passive_delay);
> +
> +	ret = platform_get_irq_byname(pdev, "THERMAL");
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to get platform IRQ.\n");
> +		goto err_zone;
> +	}
> +	thermal->irq = ret;
> +
> +	ret = request_threaded_irq(thermal->irq, NULL,
> +				   da9062_thermal_irq_handler,
> +				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> +				   "THERMAL", thermal);
> +	if (ret) {
> +		dev_err(&pdev->dev,
> +			"Failed to request thermal device IRQ.\n");
> +		goto err_zone;
> +	}
> +
> +	platform_set_drvdata(pdev, thermal);
> +	return 0;
> +
> +err_zone:
> +	thermal_zone_device_unregister(thermal->zone);
> +err:
> +	return ret;
> +}
> +
> +static int da9062_thermal_remove(struct platform_device *pdev)
> +{
> +	struct	da9062_thermal *thermal = platform_get_drvdata(pdev);
> +
> +	free_irq(thermal->irq, thermal);
> +	cancel_delayed_work_sync(&thermal->work);
> +	thermal_zone_device_unregister(thermal->zone);
> +	return 0;
> +}
> +
> +static struct platform_driver da9062_thermal_driver = {
> +	.probe	= da9062_thermal_probe,
> +	.remove	= da9062_thermal_remove,
> +	.driver	= {
> +		.name	= "da9062-thermal",
> +		.of_match_table = da9062_compatible_reg_id_table,
> +	},
> +};
> +
> +module_platform_driver(da9062_thermal_driver);
> +
> +MODULE_AUTHOR("Steve Twiss");
> +MODULE_DESCRIPTION("Thermal TJUNC device driver for Dialog DA9062 and DA9061");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:da9062-thermal");
> -- 
> end-of-patch for PATCH V7
> 

^ permalink raw reply

* Re: [PATCH V4 2/2] thermal: broadcom: add Northstar thermal driver
From: Florian Fainelli @ 2017-04-01 20:20 UTC (permalink / raw)
  To: Eduardo Valentin, Rafał Miłecki
  Cc: Zhang Rui, Rob Herring, Mark Rutland, Stephen Warren, Lee Jones,
	Eric Anholt, Ray Jui, Scott Branden, bcm-kernel-feedback-list,
	linux-pm, devicetree, linux-rpi-kernel, linux-arm-kernel,
	Rafał Miłecki, Jon Mason
In-Reply-To: <20170401195443.GE28514@localhost.localdomain>

On April 1, 2017 12:54:45 PM PDT, Eduardo Valentin <edubezval@gmail.com> wrote:
>Also, I have just merged a BRCM driver. Does it make sense to move it
>here too?

I think it does make sense to have all Broadcom SoCs thermal drivers under a broadcom/ directory. As a matter of fact, I will be submitting another one (for brcmstb SoCs) shortly.
Hi Eduardo,
-- 
Florian

^ permalink raw reply

* Re: [PATCH V4 2/2] thermal: broadcom: add Northstar thermal driver
From: Rafał Miłecki @ 2017-04-01 21:41 UTC (permalink / raw)
  To: Eduardo Valentin, Rafał Miłecki
  Cc: Mark Rutland, devicetree, Florian Fainelli, Scott Branden,
	Stephen Warren, Ray Jui, linux-pm, Lee Jones, Jon Mason,
	Eric Anholt, Rob Herring, bcm-kernel-feedback-list,
	linux-rpi-kernel, Zhang Rui, linux-arm-kernel
In-Reply-To: <20170401195443.GE28514@localhost.localdomain>

On 04/01/2017 09:54 PM, Eduardo Valentin wrote:
> On Fri, Mar 31, 2017 at 10:11:24PM +0200, Rafał Miłecki wrote:
>> From: Rafał Miłecki <rafal@milecki.pl>
>>
>> Northstar is a SoC family commonly used in home routers. This commit
>> adds a driver for checking CPU temperature. As Northstar Plus seems to
>> also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.
>>
>> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
>> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
>> ---
>
> This driver looks fine from what concerns the of thermal usage.
> I had only one request on the DT bindings example. I believe better to
> get the example fixed so bad DTs does not get copied.

Thanks! I'll comment on this in a reply to patch 1/2.


>> V2: Make it iProc specific as NSP can also use this driver
>>     Select proper symbols in config ARCH_BCM_IPROC
>>     Define PVTMON register bits
>>     Update code selecting temperature monitor mode
>>     Thank you Jon!
>> V3: More details in help message for BCM_NS_THERMAL
>>     Use slope & offset
>>     Drop arch code change (I'll be submitted using a proper tree)
>>     Thank you Eduardo!
>> V4: Comment operations on PVTMON_CONTROL0 register
>> ---
>>  drivers/thermal/Kconfig               |   5 ++
>>  drivers/thermal/Makefile              |   1 +
>>  drivers/thermal/broadcom/Kconfig      |   8 +++
>>  drivers/thermal/broadcom/Makefile     |   1 +
>>  drivers/thermal/broadcom/ns-thermal.c | 105 ++++++++++++++++++++++++++++++++++
>
> Also, I have just merged a BRCM driver. Does it make sense to move it
> here too?
>
> It does not need to be a blocking request for this driver though.

Yes, I plan to send a patch for that after getting this one accepted.

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

^ permalink raw reply

* Re: [PATCH V4 1/2] dt-bindings: thermal: add support for Broadcom's Northstar thermal
From: Rafał Miłecki @ 2017-04-01 21:50 UTC (permalink / raw)
  To: Eduardo Valentin, Florian Fainelli, Jon Mason
  Cc: Zhang Rui, Rob Herring, Mark Rutland, Stephen Warren, Lee Jones,
	Eric Anholt, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Rafał Miłecki
In-Reply-To: <20170401195136.GD28514-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>

On 04/01/2017 09:51 PM, Eduardo Valentin wrote:
> On Fri, Mar 31, 2017 at 10:11:23PM +0200, Rafał Miłecki wrote:
>> From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>>
>> This commit documents binding for thermal used in Northstar family SoCs.
>>
>> Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>> ---
>> V3: Add thermal-zones to the example
>>     Rob: Because of this update, I didn't include Acked-by I got for V2
>> ---
>>  .../devicetree/bindings/thermal/brcm,ns-thermal    | 26 ++++++++++++++++++++++
>>  1 file changed, 26 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal
>>
>> diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
>> new file mode 100644
>> index 000000000000..c561c7349f17
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
>> @@ -0,0 +1,26 @@
>> +* Broadcom Northstar Thermal
>> +
>> +This binding describes thermal sensor that is part of Northstar's DMU (Device
>> +Management Unit).
>> +
>> +Required properties:
>> +- compatible : Must be "brcm,ns-thermal"
>> +- reg : iomem address range of PVTMON registers
>> +- #thermal-sensor-cells : Should be <0>
>> +
>> +Example:
>> +
>> +thermal: thermal@1800c2c0 {
>> +	compatible = "brcm,ns-thermal";
>> +	reg = <0x1800c2c0 0x10>;
>> +	#thermal-sensor-cells = <0>;
>> +};
>> +
>> +thermal-zones {
>> +	cpu_thermal: cpu-thermal {
>> +		polling-delay-passive = <0>;
>> +		polling-delay = <1000>;
>> +		coefficients = <(-556) 418000>;
>> +		thermal-sensors = <&thermal>;
>
> You need to define trips and cooling devices here. Otherwise, makes
> little sense to have this device in thermal subsystem. Here is an
> example of minimal set:
> https://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git/commit/?h=linus&id=1e2ac9821de6a85d3e8358f238436708d1d46869
>
> The above has no passive action. It is just gonna shutdown the system if
> temperature crosses a threshold.
>
> But, a typical cooling device would be CPU frequency throttling. Do you have
> that up and running in your routers?

I don't have CPU freq throttling, so shutdown will be the only solution for
critical temp right now.

I know I should have at least a trip for critical temperature, but the problem
is I don't know what value to use. There isn't any info about this in public
datasheets. Broadcom's SDK doesn't mention it. Vendors share only the max
environment temp, not the max CPU temp.

So for now I only meant to provide user space access to reading current CPU
temperature. I could do some stress tests and ask other users to do it as well.

Or maybe I could just put in Documentation some round value that makes more or
less sense and then work on a proper content of real DTS files?

Unless we can get some hint from Broadcom people. Jon? Florian? Anyone?

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] Make EN2 pin optional in the TRF7970A driver
From: Samuel Ortiz @ 2017-04-01 22:35 UTC (permalink / raw)
  To: Heiko Schocher
  Cc: netdev, devicetree, linux-wireless, linux-kernel, Rob Herring,
	Mark Rutland
In-Reply-To: <1486444924-18444-1-git-send-email-hs@denx.de>

Hi Heiko,

On Tue, Feb 07, 2017 at 06:22:04AM +0100, Heiko Schocher wrote:
> From: Guan Ben <ben.guan@cn.bosch.com>
> 
> Make the EN2 pin optional. This is useful for boards,
> which have this pin fix wired, for example to ground.
> 
> Signed-off-by: Guan Ben <ben.guan@cn.bosch.com>
> Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> 
> ---
> 
>  .../devicetree/bindings/net/nfc/trf7970a.txt       |  4 ++--
>  drivers/nfc/trf7970a.c                             | 26 ++++++++++++----------
>  2 files changed, 16 insertions(+), 14 deletions(-)
Applied to nfc-next, thanks.

Cheers,
Samuel.

^ permalink raw reply

* Re: [PATCH linux v5 2/2] drivers: hwmon: Support for ASPEED PWM/Fan tach
From: Guenter Roeck @ 2017-04-01 22:45 UTC (permalink / raw)
  To: Jaghathiswari Rankappagounder Natarajan,
	joel-U3u1mxZcP9KHXe+LvDLADg, jdelvare-IBi9RG/b67k,
	linux-hwmon-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	openbmc-uLR06cmDAlY/bJ5BZ2RsiQ, corbet-T1hC0tSOHrs,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170324181723.29379-3-jaghu-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>

On 03/24/2017 11:17 AM, Jaghathiswari Rankappagounder Natarajan wrote:
> The ASPEED AST2400/2500 PWM controller supports 8 PWM output ports.
> The ASPEED AST2400/2500 Fan tach controller supports 16 tachometer
> inputs.
> The device driver matches on the device tree node. The configuration
> values
> are read from the device tree and written to the respective registers.
> The driver provides a sysfs entries through which the user can
> configure the duty-cycle value (ranging from 0 to 100 percent) and read
> the
> fan tach rpm value.
>

Odd line breaks.

> Signed-off-by: Jaghathiswari Rankappagounder Natarajan <jaghu-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> ---
>  v5:
> - Changed the driver to suit the changes in the device tree documentation
>
>  v4:
> - Modified this driver to suit the representation in the devicetree
>
>  v3:
> - Only sent out device tree documentation; did not send this driver
>
>  v2:
> - Used BIT()
> - Used regmap
> - Avoided division when raw data is 0
> - Removed empty lines between declaration
> - Removed macros; Used two attribute groups and used is_visible callback
> - Returned error when properties are undefined
> - Removed .owner field
> - Used PTR_ERR_OR_ZERO
> - Removed explicit of_node_put for child nodes
>
>  Documentation/hwmon/aspeed-pwm-tacho |  22 +
>  drivers/hwmon/Kconfig                |  13 +-
>  drivers/hwmon/Makefile               |   1 +
>  drivers/hwmon/aspeed-pwm-tacho.c     | 854 +++++++++++++++++++++++++++++++++++
>  4 files changed, 888 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/hwmon/aspeed-pwm-tacho
>  create mode 100644 drivers/hwmon/aspeed-pwm-tacho.c
>
> diff --git a/Documentation/hwmon/aspeed-pwm-tacho b/Documentation/hwmon/aspeed-pwm-tacho
> new file mode 100644
> index 000000000000..0e9ec6d5f900
> --- /dev/null
> +++ b/Documentation/hwmon/aspeed-pwm-tacho
> @@ -0,0 +1,22 @@
> +Kernel driver aspeed-pwm-tacho
> +==============================
> +
> +Supported chips:
> +	ASPEED AST2400/2500
> +
> +Authors:
> +	<jaghu-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> +
> +Description:
> +------------
> +This driver implements support for ASPEED AST2400/2500 PWM and Fan Tacho
> +controller. The PWM controller supports upto 8 PWM outputs. The Fan tacho
> +controller supports upto 16 tachometer inputs.
> +
up to

> +The driver provides the following sensor accesses in sysfs:
> +
> +fanX_input	ro	provide current fan rotation value in RPM as reported
> +			by the fan to the device.
> +
> +pwmX		rw	get or set PWM fan control value. This is an integer
> +			value between 0(off) and 255(full speed).
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 45cef3d2c75c..487110f21827 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -341,6 +341,15 @@ config SENSORS_ASB100
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called asb100.
>
> +config SENSORS_ASPEED
> +	tristate "ASPEED AST2400/AST2500 PWM and Fan tach driver"
> +	help
> +	  This driver provides support for ASPEED AST2400/AST2500 PWM
> +	  and Fan Tacho controllers.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called aspeed_pwm_tacho.
> +
>  config SENSORS_ATXP1
>  	tristate "Attansic ATXP1 VID controller"
>  	depends on I2C
> @@ -952,7 +961,7 @@ config SENSORS_LM70
>  	help
>  	  If you say yes here you get support for the National Semiconductor
>  	  LM70, LM71, LM74 and Texas Instruments TMP121/TMP123 digital tempera-
> -	  ture sensor chips.
> +	  true sensor chips.

Unrelated. Please drop. Separate patch would be appreciated, of course.

>
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called lm70.
> @@ -1506,7 +1515,7 @@ config SENSORS_ADS7871
>
>  config SENSORS_AMC6821
>  	tristate "Texas Instruments AMC6821"
> -	depends on I2C
> +	depends on I2C

Unrelated. Please drop.

>  	help
>  	  If you say yes here you get support for the Texas Instruments
>  	  AMC6821 hardware monitoring chips.
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index aecf4ba17460..83025cc9bb45 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -46,6 +46,7 @@ obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
>  obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
>  obj-$(CONFIG_SENSORS_ARM_SCPI)	+= scpi-hwmon.o
>  obj-$(CONFIG_SENSORS_ASC7621)	+= asc7621.o
> +obj-$(CONFIG_SENSORS_ASPEED)	+= aspeed-pwm-tacho.o
>  obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
>  obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
>  obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
> diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
> new file mode 100644
> index 000000000000..28888cc34555
> --- /dev/null
> +++ b/drivers/hwmon/aspeed-pwm-tacho.c
> @@ -0,0 +1,854 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 or later as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/delay.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/sysfs.h>
> +#include <linux/regmap.h>
> +
> +/* ASPEED PWM & FAN Tach Register Definition */
> +#define ASPEED_PTCR_CTRL		0x00
> +#define ASPEED_PTCR_CLK_CTRL		0x04
> +#define ASPEED_PTCR_DUTY0_CTRL		0x08
> +#define ASPEED_PTCR_DUTY1_CTRL		0x0c
> +#define ASPEED_PTCR_TYPEM_CTRL		0x10
> +#define ASPEED_PTCR_TYPEM_CTRL1		0x14
> +#define ASPEED_PTCR_TYPEN_CTRL		0x18
> +#define ASPEED_PTCR_TYPEN_CTRL1		0x1c
> +#define ASPEED_PTCR_TACH_SOURCE		0x20
> +#define ASPEED_PTCR_TRIGGER		0x28
> +#define ASPEED_PTCR_RESULT		0x2c
> +#define ASPEED_PTCR_INTR_CTRL		0x30
> +#define ASPEED_PTCR_INTR_STS		0x34
> +#define ASPEED_PTCR_TYPEM_LIMIT		0x38
> +#define ASPEED_PTCR_TYPEN_LIMIT		0x3C
> +#define ASPEED_PTCR_CTRL_EXT		0x40
> +#define ASPEED_PTCR_CLK_CTRL_EXT	0x44
> +#define ASPEED_PTCR_DUTY2_CTRL		0x48
> +#define ASPEED_PTCR_DUTY3_CTRL		0x4c
> +#define ASPEED_PTCR_TYPEO_CTRL		0x50
> +#define ASPEED_PTCR_TYPEO_CTRL1		0x54
> +#define ASPEED_PTCR_TACH_SOURCE_EXT	0x60
> +#define ASPEED_PTCR_TYPEO_LIMIT		0x78
> +
> +/* ASPEED_PTCR_CTRL : 0x00 - General Control Register */
> +#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1	15
> +#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2	6
> +#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK	(BIT(7) | BIT(15))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1	14
> +#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2	5
> +#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK	(BIT(6) | BIT(14))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1	13
> +#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2	4
> +#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK	(BIT(5) | BIT(13))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1	12
> +#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2	3
> +#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK	(BIT(4) | BIT(12))
> +
> +#define	ASPEED_PTCR_CTRL_FAN_NUM_EN(x)	BIT(16 + (x))
> +
> +#define	ASPEED_PTCR_CTRL_PWMD_EN	BIT(11)
> +#define	ASPEED_PTCR_CTRL_PWMC_EN	BIT(10)
> +#define	ASPEED_PTCR_CTRL_PWMB_EN	BIT(9)
> +#define	ASPEED_PTCR_CTRL_PWMA_EN	BIT(8)
> +
> +#define	ASPEED_PTCR_CTRL_CLK_SRC	BIT(1)
> +#define	ASPEED_PTCR_CTRL_CLK_EN		BIT(0)
> +
> +/* ASPEED_PTCR_CLK_CTRL : 0x04 - Clock Control Register */
> +/* TYPE N */
> +#define ASPEED_PTCR_CLK_CTRL_TYPEN_MASK		GENMASK(31, 16)
> +#define ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT		24
> +#define ASPEED_PTCR_CLK_CTRL_TYPEN_H		20
> +#define ASPEED_PTCR_CLK_CTRL_TYPEN_L		16
> +/* TYPE M */
> +#define ASPEED_PTCR_CLK_CTRL_TYPEM_MASK         GENMASK(15, 0)
> +#define ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT		8
> +#define ASPEED_PTCR_CLK_CTRL_TYPEM_H		4
> +#define ASPEED_PTCR_CLK_CTRL_TYPEM_L		0
> +
> +/*
> + * ASPEED_PTCR_DUTY_CTRL/1/2/3 : 0x08/0x0C/0x48/0x4C - PWM-FAN duty control
> + * 0/1/2/3 register
> + */
> +#define DUTY_CTRL_PWM2_FALL_POINT	24
> +#define DUTY_CTRL_PWM2_RISE_POINT	16
> +#define DUTY_CTRL_PWM2_RISE_FALL_MASK	GENMASK(31, 16)
> +#define DUTY_CTRL_PWM1_FALL_POINT	8
> +#define DUTY_CTRL_PWM1_RISE_POINT	0
> +#define DUTY_CTRL_PWM1_RISE_FALL_MASK   GENMASK(15, 0)
> +
> +/* ASPEED_PTCR_TYPEM_CTRL : 0x10/0x18/0x50 - Type M/N/O Ctrl 0 Register */
> +#define TYPE_CTRL_FAN_MASK		(GENMASK(5, 1) | GENMASK(31, 16))
> +#define TYPE_CTRL_FAN1_MASK		GENMASK(31, 0)
> +#define TYPE_CTRL_FAN_PERIOD		16
> +#define TYPE_CTRL_FAN_MODE		4
> +#define TYPE_CTRL_FAN_DIVISION		1
> +#define TYPE_CTRL_FAN_TYPE_EN		1
> +
> +/* ASPEED_PTCR_TACH_SOURCE : 0x20/0x60 - Tach Source Register */
> +/* bit [0,1] at 0x20, bit [2] at 0x60 */
> +#define TACH_PWM_SOURCE_BIT01(x)	((x) * 2)
> +#define TACH_PWM_SOURCE_BIT2(x)		((x) * 2)
> +#define TACH_PWM_SOURCE_MASK_BIT01(x)	(0x3 << ((x) * 2))
> +#define TACH_PWM_SOURCE_MASK_BIT2(x)	BIT((x) * 2)
> +
> +/* ASPEED_PTCR_RESULT : 0x2c - Result Register */
> +#define RESULT_STATUS_MASK		BIT(31)
> +#define RESULT_VALUE_MASK		0xfffff
> +
> +/* ASPEED_PTCR_CTRL_EXT : 0x40 - General Control Extension #1 Register */
> +#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1	15
> +#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2	6
> +#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK	(BIT(7) | BIT(15))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1	14
> +#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2	5
> +#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK	(BIT(6) | BIT(14))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1	13
> +#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2	4
> +#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK	(BIT(5) | BIT(13))
> +
> +#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1	12
> +#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2	3
> +#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK	(BIT(4) | BIT(12))
> +
> +#define	ASPEED_PTCR_CTRL_PWMH_EN	BIT(11)
> +#define	ASPEED_PTCR_CTRL_PWMG_EN	BIT(10)
> +#define	ASPEED_PTCR_CTRL_PWMF_EN	BIT(9)
> +#define	ASPEED_PTCR_CTRL_PWME_EN	BIT(8)
> +
> +/* ASPEED_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1 Register */
> +/* TYPE O */
> +#define ASPEED_PTCR_CLK_CTRL_TYPEO_MASK         GENMASK(15, 0)
> +#define ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT		8
> +#define ASPEED_PTCR_CLK_CTRL_TYPEO_H		4
> +#define ASPEED_PTCR_CLK_CTRL_TYPEO_L		0
> +
> +#define PWM_MAX 255
> +
> +#define M_PWM_DIV_H 0x00
> +#define M_PWM_DIV_L 0x05
> +#define M_PWM_PERIOD 0x5F
> +#define M_TACH_CLK_DIV 0x00
> +#define M_TACH_MODE 0x00
> +#define M_TACH_UNIT 0x1000
> +#define INIT_FAN_CTRL 0xFF
> +
> +struct aspeed_pwm_tacho_regmap {
> +	void __iomem *regs;
> +};
> +

Can't you just use the regs pointer directly ? Why a structure with just one
variable in it ?

> +struct aspeed_pwm_tacho_data {
> +	struct regmap *regmap;
> +	unsigned long clk_freq;
> +	bool pwm_present[8];
> +	bool fan_tach_present[16];
> +	u8 type_pwm_clock_unit[3];
> +	u8 type_pwm_clock_division_h[3];
> +	u8 type_pwm_clock_division_l[3];
> +	u8 type_fan_tach_clock_division[3];
> +	u16 type_fan_tach_unit[3];
> +	u8 pwm_port_type[8];
> +	u8 pwm_port_fan_ctrl[8];
> +	u8 fan_tach_ch_source[16];
> +	const struct attribute_group *groups[2];

groups must be NULL terminated, so you'll need three groups here since
two are used.

> +};
> +
> +enum type { TYPEM, TYPEN, TYPEO };
> +
> +struct type_params {
> +	u32 l_value;
> +	u32 h_value;
> +	u32 unit_value;
> +	u32 clk_ctrl_mask;
> +	u32 clk_ctrl_reg;
> +	u32 ctrl_reg;
> +	u32 ctrl_reg1;
> +};
> +
> +static const struct type_params type_params[] = {
> +	[TYPEM] = {
> +		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEM_L,
> +		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEM_H,
> +		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT,
> +		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEM_MASK,
> +		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
> +		.ctrl_reg = ASPEED_PTCR_TYPEM_CTRL,
> +		.ctrl_reg1 = ASPEED_PTCR_TYPEM_CTRL1,
> +	},
> +	[TYPEN] = {
> +		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEN_L,
> +		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEN_H,
> +		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT,
> +		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEN_MASK,
> +		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
> +		.ctrl_reg = ASPEED_PTCR_TYPEN_CTRL,
> +		.ctrl_reg1 = ASPEED_PTCR_TYPEN_CTRL1,
> +	},
> +	[TYPEO] = {
> +		.l_value = ASPEED_PTCR_CLK_CTRL_TYPEO_L,
> +		.h_value = ASPEED_PTCR_CLK_CTRL_TYPEO_H,
> +		.unit_value = ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT,
> +		.clk_ctrl_mask = ASPEED_PTCR_CLK_CTRL_TYPEO_MASK,
> +		.clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL_EXT,
> +		.ctrl_reg = ASPEED_PTCR_TYPEO_CTRL,
> +		.ctrl_reg1 = ASPEED_PTCR_TYPEO_CTRL1,
> +	}
> +};
> +
> +enum pwm_port { PWMA, PWMB, PWMC, PWMD, PWME, PWMF, PWMG, PWMH };
> +
> +struct pwm_port_params {
> +	u32 pwm_en;
> +	u32 ctrl_reg;
> +	u32 type_part1;
> +	u32 type_part2;
> +	u32 type_mask;
> +	u32 duty_ctrl_rise_point;
> +	u32 duty_ctrl_fall_point;
> +	u32 duty_ctrl_reg;
> +	u32 duty_ctrl_rise_fall_mask;
> +};
> +
> +static const struct pwm_port_params pwm_port_params[] = {
> +	[PWMA] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMA_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
> +	},
> +	[PWMB] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMB_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
> +	},
> +	[PWMC] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMC_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
> +	},
> +	[PWMD] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMD_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
> +	},
> +	[PWME] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWME_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
> +	},
> +	[PWMF] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMF_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
> +	},
> +	[PWMG] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMG_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM1_RISE_FALL_MASK,
> +	},
> +	[PWMH] = {
> +		.pwm_en = ASPEED_PTCR_CTRL_PWMH_EN,
> +		.ctrl_reg = ASPEED_PTCR_CTRL_EXT,
> +		.type_part1 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1,
> +		.type_part2 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2,
> +		.type_mask = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK,
> +		.duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
> +		.duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
> +		.duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
> +		.duty_ctrl_rise_fall_mask = DUTY_CTRL_PWM2_RISE_FALL_MASK,
> +	}
> +};
> +
> +static int regmap_aspeed_pwm_tacho_reg_write(void *context, unsigned int reg,
> +					     unsigned int val)
> +{
> +	struct aspeed_pwm_tacho_regmap *hregmap = context;
> +
> +	writel(val, hregmap->regs + reg);
> +	return 0;
> +}
> +
> +static int regmap_aspeed_pwm_tacho_reg_read(void *context, unsigned int reg,
> +					    unsigned int *val)
> +{
> +	struct aspeed_pwm_tacho_regmap *hregmap = context;
> +
> +	*val = readl(hregmap->regs + reg);
> +	return 0;
> +}
> +
> +static const struct regmap_config aspeed_pwm_tacho_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = ASPEED_PTCR_TYPEO_LIMIT,
> +	.reg_write = regmap_aspeed_pwm_tacho_reg_write,
> +	.reg_read = regmap_aspeed_pwm_tacho_reg_read,
> +	.fast_io = true,
> +};
> +
> +static void aspeed_set_clock_enable(struct regmap *regmap, bool val)
> +{
> +	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
> +			   ASPEED_PTCR_CTRL_CLK_EN,
> +			   val ? ASPEED_PTCR_CTRL_CLK_EN : 0);
> +}
> +
> +static void aspeed_set_clock_source(struct regmap *regmap, int val)
> +{
> +	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
> +			   ASPEED_PTCR_CTRL_CLK_SRC,
> +			   val ? ASPEED_PTCR_CTRL_CLK_SRC : 0);
> +}
> +
> +static void aspeed_set_pwm_clock_values(struct regmap *regmap, u8 type,
> +					u8 div_high, u8 div_low, u8 unit)
> +{
> +	u32 reg_value = ((div_high << type_params[type].h_value) |
> +			 (div_low << type_params[type].l_value) |
> +			 (unit << type_params[type].unit_value));
> +
> +	regmap_update_bits(regmap, type_params[type].clk_ctrl_reg,
> +			   type_params[type].clk_ctrl_mask, reg_value);
> +}
> +
> +static void aspeed_set_pwm_port_enable(struct regmap *regmap, u8 pwm_port,
> +				       bool enable)
> +{
> +	regmap_update_bits(regmap, pwm_port_params[pwm_port].ctrl_reg,
> +			   pwm_port_params[pwm_port].pwm_en,
> +			   enable ? pwm_port_params[pwm_port].pwm_en : 0);
> +}
> +
> +static void aspeed_set_pwm_port_type(struct regmap *regmap,
> +				     u8 pwm_port, u8 type)
> +{
> +	u32 reg_value = (type & 0x1) << pwm_port_params[pwm_port].type_part1;
> +
> +	reg_value |= (type & 0x2) << pwm_port_params[pwm_port].type_part2;
> +
> +	regmap_update_bits(regmap, pwm_port_params[pwm_port].ctrl_reg,
> +			   pwm_port_params[pwm_port].type_mask, reg_value);
> +}
> +
> +static void aspeed_set_pwm_port_duty_rising_falling(struct regmap *regmap,
> +						    u8 pwm_port, u8 rising,
> +						    u8 falling)
> +{
> +	u32 reg_value = (rising <<
> +			 pwm_port_params[pwm_port].duty_ctrl_rise_point);
> +	reg_value |= (falling <<
> +		      pwm_port_params[pwm_port].duty_ctrl_fall_point);
> +
> +	regmap_update_bits(regmap, pwm_port_params[pwm_port].duty_ctrl_reg,
> +			   pwm_port_params[pwm_port].duty_ctrl_rise_fall_mask,
> +			   reg_value);
> +}
> +
> +static void aspeed_set_tacho_type_enable(struct regmap *regmap, u8 type,
> +					 bool enable)
> +{
> +	regmap_update_bits(regmap, type_params[type].ctrl_reg,
> +			   TYPE_CTRL_FAN_TYPE_EN,
> +			   enable ? TYPE_CTRL_FAN_TYPE_EN : 0);
> +}
> +
> +static void aspeed_set_tacho_type_values(struct regmap *regmap, u8 type,
> +					 u8 mode, u16 unit, u8 division)
> +{
> +	u32 reg_value = ((mode << TYPE_CTRL_FAN_MODE) |
> +			 (unit << TYPE_CTRL_FAN_PERIOD) |
> +			 (division << TYPE_CTRL_FAN_DIVISION));
> +
> +	regmap_update_bits(regmap, type_params[type].ctrl_reg,
> +			   TYPE_CTRL_FAN_MASK, reg_value);
> +	regmap_update_bits(regmap, type_params[type].ctrl_reg1,
> +			   TYPE_CTRL_FAN1_MASK, unit << 16);
> +}
> +
> +static void aspeed_set_fan_tach_ch_enable(struct regmap *regmap, u8 fan_tach_ch,
> +					  bool enable)
> +{
> +	regmap_update_bits(regmap, ASPEED_PTCR_CTRL,
> +			   ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch),
> +			   enable ?
> +			   ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch) : 0);
> +}
> +
> +static void aspeed_set_fan_tach_ch_source(struct regmap *regmap, u8 fan_tach_ch,
> +					  u8 fan_tach_ch_source)
> +{
> +	u32 reg_value1 = ((fan_tach_ch_source & 0x3) <<
> +			  TACH_PWM_SOURCE_BIT01(fan_tach_ch));
> +	u32 reg_value2 = (((fan_tach_ch_source & 0x4) >> 2) <<
> +			  TACH_PWM_SOURCE_BIT2(fan_tach_ch));
> +
> +	regmap_update_bits(regmap, ASPEED_PTCR_TACH_SOURCE,
> +			   TACH_PWM_SOURCE_MASK_BIT01(fan_tach_ch),
> +			   reg_value1);
> +
> +	regmap_update_bits(regmap, ASPEED_PTCR_TACH_SOURCE_EXT,
> +			   TACH_PWM_SOURCE_MASK_BIT2(fan_tach_ch),
> +			   reg_value2);
> +}
> +
> +static void aspeed_set_pwm_port_fan_ctrl(struct aspeed_pwm_tacho_data *priv,
> +					 u8 index, u8 fan_ctrl)
> +{
> +	u16 period, dc_time_on;
> +
> +	period = priv->type_pwm_clock_unit[priv->pwm_port_type[index]];
> +	period += 1;
> +	dc_time_on = (fan_ctrl * period) / PWM_MAX;
> +
> +	if (dc_time_on == 0) {
> +		aspeed_set_pwm_port_enable(priv->regmap, index, false);
> +	} else {
> +		if (dc_time_on == period)
> +			dc_time_on = 0;
> +
> +		aspeed_set_pwm_port_duty_rising_falling(priv->regmap, index, 0,
> +							dc_time_on);
> +		aspeed_set_pwm_port_enable(priv->regmap, index, true);
> +	}
> +}
> +
> +static u32 aspeed_get_fan_tach_ch_measure_period(struct aspeed_pwm_tacho_data
> +						 *priv, u8 type)
> +{
> +	u32 clk;
> +	u16 tacho_unit;
> +	u8 clk_unit, div_h, div_l, tacho_div;
> +
> +	clk = priv->clk_freq;
> +	clk_unit = priv->type_pwm_clock_unit[type];
> +	div_h = priv->type_pwm_clock_division_h[type];
> +	div_h = 0x1 << div_h;
> +	div_l = priv->type_pwm_clock_division_l[type];
> +	if (div_l == 0)
> +		div_l = 1;
> +	else
> +		div_l = div_l * 2;
> +
> +	tacho_unit = priv->type_fan_tach_unit[type];
> +	tacho_div = priv->type_fan_tach_clock_division[type];
> +
> +	tacho_div = 0x4 << (tacho_div * 2);
> +	return clk / (clk_unit * div_h * div_l * tacho_div * tacho_unit);
> +}
> +
> +static u32 aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
> +				      u8 fan_tach_ch)
> +{
> +	u32 raw_data, tach_div, clk_source, timeout = 0, sec, val;
> +	u8 fan_tach_ch_source, type;
> +
> +	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0);
> +	regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch);
> +
> +	fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch];
> +	type = priv->pwm_port_type[fan_tach_ch_source];
> +
> +	sec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type));
> +
> +	msleep(sec);
> +
> +	regmap_read(priv->regmap, ASPEED_PTCR_RESULT, &val);
> +	while (!(val & RESULT_STATUS_MASK)) {
> +		timeout++;
> +		if (timeout > 1)
> +			return 0;
> +		msleep(sec);

val never changes.

> +	}
> +
> +	regmap_read(priv->regmap, ASPEED_PTCR_RESULT, &val);
> +	raw_data = val & RESULT_VALUE_MASK;
> +	tach_div = priv->type_fan_tach_clock_division[type];
> +
> +	tach_div = 0x4 << (tach_div * 2);
> +	clk_source = priv->clk_freq;
> +
> +	if (raw_data == 0)
> +		return 0;
> +	else

else is unnecessary after return

> +		return (clk_source * 60) / (2 * raw_data * tach_div);
> +}
> +
> +static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
> +		       const char *buf, size_t count)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int index = sensor_attr->index;
> +	int ret;
> +	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
> +	long fan_ctrl;
> +
> +	ret = kstrtol(buf, 10, &fan_ctrl);
> +	if (ret != 0)
> +		return ret;
> +
> +	if (fan_ctrl < 0 || fan_ctrl > PWM_MAX)
> +		return -EINVAL;
> +
> +	if (priv->pwm_port_fan_ctrl[index] == fan_ctrl)
> +		return count;
> +
> +	priv->pwm_port_fan_ctrl[index] = fan_ctrl;
> +	aspeed_set_pwm_port_fan_ctrl(priv, index, fan_ctrl);
> +
> +	return count;
> +}
> +
> +static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
> +			char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int index = sensor_attr->index;
> +	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
> +
> +	return sprintf(buf, "%u\n", priv->pwm_port_fan_ctrl[index]);
> +}
> +
> +static ssize_t show_rpm(struct device *dev, struct device_attribute *attr,
> +			char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int index = sensor_attr->index;
> +	u32 rpm;
> +	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
> +
> +	rpm = aspeed_get_fan_tach_ch_rpm(priv, index);
> +
> +	return sprintf(buf, "%u\n", rpm);
> +}
> +
> +static umode_t pwm_is_visible(struct kobject *kobj,
> +			      struct attribute *a, int index)
> +{
> +	struct device *dev = container_of(kobj, struct device, kobj);
> +	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
> +
> +	if (!priv->pwm_present[index])
> +		return 0;
> +	return a->mode;
> +}
> +
> +static umode_t fan_dev_is_visible(struct kobject *kobj,
> +				  struct attribute *a, int index)
> +{
> +	struct device *dev = container_of(kobj, struct device, kobj);
> +	struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
> +
> +	if (!priv->fan_tach_present[index])
> +		return 0;
> +	return a->mode;
> +}
> +
> +static SENSOR_DEVICE_ATTR(pwm0, 0644,
> +			show_pwm, set_pwm, 0);
> +static SENSOR_DEVICE_ATTR(pwm1, 0644,
> +			show_pwm, set_pwm, 1);
> +static SENSOR_DEVICE_ATTR(pwm2, 0644,
> +			show_pwm, set_pwm, 2);
> +static SENSOR_DEVICE_ATTR(pwm3, 0644,
> +			show_pwm, set_pwm, 3);
> +static SENSOR_DEVICE_ATTR(pwm4, 0644,
> +			show_pwm, set_pwm, 4);
> +static SENSOR_DEVICE_ATTR(pwm5, 0644,
> +			show_pwm, set_pwm, 5);
> +static SENSOR_DEVICE_ATTR(pwm6, 0644,
> +			show_pwm, set_pwm, 6);
> +static SENSOR_DEVICE_ATTR(pwm7, 0644,
> +			show_pwm, set_pwm, 7);

Unnecessary continuation lines.

> +
> +static struct attribute *pwm_dev_attrs[] = {
> +	&sensor_dev_attr_pwm0.dev_attr.attr,
> +	&sensor_dev_attr_pwm1.dev_attr.attr,
> +	&sensor_dev_attr_pwm2.dev_attr.attr,
> +	&sensor_dev_attr_pwm3.dev_attr.attr,
> +	&sensor_dev_attr_pwm4.dev_attr.attr,
> +	&sensor_dev_attr_pwm5.dev_attr.attr,
> +	&sensor_dev_attr_pwm6.dev_attr.attr,
> +	&sensor_dev_attr_pwm7.dev_attr.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group pwm_dev_group = {
> +	.attrs = pwm_dev_attrs,
> +	.is_visible = pwm_is_visible,
> +};
> +
> +static SENSOR_DEVICE_ATTR(fan0_input, 0444,
> +		show_rpm, NULL, 0);
> +static SENSOR_DEVICE_ATTR(fan1_input, 0444,
> +		show_rpm, NULL, 1);
> +static SENSOR_DEVICE_ATTR(fan2_input, 0444,
> +		show_rpm, NULL, 2);
> +static SENSOR_DEVICE_ATTR(fan3_input, 0444,
> +		show_rpm, NULL, 3);
> +static SENSOR_DEVICE_ATTR(fan4_input, 0444,
> +		show_rpm, NULL, 4);
> +static SENSOR_DEVICE_ATTR(fan5_input, 0444,
> +		show_rpm, NULL, 5);
> +static SENSOR_DEVICE_ATTR(fan6_input, 0444,
> +		show_rpm, NULL, 6);
> +static SENSOR_DEVICE_ATTR(fan7_input, 0444,
> +		show_rpm, NULL, 7);
> +static SENSOR_DEVICE_ATTR(fan8_input, 0444,
> +		show_rpm, NULL, 8);
> +static SENSOR_DEVICE_ATTR(fan9_input, 0444,
> +		show_rpm, NULL, 9);
> +static SENSOR_DEVICE_ATTR(fan10_input, 0444,
> +		show_rpm, NULL, 10);
> +static SENSOR_DEVICE_ATTR(fan11_input, 0444,
> +		show_rpm, NULL, 11);
> +static SENSOR_DEVICE_ATTR(fan12_input, 0444,
> +		show_rpm, NULL, 12);
> +static SENSOR_DEVICE_ATTR(fan13_input, 0444,
> +		show_rpm, NULL, 13);
> +static SENSOR_DEVICE_ATTR(fan14_input, 0444,
> +		show_rpm, NULL, 14);
> +static SENSOR_DEVICE_ATTR(fan15_input, 0444,
> +		show_rpm, NULL, 15);
> +
Unnecessary continuation lines.

> +static struct attribute *fan_dev_attrs[] = {
> +	&sensor_dev_attr_fan0_input.dev_attr.attr,
> +	&sensor_dev_attr_fan1_input.dev_attr.attr,
> +	&sensor_dev_attr_fan2_input.dev_attr.attr,
> +	&sensor_dev_attr_fan3_input.dev_attr.attr,
> +	&sensor_dev_attr_fan4_input.dev_attr.attr,
> +	&sensor_dev_attr_fan5_input.dev_attr.attr,
> +	&sensor_dev_attr_fan6_input.dev_attr.attr,
> +	&sensor_dev_attr_fan7_input.dev_attr.attr,
> +	&sensor_dev_attr_fan8_input.dev_attr.attr,
> +	&sensor_dev_attr_fan9_input.dev_attr.attr,
> +	&sensor_dev_attr_fan10_input.dev_attr.attr,
> +	&sensor_dev_attr_fan11_input.dev_attr.attr,
> +	&sensor_dev_attr_fan12_input.dev_attr.attr,
> +	&sensor_dev_attr_fan13_input.dev_attr.attr,
> +	&sensor_dev_attr_fan14_input.dev_attr.attr,
> +	&sensor_dev_attr_fan15_input.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group fan_dev_group = {
> +	.attrs = fan_dev_attrs,
> +	.is_visible = fan_dev_is_visible,
> +};
> +
> +/*
> + * The clock type is type M :
> + * The PWM frequency = 24MHz / (type M clock division L bit *
> + * type M clock division H bit * (type M PWM period bit + 1))
> + */
> +static void aspeed_create_type(struct aspeed_pwm_tacho_data *priv)
> +{
> +	priv->type_pwm_clock_division_h[TYPEM] = M_PWM_DIV_H;
> +	priv->type_pwm_clock_division_l[TYPEM] = M_PWM_DIV_L;
> +	priv->type_pwm_clock_unit[TYPEM] = M_PWM_PERIOD;
> +	aspeed_set_pwm_clock_values(priv->regmap, TYPEM, M_PWM_DIV_H,
> +				    M_PWM_DIV_L, M_PWM_PERIOD);
> +	aspeed_set_tacho_type_enable(priv->regmap, TYPEM, true);
> +	priv->type_fan_tach_clock_division[TYPEM] = M_TACH_CLK_DIV;
> +	priv->type_fan_tach_unit[TYPEM] = M_TACH_UNIT;
> +	aspeed_set_tacho_type_values(priv->regmap, TYPEM, M_TACH_MODE,
> +				     M_TACH_UNIT, M_TACH_CLK_DIV);
> +}
> +
> +static void aspeed_create_pwm_port(struct aspeed_pwm_tacho_data *priv,
> +				   u8 pwm_port)
> +{
> +	aspeed_set_pwm_port_enable(priv->regmap, pwm_port, true);
> +	priv->pwm_present[pwm_port] = true;
> +
> +	priv->pwm_port_type[pwm_port] = TYPEM;
> +	aspeed_set_pwm_port_type(priv->regmap, pwm_port, TYPEM);
> +
> +	priv->pwm_port_fan_ctrl[pwm_port] = INIT_FAN_CTRL;
> +	aspeed_set_pwm_port_fan_ctrl(priv, pwm_port, INIT_FAN_CTRL);
> +}
> +
> +static void aspeed_create_fan_tach_channel(struct aspeed_pwm_tacho_data *priv,
> +					   u8 *fan_tach_ch,
> +					   int count,
> +					   u8 pwm_source)
> +{
> +	u8 val, index;
> +
> +	for (val = 0; val < count; val++) {
> +		index = fan_tach_ch[val];
> +		aspeed_set_fan_tach_ch_enable(priv->regmap, index, true);
> +		priv->fan_tach_present[index] = true;
> +		priv->fan_tach_ch_source[index] = pwm_source;
> +		aspeed_set_fan_tach_ch_source(priv->regmap, index, pwm_source);
> +	}
> +}
> +
> +static int aspeed_create_fan(struct device *dev,
> +			     struct device_node *child,
> +			     struct aspeed_pwm_tacho_data *priv)
> +{
> +	u8 *fan_tach_ch;
> +	u32 pwm_port;
> +	int ret, count;
> +
> +	ret = of_property_read_u32(child, "reg", &pwm_port);
> +	if (ret)
> +		return ret;
> +	aspeed_create_pwm_port(priv, (u8)pwm_port);
> +
> +	count = of_property_count_u8_elems(child, "aspeed-fan-tach-ch");
> +	if (count < 1)
> +		return -EINVAL;
> +	fan_tach_ch = devm_kzalloc(dev, sizeof(*fan_tach_ch) * count,
> +				   GFP_KERNEL);
> +	if (!fan_tach_ch)
> +		return -ENOMEM;
> +	ret = of_property_read_u8_array(child, "aspeed-fan-tach-ch",
> +					fan_tach_ch, count);
> +	if (ret)
> +		return ret;
> +	aspeed_create_fan_tach_channel(priv, fan_tach_ch, count, pwm_port);
> +
> +	return 0;
> +}
> +
> +static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np, *child;
> +	struct aspeed_pwm_tacho_data *priv;
> +	struct aspeed_pwm_tacho_regmap *hregmap;
> +	struct resource *res;
> +	struct device *hwmon;
> +	struct clk *clk;
> +	int ret;
> +
> +	np = dev->of_node;
> +
> +	hregmap = devm_kzalloc(dev, sizeof(*hregmap), GFP_KERNEL);
> +	if (!hregmap)
> +		return -ENOMEM;
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENOENT;
> +	hregmap->regs = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(hregmap->regs))
> +		return PTR_ERR(hregmap->regs);
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +	priv->regmap = devm_regmap_init(dev, NULL, hregmap,
> +			&aspeed_pwm_tacho_regmap_config);
> +	if (IS_ERR(priv->regmap))
> +		return PTR_ERR(priv->regmap);
> +	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE, 0);
> +	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE_EXT, 0);
> +
> +	clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(clk))
> +		return -ENODEV;
> +	priv->clk_freq = clk_get_rate(clk);
> +	aspeed_set_clock_enable(priv->regmap, true);
> +	aspeed_set_clock_source(priv->regmap, 0);
> +
> +	aspeed_create_type(priv);
> +
> +	for_each_child_of_node(np, child) {
> +		ret = aspeed_create_fan(dev, child, priv);
> +		of_node_put(child);
> +		if (ret)
> +			return ret;
> +	}
> +	of_node_put(np);
> +
> +	priv->groups[0] = &pwm_dev_group;
> +	priv->groups[1] = &fan_dev_group;
> +	hwmon = devm_hwmon_device_register_with_groups(dev,
> +						       "aspeed_pwm_tacho",
> +						       priv, priv->groups);
> +
> +	return PTR_ERR_OR_ZERO(hwmon);
> +}
> +
> +static const struct of_device_id of_pwm_tacho_match_table[] = {
> +	{ .compatible = "aspeed,ast2400-pwm-tacho", },
> +	{ .compatible = "aspeed,ast2500-pwm-tacho", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, of_pwm_tacho_match_table);
> +
> +static struct platform_driver aspeed_pwm_tacho_driver = {
> +	.probe		= aspeed_pwm_tacho_probe,
> +	.driver		= {
> +		.name	= "aspeed_pwm_tacho",
> +		.of_match_table = of_pwm_tacho_match_table,
> +	},
> +};
> +
> +module_platform_driver(aspeed_pwm_tacho_driver);
> +
> +MODULE_AUTHOR("Jaghathiswari Rankappagounder Natarajan <jaghu-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>");
> +MODULE_DESCRIPTION("ASPEED PWM and Fan Tacho device driver");
> +MODULE_LICENSE("GPL");
> --
> 2.12.1.578.ge9c3154ca4-goog
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH V4 1/2] dt-bindings: thermal: add support for Broadcom's Northstar thermal
From: Eduardo Valentin @ 2017-04-02  4:13 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Florian Fainelli, Jon Mason, Zhang Rui, Rob Herring, Mark Rutland,
	Stephen Warren, Lee Jones, Eric Anholt, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Rafał Miłecki
In-Reply-To: <6dd907e4-c213-3174-8613-99427e6ea0e9-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Hey,

On Sat, Apr 01, 2017 at 11:50:26PM +0200, Rafał Miłecki wrote:
> On 04/01/2017 09:51 PM, Eduardo Valentin wrote:
> >On Fri, Mar 31, 2017 at 10:11:23PM +0200, Rafał Miłecki wrote:
> >>From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
> >>
> >>This commit documents binding for thermal used in Northstar family SoCs.
> >>
> >>Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
> >>---
> >>V3: Add thermal-zones to the example
> >>    Rob: Because of this update, I didn't include Acked-by I got for V2
> >>---
> >> .../devicetree/bindings/thermal/brcm,ns-thermal    | 26 ++++++++++++++++++++++
> >> 1 file changed, 26 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> >>
> >>diff --git a/Documentation/devicetree/bindings/thermal/brcm,ns-thermal b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> >>new file mode 100644
> >>index 000000000000..c561c7349f17
> >>--- /dev/null
> >>+++ b/Documentation/devicetree/bindings/thermal/brcm,ns-thermal
> >>@@ -0,0 +1,26 @@
> >>+* Broadcom Northstar Thermal
> >>+
> >>+This binding describes thermal sensor that is part of Northstar's DMU (Device
> >>+Management Unit).
> >>+
> >>+Required properties:
> >>+- compatible : Must be "brcm,ns-thermal"
> >>+- reg : iomem address range of PVTMON registers
> >>+- #thermal-sensor-cells : Should be <0>
> >>+
> >>+Example:
> >>+
> >>+thermal: thermal@1800c2c0 {
> >>+	compatible = "brcm,ns-thermal";
> >>+	reg = <0x1800c2c0 0x10>;
> >>+	#thermal-sensor-cells = <0>;
> >>+};
> >>+
> >>+thermal-zones {
> >>+	cpu_thermal: cpu-thermal {
> >>+		polling-delay-passive = <0>;
> >>+		polling-delay = <1000>;
> >>+		coefficients = <(-556) 418000>;
> >>+		thermal-sensors = <&thermal>;
> >
> >You need to define trips and cooling devices here. Otherwise, makes
> >little sense to have this device in thermal subsystem. Here is an
> >example of minimal set:
> >https://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git/commit/?h=linus&id=1e2ac9821de6a85d3e8358f238436708d1d46869
> >
> >The above has no passive action. It is just gonna shutdown the system if
> >temperature crosses a threshold.
> >
> >But, a typical cooling device would be CPU frequency throttling. Do you have
> >that up and running in your routers?
> 
> I don't have CPU freq throttling, so shutdown will be the only solution for
> critical temp right now.

OK. Is there any plans to get cpu cooling / DVFS working on your boards?

> 
> I know I should have at least a trip for critical temperature, but the problem
> is I don't know what value to use. There isn't any info about this in public

And that is enough justification to block this to go upstream. We need
the correct shutdown threshold value to put as example. If we don't,
users of this drivers will be pretty much guessing.

> datasheets. Broadcom's SDK doesn't mention it. Vendors share only the max
> environment temp, not the max CPU temp.

Silicon goes bad typically at 125C. But that also typically requires a
good extrapolation of hotspot(s). Some drivers prefer to play safer and
use lower numbers (100C).

> 
> So for now I only meant to provide user space access to reading current CPU
> temperature. I could do some stress tests and ask other users to do it as well.
> 

I see..


> Or maybe I could just put in Documentation some round value that makes more or
> less sense and then work on a proper content of real DTS files?
> 

The problem with the above is that I see very commonly examples being
copied into DTS. So, better to have a good binding
example/documentation. That is what they are for anyway.

> Unless we can get some hint from Broadcom people. Jon? Florian? Anyone?
> 

Yeah, that would be probably best.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 0/5] Add ARM Mali Midgard device tree bindings and gpu node for rk3288
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Sjoerd Simons, Enric Balletbo i Serra, John Reitan, Wookey,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guillaume Tucker

The ARM Mali Midgard GPU kernel driver is only available
out-of-tree and is not going to be merged in its current form.
However, it would be useful to have its device tree bindings
merged.  In particular, this would enable distributions to create
working driver packages (dkms...) without having to patch the
kernel.

The bindings for the earlier Mali Utgard GPU family have already
been merged, so this is essentially the same scenario but for
newer GPUs (Mali-T604 ~ Mali-T880).

This series of patches first imports the bindings from the latest
driver release with some clean-up then adds a gpu node for the
rk3288 SoC.  This was successfully tested on Radxa Rock2 Square,
Firefly, Veyron Minnie and Jerry boards board using Mali kernel
driver r16p0 and r12p0 user-space binary.

Changes since v1:
- enabled gpu on rk3288-veyron boards

Enric Balletbo i Serra (1):
  ARM: dts: rockchip: enable ARM Mali GPU on rk3288-veyron

Guillaume Tucker (4):
  dt-bindings: gpu: add bindings for the ARM Mali Midgard GPU
  ARM: dts: rockchip: add ARM Mali GPU node for rk3288
  ARM: dts: rockchip: enable ARM Mali GPU on rk3288-rock2-som
  ARM: dts: rockchip: enable ARM Mali GPU on rk3288-firefly

 .../devicetree/bindings/gpu/arm,mali-midgard.txt   | 53 ++++++++++++++++++++++
 arch/arm/boot/dts/rk3288-firefly.dtsi              |  5 ++
 arch/arm/boot/dts/rk3288-rock2-som.dtsi            |  5 ++
 arch/arm/boot/dts/rk3288-veyron.dtsi               |  5 ++
 arch/arm/boot/dts/rk3288.dtsi                      | 23 ++++++++++
 5 files changed, 91 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt

--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 1/5] dt-bindings: gpu: add bindings for the ARM Mali Midgard GPU
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Sjoerd Simons, Enric Balletbo i Serra, John Reitan, Wookey,
	devicetree, linux-rockchip, linux-arm-kernel, linux-kernel,
	Guillaume Tucker
In-Reply-To: <cover.1491118230.git.guillaume.tucker@collabora.com>

The ARM Mali Midgard GPU family is present in a number of SoCs
from many different vendors such as Samsung Exynos and Rockchip.

Import the device tree bindings documentation from the r16p0
release of the Mali Midgard GPU kernel driver:

  https://developer.arm.com/-/media/Files/downloads/mali-drivers/kernel/mali-midgard-gpu/TX011-SW-99002-r16p0-00rel0.tgz

The following optional bindings have been omitted in this initial
version as they are only used in very specific cases:

  * snoop_enable_smc
  * snoop_disable_smc
  * jm_config
  * power_model
  * system-coherency
  * ipa-model

The example has been simplified accordingly.

The compatible string definition has been limited to
"arm,mali-midgard" to avoid checkpatch.pl warnings and to match
what the driver actually expects (as of r16p0 out-of-tree).

CC: John Reitan <john.reitan@arm.com>
Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
---
 .../devicetree/bindings/gpu/arm,mali-midgard.txt   | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt

diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
new file mode 100644
index 000000000000..da8fc6d21bbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
@@ -0,0 +1,53 @@
+#
+# (C) COPYRIGHT 2013-2016 ARM Limited.
+# Copyright (C) 2017 Collabora Ltd
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+
+
+ARM Mali Midgard GPU
+====================
+
+Required properties:
+
+- compatible : Should be "arm,mali-midgard".
+- reg : Physical base address of the device and length of the register area.
+- interrupts : Contains the three IRQ lines required by Mali Midgard devices.
+- interrupt-names : Contains the names of IRQ resources in the order they were
+  provided in the interrupts property. Must contain: "JOB, "MMU", "GPU".
+
+Optional:
+
+- clocks : Phandle to clock for the Mali Midgard device.
+- clock-names : Shall be "clk_mali".
+- mali-supply : Phandle to regulator for the Mali device. Refer to
+  Documentation/devicetree/bindings/regulator/regulator.txt for details.
+- operating-points : Refer to Documentation/devicetree/bindings/power/opp.txt
+  for details.
+
+Example for a Mali-T602:
+
+gpu@0xfc010000 {
+	compatible = "arm,mali-midgard";
+	reg = <0xfc010000 0x4000>;
+	interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
+	interrupt-names = "JOB", "MMU", "GPU";
+
+	clocks = <&pclk_mali>;
+	clock-names = "clk_mali";
+	mali-supply = <&vdd_mali>;
+	operating-points = <
+		/* KHz   uV */
+		533000 1250000,
+		450000 1150000,
+		400000 1125000,
+		350000 1075000,
+		266000 1025000,
+		160000  925000,
+		100000  912500,
+	>;
+};
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 2/5] ARM: dts: rockchip: add ARM Mali GPU node for rk3288
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: devicetree, Guillaume Tucker, Sjoerd Simons, Wookey, linux-kernel,
	linux-rockchip, John Reitan, Enric Balletbo i Serra,
	linux-arm-kernel
In-Reply-To: <cover.1491118230.git.guillaume.tucker@collabora.com>

Add Mali GPU device tree node for the rk3288 SoC, with devfreq
opp table.

Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
---
 arch/arm/boot/dts/rk3288.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index df8a0dbe9d91..213224ea309e 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -43,6 +43,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/clock/rk3288-cru.h>
+#include <dt-bindings/power/rk3288-power.h>
 #include <dt-bindings/thermal/thermal.h>
 #include <dt-bindings/power/rk3288-power.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
@@ -227,6 +228,28 @@
 		ports = <&vopl_out>, <&vopb_out>;
 	};
 
+	gpu: mali@ffa30000 {
+		compatible = "arm,mali-midgard";
+		reg = <0xffa30000 0x10000>;
+		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "JOB", "MMU", "GPU";
+		clocks = <&cru ACLK_GPU>;
+		clock-names = "clk_mali";
+		operating-points = <
+			/* KHz uV */
+			100000 950000
+			200000 950000
+			300000 1000000
+			400000 1100000
+			500000 1200000
+			600000 1250000
+		>;
+		power-domains = <&power RK3288_PD_GPU>;
+		status = "disabled";
+	};
+
 	sdmmc: dwmmc@ff0c0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		max-frequency = <150000000>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 3/5] ARM: dts: rockchip: enable ARM Mali GPU on rk3288-rock2-som
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Sjoerd Simons, Enric Balletbo i Serra, John Reitan, Wookey,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guillaume Tucker
In-Reply-To: <cover.1491118230.git.guillaume.tucker-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>

Add reference to the Mali GPU device tree node on the
rk3288-rock2-som platform.  Tested on a Radxa Rock2 Square board.

Signed-off-by: Guillaume Tucker <guillaume.tucker-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
---
 arch/arm/boot/dts/rk3288-rock2-som.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
index 1c0bbc9b928b..f694867fa46a 100644
--- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi
+++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi
@@ -301,3 +301,8 @@
 &wdt {
 	status = "okay";
 };
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 4/5] ARM: dts: rockchip: enable ARM Mali GPU on rk3288-firefly
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: devicetree, Guillaume Tucker, Sjoerd Simons, Wookey, linux-kernel,
	linux-rockchip, John Reitan, Enric Balletbo i Serra,
	linux-arm-kernel
In-Reply-To: <cover.1491118230.git.guillaume.tucker@collabora.com>

Add reference to the Mali GPU device tree node on rk3288-firefly.
Tested on Firefly board.

Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
---
 arch/arm/boot/dts/rk3288-firefly.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
index 10793ac18599..f520589493b4 100644
--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
@@ -594,3 +594,8 @@
 &wdt {
 	status = "okay";
 };
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 5/5] ARM: dts: rockchip: enable ARM Mali GPU on rk3288-veyron
From: Guillaume Tucker @ 2017-04-02  7:59 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Sjoerd Simons, Enric Balletbo i Serra, John Reitan, Wookey,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Guillaume Tucker
In-Reply-To: <cover.1491118230.git.guillaume.tucker-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>

From: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>

Add reference to the Mali GPU device tree node on rk3288-veyron.
Tested on Minnie and Jerry boards.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
Signed-off-by: Guillaume Tucker <guillaume.tucker-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
---
 arch/arm/boot/dts/rk3288-veyron.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
index 5d1eb0a25827..9847d5c6db3b 100644
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
@@ -447,6 +447,11 @@
 	status = "okay";
 };
 
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
 &wdt {
 	status = "okay";
 };
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH v2 2/2] iio: adc: stm32: add dt option to set resolution
From: Jonathan Cameron @ 2017-04-02  8:54 UTC (permalink / raw)
  To: Fabrice Gasnier, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, mark.rutland-5wv7dgnIgG8,
	mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w,
	alexandre.torgue-qxv4g6HH51o, lars-Qo5EllUWu/uELgA04lAiVw,
	knaack.h-Mmb7MZpHnFY, pmeerw-jW+XmwGofnusTnJN9+BGXg,
	benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A,
	benjamin.gaignard-qxv4g6HH51o,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1490963559-32159-3-git-send-email-fabrice.gasnier-qxv4g6HH51o@public.gmane.org>

On 31/03/17 13:32, Fabrice Gasnier wrote:
> stm32 adc supports several resolution. Add 'assigned-resolution-bits'
> dt optional property to set it. Default to maximum resolution in case
> it isn't set.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier-qxv4g6HH51o@public.gmane.org>
The code is fine.  Just waiting on review of the binding.

Give me a poke if I seem to have dropped this in a week or two.

Thanks,

Jonathan
> ---
> Changes in v2:
> - rename property from 'st,adc-res' to 'assigned-resolution-bits', so it
>   is more common.
> ---
>  drivers/iio/adc/stm32-adc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index 9b49a6ad..c28e7ff 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -60,6 +60,8 @@
>  #define STM32F4_EOC			BIT(1)
>  
>  /* STM32F4_ADC_CR1 - bit fields */
> +#define STM32F4_RES_SHIFT		24
> +#define STM32F4_RES_MASK		GENMASK(25, 24)
>  #define STM32F4_SCAN			BIT(8)
>  #define STM32F4_EOCIE			BIT(5)
>  
> @@ -141,6 +143,7 @@ struct stm32_adc_regs {
>   * @lock:		spinlock
>   * @bufi:		data buffer index
>   * @num_conv:		expected number of scan conversions
> + * @res:		data resolution (e.g. RES bitfield value)
>   * @trigger_polarity:	external trigger polarity (e.g. exten)
>   * @dma_chan:		dma channel
>   * @rx_buf:		dma rx buffer cpu address
> @@ -157,6 +160,7 @@ struct stm32_adc {
>  	spinlock_t		lock;		/* interrupt lock */
>  	unsigned int		bufi;
>  	unsigned int		num_conv;
> +	u32			res;
>  	u32			trigger_polarity;
>  	struct dma_chan		*dma_chan;
>  	u8			*rx_buf;
> @@ -196,6 +200,11 @@ struct stm32_adc_chan_spec {
>  	{ IIO_VOLTAGE, 15, "in15" },
>  };
>  
> +static const unsigned int stm32f4_adc_resolutions[] = {
> +	/* sorted values so the index matches RES[1:0] in STM32F4_ADC_CR1 */
> +	12, 10, 8, 6,
> +};
> +
>  /**
>   * stm32f4_sq - describe regular sequence registers
>   * - L: sequence len (register & bit field)
> @@ -302,6 +311,14 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc)
>  	stm32_adc_clr_bits(adc, STM32F4_ADC_CR1, STM32F4_EOCIE);
>  }
>  
> +static void stm32_adc_set_res(struct stm32_adc *adc)
> +{
> +	u32 val = stm32_adc_readl(adc, STM32F4_ADC_CR1);
> +
> +	val = (val & ~STM32F4_RES_MASK) | (adc->res << STM32F4_RES_SHIFT);
> +	stm32_adc_writel(adc, STM32F4_ADC_CR1, val);
> +}
> +
>  /**
>   * stm32_adc_start_conv() - Start conversions for regular channels.
>   * @adc: stm32 adc instance
> @@ -870,11 +887,37 @@ static irqreturn_t stm32_adc_trigger_handler(int irq, void *p)
>  	{},
>  };
>  
> +static int stm32_adc_of_get_resolution(struct iio_dev *indio_dev)
> +{
> +	struct device_node *node = indio_dev->dev.of_node;
> +	struct stm32_adc *adc = iio_priv(indio_dev);
> +	unsigned int i;
> +	u32 res;
> +
> +	if (of_property_read_u32(node, "assigned-resolution-bits", &res))
> +		res = stm32f4_adc_resolutions[0];
> +
> +	for (i = 0; i < ARRAY_SIZE(stm32f4_adc_resolutions); i++)
> +		if (res == stm32f4_adc_resolutions[i])
> +			break;
> +	if (i >= ARRAY_SIZE(stm32f4_adc_resolutions)) {
> +		dev_err(&indio_dev->dev, "Bad resolution: %u bits\n", res);
> +		return -EINVAL;
> +	}
> +
> +	dev_dbg(&indio_dev->dev, "Using %u bits resolution\n", res);
> +	adc->res = i;
> +
> +	return 0;
> +}
> +
>  static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
>  				    struct iio_chan_spec *chan,
>  				    const struct stm32_adc_chan_spec *channel,
>  				    int scan_index)
>  {
> +	struct stm32_adc *adc = iio_priv(indio_dev);
> +
>  	chan->type = channel->type;
>  	chan->channel = channel->channel;
>  	chan->datasheet_name = channel->name;
> @@ -883,7 +926,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
>  	chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
>  	chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
>  	chan->scan_type.sign = 'u';
> -	chan->scan_type.realbits = 12;
> +	chan->scan_type.realbits = stm32f4_adc_resolutions[adc->res];
>  	chan->scan_type.storagebits = 16;
>  	chan->ext_info = stm32_adc_ext_info;
>  }
> @@ -1022,6 +1065,11 @@ static int stm32_adc_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	ret = stm32_adc_of_get_resolution(indio_dev);
> +	if (ret < 0)
> +		goto err_clk_disable;
> +	stm32_adc_set_res(adc);
> +
>  	ret = stm32_adc_chan_of_init(indio_dev);
>  	if (ret < 0)
>  		goto err_clk_disable;
> 

^ permalink raw reply

* Re: [PATCH v4 1/6] dt-bindings: iio: rockchip-saradc: add support for rk3328
From: Jonathan Cameron @ 2017-04-02  8:58 UTC (permalink / raw)
  To: Heiko Stuebner, cl-TNX95d0MmH7DzftRWevZcw
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	zhengxing-TNX95d0MmH7DzftRWevZcw, andy.yan-TNX95d0MmH7DzftRWevZcw,
	jay.xu-TNX95d0MmH7DzftRWevZcw,
	matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w,
	paweljarosz3691-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, knaack.h-Mmb7MZpHnFY,
	lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
	wxt-TNX95d0MmH7DzftRWevZcw, david.wu-TNX95d0MmH7DzftRWevZcw,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	shawn.lin-TNX95d0MmH7DzftRWevZcw,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dianders-F7+t8E8rja9g9hUCZPvPmw,
	yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	afaerber-l3A5Bk7waGM, shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
	khilman-rdvid1DuHRBWk0Htik3J/w, arnd-r2nGTMty4D4,
	fabio.estevam-3arQi8VN3Tc, zhangqing-TNX95d0MmH7DzftRWevZcw,
	kever.yang-TNX95d0MmH7DzftRWevZcw, tony.xie
In-Reply-To: <1940747.DLKBel529v@phil>

On 27/03/17 14:25, Heiko Stuebner wrote:
> Hi Jonathan,
> 
> Am Montag, 27. März 2017, 17:40:46 CEST schrieb cl-TNX95d0MmH7DzftRWevZcw@public.gmane.org:
>> From: Liang Chen <cl-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>>
>> The rk3328 saradc is the same as rk3399.
>>
>> Signed-off-by: Liang Chen <cl-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> Reviewed-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
>> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
> just for planning purposes, do you plan on picking this up or do you
> want me to queue it with the rest of the changes (Ack needed).

Applied to the togreg branch of iio.git.  Makes more sense that
way as we might get some other changes around that file and it
doesn't make any difference to the rest of the series.

Will probably start it's way upstream this afternoon if I get
through the rest of my backlog.

Thanks,

Jonathan
> 
> Heiko
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH 1/2] iio:imu:mpu6050 update i2c bindings to reflect i2c-gate and supported parts
From: Jonathan Cameron @ 2017-04-02  9:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mark.Rutland-5wv7dgnIgG8
In-Reply-To: <20170330230252.cxbdh3g744qwdtfh@rob-hp-laptop>

On 31/03/17 00:02, Rob Herring wrote:
> On Sun, Mar 26, 2017 at 12:10:59PM +0100, Jonathan Cameron wrote:
>> These bindings are somewhat lagging the state of the driver.  The i2c-gate
>> bindings are documented elsewhere, but it seems sensible to at least have
>> an example and cross reference in here.  SPI bindings will need to be the
>> subject of a future patch.
>>
>> Signed-off-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>>  .../devicetree/bindings/iio/imu/inv_mpu6050.txt    | 23 ++++++++++++++++++++--
>>  1 file changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
>> index a9fc11e43b45..e18e04f3c6f4 100644
>> --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
>> +++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
>> @@ -3,14 +3,17 @@ InvenSense MPU-6050 Six-Axis (Gyro + Accelerometer) MEMS MotionTracking Device
>>  http://www.invensense.com/mems/gyro/mpu6050.html
>>  
>>  Required properties:
>> - - compatible : should be "invensense,mpu6050"
>> + - compatible : should be "invensense,mpu6050", "invensense,mpu6500",
>> +   "invensense,mpu9150" or "invensense,icm20608"
> 
> One per line please. With that,
> 
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
Fixed and applied.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/2] iio:imu:mpu6050 add explicit mpu9250 support
From: Jonathan Cameron @ 2017-04-02  9:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mark.Rutland-5wv7dgnIgG8
In-Reply-To: <20170330231846.j45psrzast3pjc5b@rob-hp-laptop>

On 31/03/17 00:18, Rob Herring wrote:
> On Sun, Mar 26, 2017 at 12:11:00PM +0100, Jonathan Cameron wrote:
>> The mpu9250 is a SIP containing an mpu6500 and an ak8975.  If this was all
>> there was too it there would be no need for explicit handling in the driver.
>> Arguably the bindings would also only reflect the presence of an mpu6500 with
>> the ak8975 hanging off it, as the kernel doesn't care that they are in one
>> package.
>>
>> However, the WHOAMI value changes as well so best to add explicit support.
>>
>> Signed-off-by: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt | 2 +-
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_core.c                | 6 ++++++
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c                 | 5 +++++
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h                 | 2 ++
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c                 | 1 +
>>  5 files changed, 15 insertions(+), 1 deletion(-)
> 
> Same one per line comment, but
> 
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 
Fixed up and applied.  Thanks Rob.

Jonathan

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox