Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v5 6/9] coresight: add support for CPU debug module
From: Leo Yan @ 2017-03-29 10:27 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
	Catalin Marinas, Will Deacon, Andy Gross, David Brown,
	Michael Turquette, Stephen Boyd, Mathieu Poirier, Guodong Xu,
	John Stultz, linux-doc, linux-kernel, devicetree,
	linux-arm-kernel, linux-arm-msm, linux-soc, linux-clk, mike.leach,
	sudeep.holla
In-Reply-To: <5584203e-cb19-a5d2-45b1-3e78d3482c55@arm.com>

On Wed, Mar 29, 2017 at 10:07:07AM +0100, Suzuki K Poulose wrote:

[...]

> >>>+	if (mode == EDDEVID_IMPL_NONE) {
> >>>+		drvdata->edpcsr_present  = false;
> >>>+		drvdata->edcidsr_present = false;
> >>>+		drvdata->edvidsr_present = false;
> >>>+	} else if (mode == EDDEVID_IMPL_EDPCSR) {
> >>>+		drvdata->edpcsr_present  = true;
> >>>+		drvdata->edcidsr_present = false;
> >>>+		drvdata->edvidsr_present = false;
> >>>+	} else if (mode == EDDEVID_IMPL_EDPCSR_EDCIDSR) {
> >>>+		if (!IS_ENABLED(CONFIG_64BIT) &&
> >>>+			(pcsr_offset == EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32))
> >>>+			drvdata->edpcsr_present = false;
> >>>+		else
> >>>+			drvdata->edpcsr_present = true;
> >>
> >>Sorry, I forgot why we do this check only in this mode. Shouldn't this be
> >>common to all modes (of course which implies PCSR is present) ?
> >
> >No. PCSROffset is defined differently in ARMv7 and ARMv8; So finally we
> >simplize PCSROffset value :
> >0000 - Sample offset applies based on the instruction state (indicated by PCSR[0])
> >0001 - No offset applies.
> >0010 - No offset applies, but do not use in AArch32 mode!
> >
> >So we need handle the corner case is when CPU runs AArch32 mode and
> >PCSRoffset = 'b0010. Other cases the pcsr should be present.
> 
> I understand that reasoning. But my question is, why do we check for PCSROffset
> only when mode == EDDEVID_IMPL_EDPCSR_EDCIDSR and not for say mode == EDDEVID_IMPL_EDPCSR or
> any other mode where PCSR is present.

Sorry I misunderstood your question.

I made mistake when I analyzed the possbile combination for mode and
PCSROffset so I thought it's the only case should handle:
{ EDDEVID_IMPL_EDPCSR_EDCIDSR, EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }

Below three combinations are possible to exist; so you are right, I
should move this out for the checking:
{ EDDEVID_IMPL_NONE,           EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }
{ EDDEVID_IMPL_EDPCSR_EDCIDSR, EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }
{ EDDEVID_IMPL_FULL,           EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }

Thanks,
Leo Yan

^ permalink raw reply

* Re: [PATCH v5 6/9] coresight: add support for CPU debug module
From: Suzuki K Poulose @ 2017-03-29 10:31 UTC (permalink / raw)
  To: Leo Yan
  Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
	Catalin Marinas, Will Deacon, Andy Gross, David Brown,
	Michael Turquette, Stephen Boyd, Mathieu Poirier, Guodong Xu,
	John Stultz, linux-doc, linux-kernel, devicetree,
	linux-arm-kernel, linux-arm-msm, linux-soc, linux-clk, mike.leach,
	sudeep.holla
In-Reply-To: <20170329102740.GA20804@leoy-linaro>

On 29/03/17 11:27, Leo Yan wrote:
> On Wed, Mar 29, 2017 at 10:07:07AM +0100, Suzuki K Poulose wrote:
>
> [...]
>
>>>>> +	if (mode == EDDEVID_IMPL_NONE) {
>>>>> +		drvdata->edpcsr_present  = false;
>>>>> +		drvdata->edcidsr_present = false;
>>>>> +		drvdata->edvidsr_present = false;
>>>>> +	} else if (mode == EDDEVID_IMPL_EDPCSR) {
>>>>> +		drvdata->edpcsr_present  = true;
>>>>> +		drvdata->edcidsr_present = false;
>>>>> +		drvdata->edvidsr_present = false;
>>>>> +	} else if (mode == EDDEVID_IMPL_EDPCSR_EDCIDSR) {
>>>>> +		if (!IS_ENABLED(CONFIG_64BIT) &&
>>>>> +			(pcsr_offset == EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32))
>>>>> +			drvdata->edpcsr_present = false;
>>>>> +		else
>>>>> +			drvdata->edpcsr_present = true;
>>>>
>>>> Sorry, I forgot why we do this check only in this mode. Shouldn't this be
>>>> common to all modes (of course which implies PCSR is present) ?
>>>
>>> No. PCSROffset is defined differently in ARMv7 and ARMv8; So finally we
>>> simplize PCSROffset value :
>>> 0000 - Sample offset applies based on the instruction state (indicated by PCSR[0])
>>> 0001 - No offset applies.
>>> 0010 - No offset applies, but do not use in AArch32 mode!
>>>
>>> So we need handle the corner case is when CPU runs AArch32 mode and
>>> PCSRoffset = 'b0010. Other cases the pcsr should be present.
>>
>> I understand that reasoning. But my question is, why do we check for PCSROffset
>> only when mode == EDDEVID_IMPL_EDPCSR_EDCIDSR and not for say mode == EDDEVID_IMPL_EDPCSR or
>> any other mode where PCSR is present.
>
> Sorry I misunderstood your question.
>
> I made mistake when I analyzed the possbile combination for mode and
> PCSROffset so I thought it's the only case should handle:
> { EDDEVID_IMPL_EDPCSR_EDCIDSR, EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }
>
> Below three combinations are possible to exist; so you are right, I
> should move this out for the checking:
> { EDDEVID_IMPL_NONE,           EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }

That need not be covered, as IMPL_NONE says PCSR is not implemented hence you
don't worry about anything as the functionality is missing. This should rather be:
EDDEVID_IMPL_EDPCSR, where only PCSR is implemented.

My switch...case suggestion makes it easier to do all this checking.


Thanks
Suzuki

^ permalink raw reply

* [PATCH] ARM: dts: keystone-k2l: fix broken Ethernet due to disabled OSR
From: Sekhar Nori @ 2017-03-29 10:32 UTC (permalink / raw)
  To: Santosh Shilimkar
  Cc: Mark Rutland, devicetree, Russell King, linux-kernel, Tero Kristo,
	Rob Herring, Murali Karicheri, linux-arm-kernel

From: Murali Karicheri <m-karicheri2@ti.com>

Ethernet networking on K2L has been broken since v4.11-rc1. This was
caused by commit 32a34441a9bd ("ARM: keystone: dts: fix netcp clocks
and add names"). This commit inadvertently moves on-chip static RAM
clock to the end of list of clocks provided for netcp. Since keystone
PM domain support does not have a list of recognized con_ids, only the
first clock in the list comes under runtime PM management. This means
the OSR (On-chip Static RAM) clock remains disabled and that broke
networking on K2L.

The OSR is used by QMSS on K2L as an external linking RAM. However this
is a standalone RAM that can be used for non-QMSS usage (as well as from
DSP side). So add a SRAM device node for the same and add the OSR clock
to the node.

Remove the now redundant OSR clock node from netcp.

To manage all clocks defined for netCP's use by runtime PM needs keystone
generic power domain (genpd) driver support which is under works.
Meanwhile, this patch restores K2L networking and is correct irrespective
of any future genpd work since OSR is an independent module and not part
of NetCP anyway.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Acked-by: Tero Kristo <t-kristo@ti.com>
[nsekhar@ti.com: commit message updates, port to latest mainline]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
 arch/arm/boot/dts/keystone-k2l-netcp.dtsi | 4 ++--
 arch/arm/boot/dts/keystone-k2l.dtsi       | 8 ++++++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
index b6f26824e83a..66f615a74118 100644
--- a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
@@ -137,8 +137,8 @@ netcp: netcp@26000000 {
 	/* NetCP address range */
 	ranges = <0 0x26000000 0x1000000>;
 
-	clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>, <&clkosr>;
-	clock-names = "pa_clk", "ethss_clk", "cpts", "osr_clk";
+	clocks = <&clkpa>, <&clkcpgmac>, <&chipclk12>;
+	clock-names = "pa_clk", "ethss_clk", "cpts";
 	dma-coherent;
 
 	ti,navigator-dmas = <&dma_gbe 0>,
diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi
index b58e7ebc0919..148650406cf7 100644
--- a/arch/arm/boot/dts/keystone-k2l.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l.dtsi
@@ -232,6 +232,14 @@
 			};
 		};
 
+		osr: sram@70000000 {
+			compatible = "mmio-sram";
+			reg = <0x70000000 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clocks = <&clkosr>;
+		};
+
 		dspgpio0: keystone_dsp_gpio@02620240 {
 			compatible = "ti,keystone-dsp-gpio";
 			gpio-controller;
-- 
2.9.0

^ permalink raw reply related

* Re: [PATCH v6 1/5] irqchip/aspeed-i2c-ic: binding docs for Aspeed I2C Interrupt Controller
From: Brendan Higgins @ 2017-03-29 10:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Wolfram Sang, robh+dt, mark.rutland, tglx, jason, Marc Zyngier,
	Joel Stanley, Vladimir Zapolskiy, Kachalov Anton,
	Cédric Le Goater, linux-i2c, devicetree, linux-kernel,
	OpenBMC Maillist
In-Reply-To: <1490690980.3177.108.camel@kernel.crashing.org>

I think I addressed this on the other email with the actual driver.
Anyway, I thought that this is pretty much the dummy irqchip code is
for; I have seen some other drivers do the same thing. It is true that
this is a really basic "interrupt controller;" it cannot mask on its
own, etc; nevertheless, I think you will pretty much end up with the
same code for an "I2C controller;" it just won't use an irq_domain.

^ permalink raw reply

* Re: [PATCH v5 6/9] coresight: add support for CPU debug module
From: Leo Yan @ 2017-03-29 10:37 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
	Catalin Marinas, Will Deacon, Andy Gross, David Brown,
	Michael Turquette, Stephen Boyd, Mathieu Poirier, Guodong Xu,
	John Stultz, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-soc-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	mike.leach-QSEj5FYQhm4dnm+yROfE0A, sudeep.holla-5wv7dgnIgG8
In-Reply-To: <89b6c6c7-0da0-6891-312a-c9221851c20a-5wv7dgnIgG8@public.gmane.org>

On Wed, Mar 29, 2017 at 11:31:03AM +0100, Suzuki K Poulose wrote:
> On 29/03/17 11:27, Leo Yan wrote:
> >On Wed, Mar 29, 2017 at 10:07:07AM +0100, Suzuki K Poulose wrote:
> >
> >[...]
> >
> >>>>>+	if (mode == EDDEVID_IMPL_NONE) {
> >>>>>+		drvdata->edpcsr_present  = false;
> >>>>>+		drvdata->edcidsr_present = false;
> >>>>>+		drvdata->edvidsr_present = false;
> >>>>>+	} else if (mode == EDDEVID_IMPL_EDPCSR) {
> >>>>>+		drvdata->edpcsr_present  = true;
> >>>>>+		drvdata->edcidsr_present = false;
> >>>>>+		drvdata->edvidsr_present = false;
> >>>>>+	} else if (mode == EDDEVID_IMPL_EDPCSR_EDCIDSR) {
> >>>>>+		if (!IS_ENABLED(CONFIG_64BIT) &&
> >>>>>+			(pcsr_offset == EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32))
> >>>>>+			drvdata->edpcsr_present = false;
> >>>>>+		else
> >>>>>+			drvdata->edpcsr_present = true;
> >>>>
> >>>>Sorry, I forgot why we do this check only in this mode. Shouldn't this be
> >>>>common to all modes (of course which implies PCSR is present) ?
> >>>
> >>>No. PCSROffset is defined differently in ARMv7 and ARMv8; So finally we
> >>>simplize PCSROffset value :
> >>>0000 - Sample offset applies based on the instruction state (indicated by PCSR[0])
> >>>0001 - No offset applies.
> >>>0010 - No offset applies, but do not use in AArch32 mode!
> >>>
> >>>So we need handle the corner case is when CPU runs AArch32 mode and
> >>>PCSRoffset = 'b0010. Other cases the pcsr should be present.
> >>
> >>I understand that reasoning. But my question is, why do we check for PCSROffset
> >>only when mode == EDDEVID_IMPL_EDPCSR_EDCIDSR and not for say mode == EDDEVID_IMPL_EDPCSR or
> >>any other mode where PCSR is present.
> >
> >Sorry I misunderstood your question.
> >
> >I made mistake when I analyzed the possbile combination for mode and
> >PCSROffset so I thought it's the only case should handle:
> >{ EDDEVID_IMPL_EDPCSR_EDCIDSR, EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }
> >
> >Below three combinations are possible to exist; so you are right, I
> >should move this out for the checking:
> >{ EDDEVID_IMPL_NONE,           EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 }
> 
> That need not be covered, as IMPL_NONE says PCSR is not implemented hence you
> don't worry about anything as the functionality is missing. This should rather be:
> EDDEVID_IMPL_EDPCSR, where only PCSR is implemented.

I think below combination doesn't really exist:
{ EDDEVID_IMPL_EDPCSR, EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 };

EDDEVID_IMPL_EDPCSR is only defined in ARMv7 ARM, and
EDDEVID1_PCSR_NO_OFFSET_DIS_AARCH32 is only defined in ARMv8 ARM.

> My switch...case suggestion makes it easier to do all this checking.

Agree. Will do this.

Thanks,
Leo Yan
--
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 v3 0/5] Add support for the R_CCU on Allwinner H3/A64 SoCs
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng

Allwinner SoCs after sun6i-a31 nearly all have a R_CCU in PRCM part.
(V3s and R40 do not have it, as they have even no PRCM)

This patch adds support for the ones on H3/A64.

Some clock/reset values are reserved for easier extending the support to
A31/A23, but for this I think some changes to the PRCM MFD should be made,
see [1] (Although this is only a sketch).

The r_pio device node is also added for A64, as the driver is already
merged, and its depends (r_ccu) is now met.

[1] https://github.com/wens/linux/commits/sunxi-ng-prcm

Icenowy Zheng (5):
  dt-bindings: update device tree binding for Allwinner PRCM CCUs
  clk: sunxi-ng: add support for PRCM CCUs
  arm64: allwinner: a64: add r_ccu node
  ARM: sunxi: h3/h5: switch apb0-related clocks to r_ccu
  arm64: allwinner: a64: add R_PIO pinctrl node

 .../devicetree/bindings/clock/sunxi-ccu.txt        |  17 +-
 arch/arm/boot/dts/sunxi-h3-h5.dtsi                 |  47 ++---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi      |  31 +++
 drivers/clk/sunxi-ng/Kconfig                       |   6 +
 drivers/clk/sunxi-ng/Makefile                      |   1 +
 drivers/clk/sunxi-ng/ccu-sun8i-r.c                 | 211 +++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun8i-r.h                 |  27 +++
 include/dt-bindings/clock/sun8i-r-ccu.h            |  59 ++++++
 include/dt-bindings/reset/sun8i-r-ccu.h            |  53 ++++++
 9 files changed, 420 insertions(+), 32 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.h
 create mode 100644 include/dt-bindings/clock/sun8i-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-r-ccu.h

-- 
2.12.0

^ permalink raw reply

* [PATCH v3 1/5] dt-bindings: update device tree binding for Allwinner PRCM CCUs
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Many Allwinner SoCs after A31 have a CCU in PRCM block.

Give the ones on H3 and A64 compatible strings.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Removed frequency info of iosc in this device tree binding document.
Changes in v2:
- Add iosc for R_CCU's on H3/A64.

 Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index 68512aa398a9..e9c5a1d9834a 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -7,9 +7,11 @@ Required properties :
 		- "allwinner,sun8i-a23-ccu"
 		- "allwinner,sun8i-a33-ccu"
 		- "allwinner,sun8i-h3-ccu"
+		- "allwinner,sun8i-h3-r-ccu"
 		- "allwinner,sun8i-v3s-ccu"
 		- "allwinner,sun9i-a80-ccu"
 		- "allwinner,sun50i-a64-ccu"
+		- "allwinner,sun50i-a64-r-ccu"
 		- "allwinner,sun50i-h5-ccu"
 
 - reg: Must contain the registers base address and length
@@ -20,7 +22,10 @@ Required properties :
 - #clock-cells : must contain 1
 - #reset-cells : must contain 1
 
-Example:
+For the PRCM CCUs on H3/A64, one more clock is needed:
+- "iosc": the SoC's internal frequency oscillator
+
+Example for generic CCU:
 ccu: clock@01c20000 {
 	compatible = "allwinner,sun8i-h3-ccu";
 	reg = <0x01c20000 0x400>;
@@ -29,3 +34,13 @@ ccu: clock@01c20000 {
 	#clock-cells = <1>;
 	#reset-cells = <1>;
 };
+
+Example for PRCM CCU:
+r_ccu: clock@01f01400 {
+	compatible = "allwinner,sun50i-a64-r-ccu";
+	reg = <0x01f01400 0x100>;
+	clocks = <&osc24M>, <&osc32k>, <&iosc>;
+	clock-names = "hosc", "losc", "iosc";
+	#clock-cells = <1>;
+	#reset-cells = <1>;
+};
-- 
2.12.0

^ permalink raw reply related

* [PATCH v3 2/5] clk: sunxi-ng: add support for PRCM CCUs
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

SoCs after A31 has a clock controller module in the PRCM part.

Support the clock controller module on H3/5 and A64 now.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 mux to iosc, as its frequency varies between SoCs. (And
  none of them is really 32000Hz)
Changes in v2:
- Replace all sun6i to sun8i, as this driver currently doesn't really
  support sun6i(A31).
- Add osc32000 mux for ar100 clk. (Note: the frequency is proven to be wrong
  during the development of PATCH v3).
- Rename some clocks.
- Add gate of TWD (Trusted Watchdog). There's no reset for TWD.
- Removed reset of PIO, which doesn't exist really.

 drivers/clk/sunxi-ng/Kconfig            |   6 +
 drivers/clk/sunxi-ng/Makefile           |   1 +
 drivers/clk/sunxi-ng/ccu-sun8i-r.c      | 211 ++++++++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun8i-r.h      |  27 ++++
 include/dt-bindings/clock/sun8i-r-ccu.h |  59 +++++++++
 include/dt-bindings/reset/sun8i-r-ccu.h |  53 ++++++++
 6 files changed, 357 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.h
 create mode 100644 include/dt-bindings/clock/sun8i-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun8i-r-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8af8f4be8e3b..fbd3f8cd5c22 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -151,4 +151,10 @@ config SUN9I_A80_CCU
 	default MACH_SUN9I
 	depends on MACH_SUN9I || COMPILE_TEST
 
+config SUN8I_R_CCU
+	bool "Support for Allwinner SoCs' PRCM CCUs"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_GATE
+	default MACH_SUN8I || (ARCH_SUNXI && ARM64)
+
 endif
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 6feaac0c5600..0ec02fe14c50 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
 obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
 obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
+obj-$(CONFIG_SUN8I_R_CCU)	+= ccu-sun8i-r.o
 obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80.o
 obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-de.o
 obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
new file mode 100644
index 000000000000..ddbb34018086
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun8i-r.h"
+
+static const char * const ar100_parents[] = { "osc32k", "osc24M",
+					     "pll-periph0", "iosc" };
+
+static struct ccu_div ar100_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.mux		= {
+		.shift	= 16,
+		.width	= 2,
+
+		.variable_prediv	= {
+			.index	= 2,
+			.shift	= 8,
+			.width	= 5,
+		},
+	},
+
+	.common		= {
+		.reg		= 0x00,
+		.features	= CCU_FEATURE_VARIABLE_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
+						      ar100_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
+
+static struct ccu_div apb0_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.common		= {
+		.reg		= 0x0c,
+		.hw.init	= CLK_HW_INIT("apb0",
+					      "ahb0",
+					      &ccu_div_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
+		      0x28, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
+		      0x28, BIT(1), 0);
+static SUNXI_CCU_GATE(apb0_timer_clk,	"apb0-timer",	"apb0",
+		      0x28, BIT(2), 0);
+static SUNXI_CCU_GATE(apb0_rsb_clk,	"apb0-rsb",	"apb0",
+		      0x28, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_uart_clk,	"apb0-uart",	"apb0",
+		      0x28, BIT(4), 0);
+static SUNXI_CCU_GATE(apb0_i2c_clk,	"apb0-i2c",	"apb0",
+		      0x28, BIT(6), 0);
+static SUNXI_CCU_GATE(apb0_twd_clk,	"apb0-twd",	"apb0",
+		      0x28, BIT(7), 0);
+
+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
+				  r_mod0_default_parents, 0x54,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
+	&ar100_clk.common,
+	&apb0_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb0_timer_clk.common,
+	&apb0_uart_clk.common,
+	&apb0_i2c_clk.common,
+	&ir_clk.common,
+};
+
+static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
+	&ar100_clk.common,
+	&apb0_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb0_timer_clk.common,
+	&apb0_rsb_clk.common,
+	&apb0_uart_clk.common,
+	&apb0_i2c_clk.common,
+	&ir_clk.common,
+};
+
+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
+	.hws	= {
+		[CLK_AR100]		= &ar100_clk.common.hw,
+		[CLK_AHB0]		= &ahb0_clk.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
+	.hws	= {
+		[CLK_AR100]		= &ar100_clk.common.hw,
+		[CLK_AHB0]		= &ahb0_clk.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
+		[CLK_APB0_RSB]		= &apb0_rsb_clk.common.hw,
+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
+};
+
+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
+	[RST_APB0_RSB]		=  { 0xb0, BIT(3) },
+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
+};
+
+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
+	.ccu_clks	= sun8i_h3_r_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun8i_h3_r_ccu_clks),
+
+	.hw_clks	= &sun8i_h3_r_hw_clks,
+
+	.resets		= sun8i_h3_r_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun8i_h3_r_ccu_resets),
+};
+
+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
+	.ccu_clks	= sun50i_a64_r_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_a64_r_ccu_clks),
+
+	.hw_clks	= &sun50i_a64_r_hw_clks,
+
+	.resets		= sun50i_a64_r_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_a64_r_ccu_resets),
+};
+
+static void __init sunxi_r_ccu_init(struct device_node *node,
+				    const struct sunxi_ccu_desc *desc)
+{
+	void __iomem *reg;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	sunxi_ccu_probe(node, reg, desc);
+}
+
+static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
+{
+	sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
+	       sun8i_h3_r_ccu_setup);
+
+static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
+{
+	sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
+	       sun50i_a64_r_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
new file mode 100644
index 000000000000..eaa431fd1d8f
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 Icenowy <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * 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.
+ */
+
+#ifndef _CCU_SUN8I_R_H
+#define _CCU_SUN8I_R_H_
+
+#include <dt-bindings/clock/sun8i-r-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
+
+/* AHB/APB bus clocks are not exported */
+#define CLK_AHB0	1
+#define CLK_APB0	2
+
+#define CLK_NUMBER	(CLK_APB0_TWD + 1)
+
+#endif /* _CCU_SUN8I_R_H */
diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h
new file mode 100644
index 000000000000..779d20aa0d05
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-r-ccu.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+
+#define CLK_AR100		0
+
+#define CLK_APB0_PIO		3
+#define CLK_APB0_IR		4
+#define CLK_APB0_TIMER		5
+#define CLK_APB0_RSB		6
+#define CLK_APB0_UART		7
+/* 8 is reserved for CLK_APB0_W1 on A31 */
+#define CLK_APB0_I2C		9
+#define CLK_APB0_TWD		10
+
+#define CLK_IR			11
+
+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h
new file mode 100644
index 000000000000..4ba64f3d6fc9
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-r-ccu.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+
+#define RST_APB0_IR		0
+#define RST_APB0_TIMER		1
+#define RST_APB0_RSB		2
+#define RST_APB0_UART		3
+/* 4 is reserved for RST_APB0_W1 on A31 */
+#define RST_APB0_I2C		5
+
+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */
-- 
2.12.0

^ permalink raw reply related

* [PATCH v3 3/5] arm64: allwinner: a64: add r_ccu node
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

A64 SoC have a CCU (r_ccu) in PRCM block.

Add the device node for it.

The mux 3 of R_CCU is an internal oscillator, which is 16MHz according
to the user manual, and has only 30% accuracy based on our experience
on older SoCs. The real mesaured value of it on two Pine64 boards is
around 11MHz, which is around 70% of 16MHz.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 to iosc, which is 16MHz plus minus 30%, according to the
  RTC chapter of the user manual and our experiences on A33.
Changes in v2:
- Add osc32000.

 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1c64ea2d23f9..0fe9865d4bd6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -43,8 +43,10 @@
  */
 
 #include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/clock/sun8i-r-ccu.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -98,6 +100,14 @@
 		clock-output-names = "osc32k";
 	};
 
+	iosc: internal-osc-clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <16000000>;
+		clock-accuracy = <300000000>;
+		clock-output-names = "iosc";
+	};
+
 	psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
@@ -392,5 +402,14 @@
 			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		r_ccu: clock@1f01400 {
+			compatible = "allwinner,sun50i-a64-r-ccu";
+			reg = <0x01f01400 0x100>;
+			clocks = <&osc24M>, <&osc32k>, <&iosc>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
 	};
 };
-- 
2.12.0

^ permalink raw reply related

* [PATCH v3 4/5] ARM: sunxi: h3/h5: switch apb0-related clocks to r_ccu
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .

The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
Changes in v3:
- Change osc32000 to iosc.

 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 47 +++++++++++++-------------------------
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..a7e858a82c90 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -41,8 +41,10 @@
  */
 
 #include <dt-bindings/clock/sun8i-h3-ccu.h>
+#include <dt-bindings/clock/sun8i-r-ccu.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/sun8i-h3-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -68,31 +70,12 @@
 			clock-output-names = "osc32k";
 		};
 
-		apb0: apb0_clk {
-			compatible = "fixed-factor-clock";
+		iosc: internal-osc-clk {
 			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <1>;
-			clocks = <&osc24M>;
-			clock-output-names = "apb0";
-		};
-
-		apb0_gates: clk@01f01428 {
-			compatible = "allwinner,sun8i-h3-apb0-gates-clk",
-				     "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01f01428 0x4>;
-			#clock-cells = <1>;
-			clocks = <&apb0>;
-			clock-indices = <0>, <1>;
-			clock-output-names = "apb0_pio", "apb0_ir";
-		};
-
-		ir_clk: ir_clk@01f01454 {
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01f01454 0x4>;
-			#clock-cells = <0>;
-			clocks = <&osc32k>, <&osc24M>;
-			clock-output-names = "ir";
+			compatible = "fixed-clock";
+			clock-frequency = <16000000>;
+			clock-accuracy = <300000000>;
+			clock-output-names = "iosc";
 		};
 	};
 
@@ -576,9 +559,12 @@
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		apb0_reset: reset@01f014b0 {
-			reg = <0x01f014b0 0x4>;
-			compatible = "allwinner,sun6i-a31-clock-reset";
+		r_ccu: clock@1f01400 {
+			compatible = "allwinner,sun50i-a64-r-ccu";
+			reg = <0x01f01400 0x100>;
+			clocks = <&osc24M>, <&osc32k>, <&iosc>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
 			#reset-cells = <1>;
 		};
 
@@ -589,9 +575,9 @@
 
 		ir: ir@01f02000 {
 			compatible = "allwinner,sun5i-a13-ir";
-			clocks = <&apb0_gates 1>, <&ir_clk>;
+			clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
 			clock-names = "apb", "ir";
-			resets = <&apb0_reset 1>;
+			resets = <&r_ccu RST_APB0_IR>;
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			reg = <0x01f02000 0x40>;
 			status = "disabled";
@@ -601,9 +587,8 @@
 			compatible = "allwinner,sun8i-h3-r-pinctrl";
 			reg = <0x01f02c00 0x400>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+			clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
 			clock-names = "apb", "hosc", "losc";
-			resets = <&apb0_reset 0>;
 			gpio-controller;
 			#gpio-cells = <3>;
 			interrupt-controller;
-- 
2.12.0

^ permalink raw reply related

* [PATCH v3 5/5] arm64: allwinner: a64: add R_PIO pinctrl node
From: Icenowy Zheng @ 2017-03-29 10:42 UTC (permalink / raw)
  To: Michael Turquette, Maxime Ripard, Rob Herring, Chen-Yu Tsai
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170329104246.34204-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Allwinner A64 have a dedicated pin controller to manage the PL pin bank.
As the driver and the required clock support are added, add the device
node for it.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 0fe9865d4bd6..165dbc848aa6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -411,5 +411,17 @@
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 		};
+
+		r_pio: pinctrl@01f02c00 {
+			compatible = "allwinner,sun50i-a64-r-pinctrl";
+			reg = <0x01f02c00 0x400>;
+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
 	};
 };
-- 
2.12.0

^ permalink raw reply related

* Re: [PATCH v7 1/7] clocksource/drivers/clksrc-evt-probe: Describe with the DT both the clocksource and the clockevent
From: Mark Rutland @ 2017-03-29 10:49 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rob Herring, Alexander Kochetkov, Heiko Stuebner, linux-kernel,
	devicetree, linux-arm-kernel, linux-rockchip, Thomas Gleixner,
	Russell King, Caesar Wang, Huang Tao
In-Reply-To: <20170329092210.GH2123@mai>

Hi,

On Wed, Mar 29, 2017 at 11:22:10AM +0200, Daniel Lezcano wrote:
> On Tue, Mar 28, 2017 at 08:51:46PM -0500, Rob Herring wrote:
> > On Wed, Mar 22, 2017 at 06:48:28PM +0300, Alexander Kochetkov wrote:
> > > From: Daniel Lezcano <daniel.lezcano@linaro.org>
> > > 
> > > The CLOCKSOURCE_OF_DECLARE() was introduced before the
> > > CLOCKEVENT_OF_DECLARE() and that resulted in some abuse where the
> > > clockevent and the clocksource are both initialized in the same init
> > > routine.
> > > 
> > > With the introduction of the CLOCKEVENT_OF_DECLARE(), the driver can
> > > now split the clocksource and the clockevent init code. However, the
> > > device tree may specify a single node, so the same node will be passed
> > > to the clockevent/clocksource's init function, with the same base
> > > address.
> > > 
> > > with this patch it is possible to specify an attribute to the timer's node to
> > > specify if it is a clocksource or a clockevent and define two timers node.
> > 
> > Daniel and I discussed and agreed against this a while back. What 
> > changed?
> 
> Hi Rob,
> 
> > > For example:
> > > 
> > >         timer: timer@98400000 {
> > >                 compatible = "moxa,moxart-timer";
> > >                 reg = <0x98400000 0x42>;
> > 
> > This overlaps the next node. You can change this to 0x10, but are these 
> > really 2 independent h/w blocks? Don't design the nodes around the 
> > current needs of Linux.
> 
> Mmh, thanks for raising this. Conceptually speaking there are two (or more)
> different entities, the clocksource and the clockevents but they share the same
> IP block.

>From the DT's PoV, this is one entity, which is the IP block.

The clocksource/clockevent concept is a Linux implementation detail. The
DT cannot and should not be aware of that.

[...]

> > >                 interrupts = <19 1>;
> > >                 clocks = <&coreclk>;
> > >                 clockevent;
> > 
> > This is not needed. The presence of "interrupts" is enough to say use 
> > this timer for clockevent.
> 
> Yes, that is true if no drivers was already taking CLOCKSOURCE_OF and
> initializing the clockevent. The driver will pass through the clocksource_probe
> function, check the interrupt and bail out because there is an interrupt
> declared and assume it is a clockevent, so no initialization for the driver.
> IOW, it is not backward compatible.
> 
> We need this attribute somehow in order to separate clearly a clocksource or a
> clockevent with a new implementation.

Why? A single IP block can provide the functionality of both (though
there are reasons that functionality may be mutually exclusive). What is
the benefit of this split?

> > > With this approach, we allow a mechanism to clearly define a clocksource or a
> > > clockevent without aerobatics we can find around in some drivers:
> > > 	timer-sp804.c, arc-timer.c, dw_apb_timer_of.c, mps2-timer.c,
> > > 	renesas-ostm.c, time-efm32.c, time-lpc32xx.c.
> > 
> > These all already have bindings and work. What problem are you trying to 
> > solve other than restructuring Linux?
> 
> Yes, there is already the bindings, but that force to do some hackish
> initialization.

Here, you are forcing hackish DT changes that do not truly describe HW.
How is that better?

> I would like to give the opportunity to declare separately a clocksource and a
> clockevent, in order to have full control of how this is initialized.

To me it sounds like what we need is Linux infrastructure that allows
one to register a device as having both clockevent/clocksource
functionality.

That way, we can choose to do something sane at boot time, and if the
user really wants specific devices used in specific ways, they can
request that.

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH 2/2] mtd: spi-nor: add driver for STM32 quad spi flash controller
From: Marek Vasut @ 2017-03-29 10:54 UTC (permalink / raw)
  To: Ludovic Barre, Cyrille Pitchen
  Cc: David Woodhouse, Brian Norris, Boris Brezillon,
	Richard Weinberger, Alexandre Torgue, Rob Herring,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1490619296-8168-3-git-send-email-ludovic.Barre-qxv4g6HH51o@public.gmane.org>

On 03/27/2017 02:54 PM, Ludovic Barre wrote:
> From: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
> 
> The quadspi is a specialized communication interface targeting single,
> dual or quad SPI Flash memories.
> 
> It can operate in any of the following modes:
> -indirect mode: all the operations are performed using the quadspi
>  registers
> -read memory-mapped mode: the external Flash memory is mapped to the
>  microcontroller address space and is seen by the system as if it was
>  an internal memory
> 
> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>

Hi! I presume this is not compatible with the Cadence QSPI or any other
QSPI controller, huh ?

Mostly minor nits below ...

> ---
>  drivers/mtd/spi-nor/Kconfig         |   7 +
>  drivers/mtd/spi-nor/Makefile        |   1 +
>  drivers/mtd/spi-nor/stm32-quadspi.c | 679 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 687 insertions(+)
>  create mode 100644 drivers/mtd/spi-nor/stm32-quadspi.c

[...]

> +struct stm32_qspi_cmd {
> +	struct {
> +		u32 addr_width:8;
> +		u32 dummy:8;
> +		u32 data:1;
> +	} conf;

This could all be u8 ? Why this awful construct ?

> +	u8 opcode;
> +	u32 framemode;
> +	u32 qspimode;
> +	u32 addr;
> +	size_t len;
> +	void *buf;
> +};
> +
> +static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi)
> +{
> +	u32 cr;
> +	int err = 0;

Can readl_poll_timeout() or somesuch replace this function ?

> +	if (readl_relaxed(qspi->io_base + QUADSPI_SR) & SR_TCF)
> +		return 0;
> +
> +	reinit_completion(&qspi->cmd_completion);
> +	cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
> +	writel_relaxed(cr | CR_TCIE, qspi->io_base + QUADSPI_CR);
> +
> +	if (!wait_for_completion_interruptible_timeout(&qspi->cmd_completion,
> +						       msecs_to_jiffies(1000)))
> +		err = -ETIMEDOUT;
> +
> +	writel_relaxed(cr, qspi->io_base + QUADSPI_CR);
> +	return err;
> +}
> +
> +static int stm32_qspi_wait_nobusy(struct stm32_qspi *qspi)
> +{
> +	u32 sr;
> +
> +	return readl_relaxed_poll_timeout(qspi->io_base + QUADSPI_SR, sr,
> +					  !(sr & SR_BUSY), 10, 100000);
> +}
> +
> +static void stm32_qspi_set_framemode(struct spi_nor *nor,
> +				     struct stm32_qspi_cmd *cmd, bool read)
> +{
> +	u32 dmode = CCR_DMODE_1;
> +
> +	cmd->framemode = CCR_IMODE_1;
> +
> +	if (read) {
> +		switch (nor->flash_read) {
> +		case SPI_NOR_NORMAL:
> +		case SPI_NOR_FAST:
> +			dmode = CCR_DMODE_1;
> +			break;
> +		case SPI_NOR_DUAL:
> +			dmode = CCR_DMODE_2;
> +			break;
> +		case SPI_NOR_QUAD:
> +			dmode = CCR_DMODE_4;
> +			break;
> +		}
> +	}
> +
> +	cmd->framemode |= cmd->conf.data ? dmode : 0;
> +	cmd->framemode |= cmd->conf.addr_width ? CCR_ADMODE_1 : 0;
> +}
> +
> +static void stm32_qspi_read_fifo(u8 *val, void __iomem *addr)
> +{
> +	*val = readb_relaxed(addr);
> +}
> +
> +static void stm32_qspi_write_fifo(u8 *val, void __iomem *addr)
> +{
> +	writeb_relaxed(*val, addr);
> +}
> +
> +static int stm32_qspi_tx_poll(struct stm32_qspi *qspi,
> +			      const struct stm32_qspi_cmd *cmd)
> +{
> +	void (*tx_fifo)(u8 *, void __iomem *);
> +	u32 len = cmd->len, sr;
> +	u8 *buf = cmd->buf;
> +	int ret;
> +
> +	if (cmd->qspimode == CCR_FMODE_INDW)
> +		tx_fifo = stm32_qspi_write_fifo;
> +	else
> +		tx_fifo = stm32_qspi_read_fifo;
> +
> +	while (len--) {
> +		ret = readl_relaxed_poll_timeout(qspi->io_base + QUADSPI_SR,
> +						 sr, (sr & SR_FTF),
> +						 10, 30000);

Add macros for those ad-hoc timeouts.

> +		if (ret) {
> +			dev_err(qspi->dev, "fifo timeout (stat:%#x)\n", sr);
> +			break;
> +		}
> +		tx_fifo(buf++, qspi->io_base + QUADSPI_DR);
> +	}
> +
> +	return ret;
> +}


[...]

> +static int stm32_qspi_send(struct stm32_qspi_flash *flash,
> +			   const struct stm32_qspi_cmd *cmd)
> +{
> +	struct stm32_qspi *qspi = flash->qspi;
> +	u32 ccr, dcr, cr;
> +	int err;
> +
> +	err = stm32_qspi_wait_nobusy(qspi);
> +	if (err)
> +		goto abort;
> +
> +	dcr = readl_relaxed(qspi->io_base + QUADSPI_DCR) & ~DCR_FSIZE_MASK;
> +	dcr |= DCR_FSIZE(flash->fsize);
> +	writel_relaxed(dcr, qspi->io_base + QUADSPI_DCR);
> +
> +	cr = readl_relaxed(qspi->io_base + QUADSPI_CR);
> +	cr &= ~CR_PRESC_MASK & ~CR_FSEL;
> +	cr |= CR_PRESC(flash->presc);
> +	cr |= flash->cs ? CR_FSEL : 0;
> +	writel_relaxed(cr, qspi->io_base + QUADSPI_CR);
> +
> +	if (cmd->conf.data)
> +		writel_relaxed(cmd->len - 1, qspi->io_base + QUADSPI_DLR);
> +
> +	ccr = cmd->framemode | cmd->qspimode;
> +
> +	if (cmd->conf.dummy)
> +		ccr |= CCR_DCYC(cmd->conf.dummy);
> +
> +	if (cmd->conf.addr_width)
> +		ccr |= CCR_ADSIZE(cmd->conf.addr_width - 1);
> +
> +	ccr |= CCR_INST(cmd->opcode);
> +	writel_relaxed(ccr, qspi->io_base + QUADSPI_CCR);
> +
> +	if (cmd->conf.addr_width && cmd->qspimode != CCR_FMODE_MM)
> +		writel_relaxed(cmd->addr, qspi->io_base + QUADSPI_AR);
> +
> +	err = stm32_qspi_tx(qspi, cmd);
> +	if (err)
> +		goto abort;
> +
> +	if (cmd->qspimode != CCR_FMODE_MM) {
> +		err = stm32_qspi_wait_cmd(qspi);
> +		if (err)
> +			goto abort;
> +		writel_relaxed(FCR_CTCF, qspi->io_base + QUADSPI_FCR);
> +	}
> +
> +	return err;
> +
> +abort:
> +	writel_relaxed(readl_relaxed(qspi->io_base + QUADSPI_CR)
> +		       | CR_ABORT, qspi->io_base + QUADSPI_CR);

Use a helper variable here too.

> +	dev_err(qspi->dev, "%s abort err:%d\n", __func__, err);
> +	return err;
> +}

[...]

> +static int stm32_qspi_flash_setup(struct stm32_qspi *qspi,
> +				  struct device_node *np)
> +{
> +	u32 width, flash_read, presc, cs_num, max_rate = 0;
> +	struct stm32_qspi_flash *flash;
> +	struct mtd_info *mtd;
> +	int ret;
> +
> +	of_property_read_u32(np, "reg", &cs_num);
> +	if (cs_num >= STM32_MAX_NORCHIP)
> +		return -EINVAL;
> +
> +	of_property_read_u32(np, "spi-max-frequency", &max_rate);
> +	if (!max_rate)
> +		return -EINVAL;
> +
> +	presc = DIV_ROUND_UP(qspi->clk_rate, max_rate) - 1;
> +
> +	if (of_property_read_u32(np, "spi-rx-bus-width", &width))
> +		width = 1;
> +
> +	if (width == 4)
> +		flash_read = SPI_NOR_QUAD;
> +	else if (width == 2)
> +		flash_read = SPI_NOR_DUAL;
> +	else if (width == 1)
> +		flash_read = SPI_NOR_NORMAL;
> +	else
> +		return -EINVAL;
> +
> +	flash = &qspi->flash[cs_num];
> +	flash->qspi = qspi;
> +	flash->cs = cs_num;
> +	flash->presc = presc;
> +
> +	flash->nor.dev = qspi->dev;
> +	spi_nor_set_flash_node(&flash->nor, np);
> +	flash->nor.priv = flash;
> +	mtd = &flash->nor.mtd;
> +	mtd->priv = &flash->nor;
> +
> +	flash->nor.read = stm32_qspi_read;
> +	flash->nor.write = stm32_qspi_write;
> +	flash->nor.erase = stm32_qspi_erase;
> +	flash->nor.read_reg = stm32_qspi_read_reg;
> +	flash->nor.write_reg = stm32_qspi_write_reg;
> +	flash->nor.prepare = stm32_qspi_prep;
> +	flash->nor.unprepare = stm32_qspi_unprep;
> +
> +	writel_relaxed(LPTR_DFT_TIMEOUT, qspi->io_base + QUADSPI_LPTR);
> +
> +	writel_relaxed(CR_PRESC(presc) | CR_FTHRES(3) | CR_TCEN | CR_SSHIFT
> +		       | CR_EN, qspi->io_base + QUADSPI_CR);
> +
> +	/* a minimum fsize must be set to sent the command id */
> +	flash->fsize = 25;

I don't understand why this is needed and the comment doesn't make
sense. Please fix.

> +	ret = spi_nor_scan(&flash->nor, NULL, flash_read);
> +	if (ret) {
> +		dev_err(qspi->dev, "device scan failed\n");
> +		return ret;
> +	}
> +
> +	flash->fsize = __fls(mtd->size) - 1;
> +
> +	writel_relaxed(DCR_CSHT(1), qspi->io_base + QUADSPI_DCR);
> +
> +	ret = mtd_device_register(mtd, NULL, 0);
> +	if (ret) {
> +		dev_err(qspi->dev, "mtd device parse failed\n");
> +		return ret;
> +	}
> +
> +	dev_dbg(qspi->dev, "read mm:%s cs:%d bus:%d\n",
> +		qspi->read_mode == CCR_FMODE_MM ? "yes" : "no", cs_num, width);
> +
> +	return 0;
> +}

[...]

-- 
Best regards,
Marek Vasut
--
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 v6 2/5] irqchip/aspeed-i2c-ic: Add I2C IRQ controller for Aspeed
From: Marc Zyngier @ 2017-03-29 10:55 UTC (permalink / raw)
  To: Brendan Higgins, Benjamin Herrenschmidt
  Cc: Wolfram Sang, robh+dt, mark.rutland, tglx, jason, Joel Stanley,
	Vladimir Zapolskiy, Kachalov Anton, Cédric Le Goater,
	linux-i2c, devicetree, linux-kernel, OpenBMC Maillist
In-Reply-To: <CAFd5g46TAGHWtH7p1o=AJqy8_SygpJZ4RJkJpUwDD3nKxpB5YQ@mail.gmail.com>

On 29/03/17 10:59, Brendan Higgins wrote:
> The main reason I took this approach is just because I thought it was
> cleaner from the perspective of the busses which are totally
> independent (except for the fact that they share a single hardware
> interrupt).
> 
> I did not make any measurements, so I doubt that I have anything to
> add that you don't already know. I saw other usages of chained
> interrupts that do the same thing (scan a "status" register and use
> them to make software interrupts) and I thought that is basically what
> the dummy irq chip code is for. The only thing I thought I was doing
> that was novel was actually breaking out the dummy irqchip into its
> own driver; it is not my idea, but I do think makes it a lot cleaner.
> Nevertheless, it should be cheap in terms of number of instructions;
> the most expensive part looks like looking up the mapping. In any
> case, I think the low hanging fruit here is supporting buffering or
> DMA, like Ben suggested.
> 
> To address the comment on being over engineered: outside of the init
> function (which would exist regardless of how we do this, if not here
> then in the I2C driver); the code is actually pretty small and
> generic.
> 
> All that being said, it would not be very hard to do this without
> using the dummy irqchip code and it would definitely be smaller in
> terms of indirection and space used, but I think the code would
> actually be more complicated to read. We would be going back to having
> an I2C controller along with the I2C busses; where all the I2C
> controller does is read the IRQ register and then call the appropriate
> bus irq handler, which looks a lot like a dummy irqchip.

As long as you're happy with the performance and the restrictions that
come attached to the HW, I'm happy to take the irqchip patches.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* Re: [PATCH v2 2/2] phy: meson: add USB2 PHY support for Meson GXL and GXM
From: Kishon Vijay Abraham I @ 2017-03-29 10:56 UTC (permalink / raw)
  To: Martin Blumenstingl,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	hendrik-MJglGmTD+GWCT0AhDRffsw, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	carlo-KA+7E9HrN00dnm+yROfE0A, khilman-rdvid1DuHRBWk0Htik3J/w
In-Reply-To: <CAFBinCCBkdADVX_9g54Lz2K3oPux2TnjPuotf1pz0mu6h6phTA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Hi,

On Wednesday 29 March 2017 03:03 AM, Martin Blumenstingl wrote:
> Hi Kishon,
> 
> On Sat, Mar 18, 2017 at 2:00 PM, Martin Blumenstingl
> <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> This adds a new driver for the USB2 PHYs found on Meson GXL and GXM SoCs
>> (both SoCs are using the same USB PHY register layout).
>>
>> The USB2 PHY is a simple PHY which only has a few registers to configure
>> the mode (host/device) and a reset register (to enable/disable the PHY).
>>
>> Unfortunately there are no datasheets available for this PHY. The driver
>> was written by reading the code from Amlogic's GPL kernel sources and
>> by analyzing the registers on an actual GXL and GXM device running the
>> kernel that was shipped on the boards I have.
> gentle ping - did you have time to review this patch in v2 yet?

Have a few comments, see below..
> 
>> Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>> ---
>>  drivers/phy/Kconfig              |  14 ++
>>  drivers/phy/Makefile             |   1 +
>>  drivers/phy/phy-meson-gxl-usb2.c | 273 +++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 288 insertions(+)
>>  create mode 100644 drivers/phy/phy-meson-gxl-usb2.c
>>
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index dc5277ad1b5a..2573e139fd17 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -510,6 +510,19 @@ config PHY_MESON8B_USB2
>>           and GXBB SoCs.
>>           If unsure, say N.
>>
>> +config PHY_MESON_GXL_USB
>> +       tristate "Meson GXL and GXM USB2 PHY drivers"
>> +       default ARCH_MESON
>> +       depends on OF && (ARCH_MESON || COMPILE_TEST)
>> +       depends on USB_SUPPORT
>> +       select USB_COMMON
>> +       select GENERIC_PHY
>> +       select REGMAP_MMIO
>> +       help
>> +         Enable this to support the Meson USB2 PHYs found in Meson
>> +         GXL and GXM SoCs.
>> +         If unsure, say N.
>> +
>>  config PHY_NSP_USB3
>>         tristate "Broadcom NorthStar plus USB3 PHY driver"
>>         depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
>> @@ -518,4 +531,5 @@ config PHY_NSP_USB3
>>         help
>>           Enable this to support the Broadcom Northstar plus USB3 PHY.
>>           If unsure, say N.
>> +

spurious space..
>>  endmenu
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index e7b0feb1e125..e680b856e38e 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -62,4 +62,5 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE)         += phy-bcm-cygnus-pcie.o
>>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>>  obj-$(CONFIG_PHY_NS2_PCIE)             += phy-bcm-ns2-pcie.o
>>  obj-$(CONFIG_PHY_MESON8B_USB2)         += phy-meson8b-usb2.o
>> +obj-$(CONFIG_PHY_MESON_GXL_USB)                += phy-meson-gxl-usb2.o
>>  obj-$(CONFIG_PHY_NSP_USB3)             += phy-bcm-nsp-usb3.o
>> diff --git a/drivers/phy/phy-meson-gxl-usb2.c b/drivers/phy/phy-meson-gxl-usb2.c
>> new file mode 100644
>> index 000000000000..4bf646a52c45
>> --- /dev/null
>> +++ b/drivers/phy/phy-meson-gxl-usb2.c
>> @@ -0,0 +1,273 @@
>> +/*
>> + * Meson GXL and GXM USB2 PHY driver
>> + *
>> + * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>> + *
>> + * 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.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/usb/of.h>
>> +
>> +/* bits [31:27] are read-only */
>> +#define U2P_R0                                                 0x0
>> +       #define U2P_R0_BYPASS_SEL                               BIT(0)
>> +       #define U2P_R0_BYPASS_DM_EN                             BIT(1)
>> +       #define U2P_R0_BYPASS_DP_EN                             BIT(2)
>> +       #define U2P_R0_TXBITSTUFF_ENH                           BIT(3)
>> +       #define U2P_R0_TXBITSTUFF_EN                            BIT(4)
>> +       #define U2P_R0_DM_PULLDOWN                              BIT(5)
>> +       #define U2P_R0_DP_PULLDOWN                              BIT(6)
>> +       #define U2P_R0_DP_VBUS_VLD_EXT_SEL                      BIT(7)
>> +       #define U2P_R0_DP_VBUS_VLD_EXT                          BIT(8)
>> +       #define U2P_R0_ADP_PRB_EN                               BIT(9)
>> +       #define U2P_R0_ADP_DISCHARGE                            BIT(10)
>> +       #define U2P_R0_ADP_CHARGE                               BIT(11)
>> +       #define U2P_R0_DRV_VBUS                                 BIT(12)
>> +       #define U2P_R0_ID_PULLUP                                BIT(13)
>> +       #define U2P_R0_LOOPBACK_EN_B                            BIT(14)
>> +       #define U2P_R0_OTG_DISABLE                              BIT(15)
>> +       #define U2P_R0_COMMON_ONN                               BIT(16)
>> +       #define U2P_R0_FSEL_MASK                                GENMASK(19, 17)
>> +       #define U2P_R0_REF_CLK_SEL_MASK                         GENMASK(21, 20)
>> +       #define U2P_R0_POWER_ON_RESET                           BIT(22)
>> +       #define U2P_R0_V_ATE_TEST_EN_B_MASK                     GENMASK(24, 23)
>> +       #define U2P_R0_ID_SET_ID_DQ                             BIT(25)
>> +       #define U2P_R0_ATE_RESET                                BIT(26)
>> +       #define U2P_R0_FSV_MINUS                                BIT(27)
>> +       #define U2P_R0_FSV_PLUS                                 BIT(28)
>> +       #define U2P_R0_BYPASS_DM_DATA                           BIT(29)
>> +       #define U2P_R0_BYPASS_DP_DATA                           BIT(30)
>> +
>> +#define U2P_R1                                                 0x4
>> +       #define U2P_R1_BURN_IN_TEST                             BIT(0)
>> +       #define U2P_R1_ACA_ENABLE                               BIT(1)
>> +       #define U2P_R1_DCD_ENABLE                               BIT(2)
>> +       #define U2P_R1_VDAT_SRC_EN_B                            BIT(3)
>> +       #define U2P_R1_VDAT_DET_EN_B                            BIT(4)
>> +       #define U2P_R1_CHARGES_SEL                              BIT(5)
>> +       #define U2P_R1_TX_PREEMP_PULSE_TUNE                     BIT(6)
>> +       #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK                  GENMASK(8, 7)
>> +       #define U2P_R1_TX_RES_TUNE_MASK                         GENMASK(10, 9)
>> +       #define U2P_R1_TX_RISE_TUNE_MASK                        GENMASK(12, 11)
>> +       #define U2P_R1_TX_VREF_TUNE_MASK                        GENMASK(16, 13)
>> +       #define U2P_R1_TX_FSLS_TUNE_MASK                        GENMASK(20, 17)
>> +       #define U2P_R1_TX_HSXV_TUNE_MASK                        GENMASK(22, 21)
>> +       #define U2P_R1_OTG_TUNE_MASK                            GENMASK(25, 23)
>> +       #define U2P_R1_SQRX_TUNE_MASK                           GENMASK(28, 26)
>> +       #define U2P_R1_COMP_DIS_TUNE_MASK                       GENMASK(31, 29)
>> +
>> +/* bits [31:14] are read-only */
>> +#define U2P_R2                                                 0x8
>> +       #define U2P_R2_DATA_IN_MASK                             GENMASK(3, 0)
>> +       #define U2P_R2_DATA_IN_EN_MASK                          GENMASK(7, 4)
>> +       #define U2P_R2_ADDR_MASK                                GENMASK(11, 8)
>> +       #define U2P_R2_DATA_OUT_SEL                             BIT(12)
>> +       #define U2P_R2_CLK                                      BIT(13)
>> +       #define U2P_R2_DATA_OUT_MASK                            GENMASK(17, 14)
>> +       #define U2P_R2_ACA_PIN_RANGE_C                          BIT(18)
>> +       #define U2P_R2_ACA_PIN_RANGE_B                          BIT(19)
>> +       #define U2P_R2_ACA_PIN_RANGE_A                          BIT(20)
>> +       #define U2P_R2_ACA_PIN_GND                              BIT(21)
>> +       #define U2P_R2_ACA_PIN_FLOAT                            BIT(22)
>> +       #define U2P_R2_CHARGE_DETECT                            BIT(23)
>> +       #define U2P_R2_DEVICE_SESSION_VALID                     BIT(24)
>> +       #define U2P_R2_ADP_PROBE                                BIT(25)
>> +       #define U2P_R2_ADP_SENSE                                BIT(26)
>> +       #define U2P_R2_SESSION_END                              BIT(27)
>> +       #define U2P_R2_VBUS_VALID                               BIT(28)
>> +       #define U2P_R2_B_VALID                                  BIT(29)
>> +       #define U2P_R2_A_VALID                                  BIT(30)
>> +       #define U2P_R2_ID_DIG                                   BIT(31)
>> +
>> +#define U2P_R3                                                 0xc
>> +
>> +#define RESET_COMPLETE_TIME                            500
>> +
>> +struct phy_meson_gxl_usb2_priv {
>> +       struct regmap           *regmap;
>> +       enum phy_mode           mode;
>> +       int                     is_enabled;
>> +};
>> +
>> +static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
>> +       .reg_bits = 8,
>> +       .val_bits = 32,
>> +       .reg_stride = 4,
>> +       .max_register = U2P_R3,
>> +};
>> +
>> +static int phy_meson_gxl_usb2_reset(struct phy *phy)
>> +{
>> +       struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> +       if (priv->is_enabled) {
>> +               /* reset the PHY and wait until settings are stabilized */
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> +                               U2P_R0_POWER_ON_RESET);
>> +               udelay(RESET_COMPLETE_TIME);
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> +                                  0);
>> +               udelay(RESET_COMPLETE_TIME);
>> +       }

Instead of having big if condition blocks, it could be
	if (!priv->is_enabled)
		return 0

	the configuration when priv->is_enabled is true should go here.
>> +
>> +       return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
>> +{
>> +       struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> +       switch (mode) {
>> +       case PHY_MODE_USB_HOST:
>> +       case PHY_MODE_USB_OTG:
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>> +                                  U2P_R0_DM_PULLDOWN);
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>> +                                  U2P_R0_DP_PULLDOWN);
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
>> +               break;
>> +
>> +       case PHY_MODE_USB_DEVICE:
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>> +                                  0);
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>> +                                  0);
>> +               regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
>> +                                  U2P_R0_ID_PULLUP);
>> +               break;
>> +
>> +       default:
>> +               return -EINVAL;
>> +       }
>> +
>> +       phy_meson_gxl_usb2_reset(phy);
>> +
>> +       priv->mode = mode;
>> +
>> +       return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_power_off(struct phy *phy)
>> +{
>> +       struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +
>> +       priv->is_enabled = 0;
>> +
>> +       /* power off the PHY by putting it into reset mode */
>> +       regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>> +                          U2P_R0_POWER_ON_RESET);
>> +
>> +       return 0;
>> +}
>> +
>> +static int phy_meson_gxl_usb2_power_on(struct phy *phy)
>> +{
>> +       struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>> +       int ret;
>> +
>> +       priv->is_enabled = 1;
>> +
>> +       /* power on the PHY by taking it out of reset mode */
>> +       regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
>> +
>> +       ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);

Since this is already part of phy_ops, the consumer of this phy will take care
of setting the mode right?

>> +       if (ret) {
>> +               phy_meson_gxl_usb2_power_off(phy);

This would mess up the reference count in phy_core, since this function is also
part of the phy_ops. The consumer should be responsible for powering off the phy.

Thanks
Kishon
--
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 v6 2/5] irqchip/aspeed-i2c-ic: Add I2C IRQ controller for Aspeed
From: Joel Stanley @ 2017-03-29 10:58 UTC (permalink / raw)
  To: Brendan Higgins
  Cc: Wolfram Sang, Rob Herring, Mark Rutland, Thomas Gleixner,
	Jason Cooper, Marc Zyngier, vz, mouse, Cédric Le Goater,
	linux-i2c, devicetree, Linux Kernel Mailing List,
	OpenBMC Maillist, Benjamin Herrenschmidt
In-Reply-To: <20170328051226.21677-3-brendanhiggins@google.com>

On Tue, Mar 28, 2017 at 3:42 PM, Brendan Higgins
<brendanhiggins@google.com> wrote:
> +static int __init aspeed_i2c_ic_of_init(struct device_node *node,
> +                                       struct device_node *parent)
> +{
> +       struct aspeed_i2c_ic *i2c_ic;
> +
> +       i2c_ic = kzalloc(sizeof(*i2c_ic), GFP_KERNEL);
> +       if (!i2c_ic)
> +               return -ENOMEM;
> +
> +       i2c_ic->base = of_iomap(node, 0);
> +       if (IS_ERR(i2c_ic->base))
> +               return PTR_ERR(i2c_ic->base);
> +
> +       i2c_ic->parent_irq = irq_of_parse_and_map(node, 0);
> +       if (i2c_ic->parent_irq < 0)
> +               return i2c_ic->parent_irq;
> +
> +       i2c_ic->irq_domain = irq_domain_add_linear(
> +                       node, ASPEED_I2C_IC_NUM_BUS,
> +                       &aspeed_i2c_ic_irq_domain_ops, NULL);
> +       if (!i2c_ic->irq_domain)
> +               return -ENOMEM;
> +
> +       i2c_ic->irq_domain->name = "ast-i2c-domain";

Nit: Make this aspeed-i2c-domain to make this consistent with the
other Aspeed drivers in the kernel tree.

Could this irq code be embedded in the i2c driver? We took a similar
approach for the Aspeed GPIO driver, which has a similar IRQ structure
of one hardware IRQ that tells the driver to check status registers
for the precise irq source. The upside being all of the i2c code is in
the same place in the kernel tree.

Cheers,

Joel

^ permalink raw reply

* [PATCH v3 0/2] Tango PCIe controller support
From: Marc Gonzalez @ 2017-03-29 11:11 UTC (permalink / raw)
  To: Bjorn Helgaas, Marc Zyngier, Thomas Gleixner
  Cc: DT, Lorenzo Pieralisi, Mason, linux-pci, Thibaud Cornic,
	Liviu Dudau, LKML, David Laight, Phuong Nguyen, Robin Murphy,
	Linux ARM

Hello,

The patch is split in two parts, to ease review of two orthogonal
parts (MSI controller vs host bridge)

Marc Gonzalez (2):
  PCI: Add tango MSI controller support
  PCI: Add tango PCIe host bridge support

 Documentation/devicetree/bindings/pci/tango-pcie.txt |  34 ++++
 drivers/pci/host/Kconfig                             |   7 +
 drivers/pci/host/Makefile                            |   1 +
 drivers/pci/host/pcie-tango.c                        | 344 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 386 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/tango-pcie.txt
 create mode 100644 drivers/pci/host/pcie-tango.c

-- 
2.11.0

^ permalink raw reply

* Re: [PATCH 0/4] ARM: exynos: Fix Odroid U3 USB/LAN when TFTP booting (power sequence)
From: Hans Verkuil @ 2017-03-29 11:12 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Kukjin Kim, Javier Martinez Canillas,
	Anand Moon, devicetree, linux-arm-kernel, linux-samsung-soc,
	linux-kernel
  Cc: Peter Chen, ulf.hansson, linux-pm, gregkh, linux-usb, sre,
	robh+dt, Markus Reichl, broonie, stern, Sylwester Nawrocki,
	Marek Szyprowski
In-Reply-To: <20170107085203.4431-1-krzk@kernel.org>

Hi Krzysztof,

On 07/01/17 09:51, Krzysztof Kozlowski wrote:
> Hi,
> 
> Thanks to Markus Reichl, I got an Odroid U3 to work with. Thanks to Peter
> Chen, we got a power sequence generic library which solves my long
> standing Odroid U3 problem - no LAN9730 if it was enabled by bootloader.
> 
> My previous attempts for this can be found here [0].
> 
> This patchset is based on Peter's v11 of power sequence [1].
> Patchset is available also on my Github [2].
> 
> More detailed analysis is described in patch 2/4 ("ARM: dts: exynos: Fix
> LAN9730 on Odroid U3 after tftpboot").

It's rather late, but I finally had a chance to test this and it works.

So:

Tested-by: Hans Verkuil <hans.verkuil@cisco.com>

This was with u-boot version v2016.09.01 and kernel 4.11.0-rc1.

Regards,

	Hans

> 
> 
> Best regards,
> Krzysztof
> 
> 
> [0] http://www.spinics.net/lists/linux-mmc/msg37386.html
> [1] https://lwn.net/Articles/710736/
> [2] https://github.com/krzk/linux/commits/for-next/odroid-u3-usb3503-pwrseq
> 
> Krzysztof Kozlowski (4):
>   ARM: dts: exynos: Fix indentation of EHCI and OHCI ports
>   ARM: dts: exynos: Fix LAN9730 on Odroid U3 after tftpboot
>   ARM: exynos_defconfig: Enable power sequence for Odroid U3
>   ARM: multi_v7_defconfig: Enable power sequence for Odroid U3
> 
>  arch/arm/boot/dts/exynos4.dtsi            | 24 ++++++++++++------------
>  arch/arm/boot/dts/exynos4412-odroidu3.dts | 21 +++++++++++++++++++++
>  arch/arm/configs/exynos_defconfig         |  2 ++
>  arch/arm/configs/multi_v7_defconfig       |  1 +
>  4 files changed, 36 insertions(+), 12 deletions(-)
> 

^ permalink raw reply

* Re: [PATCH v2 6/8] bus: brcmstb_gisb: Add ARM64 support
From: Mark Rutland @ 2017-03-29 11:20 UTC (permalink / raw)
  To: Doug Berger
  Cc: wangkefeng.wang, catalin.marinas, linus.walleij, will.deacon,
	mingo, f.fainelli, jonathanh, bgolaszewski,
	bcm-kernel-feedback-list, shijie.huang, treding, devicetree,
	suzuki.poulose, robh+dt, gregory.0xf0, sandeepa.s.prabhu,
	linux-arm-kernel, mirza.krak, linux-kernel, james.morse, olof,
	computersforpeace
In-Reply-To: <20170328213431.10904-7-opendmb@gmail.com>

Hi,

On Tue, Mar 28, 2017 at 02:34:29PM -0700, Doug Berger wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
> 
> Hook to the ARM64 data abort exception #16: synchronous external
> abort, which is how the GISB errors will be funneled back to the
> ARM64 CPU in case of problems

I believe that you can use a die notifier for this, and that you don't
need to hook the low-level architectural fault here.

I note that the code doesn't even look at the faulting address, and
likely doesn't have the information to do anything with it, so it make
no sense to me for this code to hook the low-level fault.

Further, as an aside, from digging into how we handle unexpected faults
it appears that we don't always treat some faults (e.g. TLB conflict,
faults on PTW) sufficiently fatally when they occur at EL0, so we likely
need to do so rework there.

Thanks,
Mark.

> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/bus/Kconfig        |  2 +-
>  drivers/bus/brcmstb_gisb.c | 15 ++++++++++++---
>  2 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
> index 0a52da439abf..d2a5f1184022 100644
> --- a/drivers/bus/Kconfig
> +++ b/drivers/bus/Kconfig
> @@ -57,7 +57,7 @@ config ARM_CCN
>  
>  config BRCMSTB_GISB_ARB
>  	bool "Broadcom STB GISB bus arbiter"
> -	depends on ARM || MIPS
> +	depends on ARM || ARM64 || MIPS
>  	default ARCH_BRCMSTB || BMIPS_GENERIC
>  	help
>  	  Driver for the Broadcom Set Top Box System-on-a-chip internal bus
> diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
> index edf79432f899..500b6bb5c739 100644
> --- a/drivers/bus/brcmstb_gisb.c
> +++ b/drivers/bus/brcmstb_gisb.c
> @@ -30,6 +30,11 @@
>  #include <asm/signal.h>
>  #endif
>  
> +#ifdef CONFIG_ARM64
> +#include <asm/signal.h>
> +#include <asm/system_misc.h>
> +#endif
> +
>  #ifdef CONFIG_MIPS
>  #include <asm/traps.h>
>  #endif
> @@ -225,7 +230,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
>  	return 0;
>  }
>  
> -#ifdef CONFIG_ARM
> +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
>  static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
>  				     struct pt_regs *regs)
>  {
> @@ -235,7 +240,7 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
>  	list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
>  		brcmstb_gisb_arb_decode_addr(gdev, "bus error");
>  
> -#if !defined(CONFIG_ARM_LPAE)
> +#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
>  	/*
>  	 * If it was an imprecise abort, then we need to correct the
>  	 * return address to be _after_ the instruction.
> @@ -247,7 +252,7 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
>  	/* Always report unhandled exception */
>  	return 1;
>  }
> -#endif
> +#endif /* CONFIG_ARM || CONFIG_ARM64 */
>  
>  #ifdef CONFIG_MIPS
>  static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup)
> @@ -395,6 +400,10 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
>  			"imprecise external abort");
>  #endif
>  #endif /* CONFIG_ARM */
> +#ifdef CONFIG_ARM64
> +	hook_fault_code(16, brcmstb_bus_error_handler, SIGBUS, 0,
> +			"synchronous external abort");
> +#endif
>  #ifdef CONFIG_MIPS
>  	board_be_handler = brcmstb_bus_error_handler;
>  #endif
> -- 
> 2.12.0
> 

^ permalink raw reply

* Re: [PATCH v2 2/7] dt-bindings: pinctrl: Add RZ/A1 bindings doc
From: Geert Uytterhoeven @ 2017-03-29 11:20 UTC (permalink / raw)
  To: Linus Walleij
  Cc: jacopo, Jacopo Mondi, Geert Uytterhoeven, Laurent Pinchart,
	Chris Brandt, Rob Herring, Mark Rutland, Russell King,
	Linux-Renesas, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CACRpkdbT3091MzAQ_hO5Hc9=gQz-eDNCDtEnVG-3G+jJ+eO+Fw@mail.gmail.com>

Hi Linus,

On Wed, Mar 29, 2017 at 12:15 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> On Wed, Mar 29, 2017 at 9:35 AM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>>> See for example:
>>> include/dt-bindings/pinctrl/mt65xx.h
>>>
>>> And how that is used in:
>>> arch/arm/boot/dts/mt2701-pinfunc.h
>>> arch/arm/boot/dts/mt2701-evb.dts
>>>
>>> The docs are here:
>>> Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
>>
>> All of the above pack the information for a pin into a single 32-bit integer.
>> Is that what you want us to use, too?
>> Currently we use two integers: 1) pin index, and 2) function/flags combo.
>
> I don't really know what you need, sorry. But some kind of figure, yes.
> I would say whatever makes sense. 16+16 bits makes sense in most
> combinatorial spaces does it not? If you split 32 bits  in 16 bits for
> pin and 16 bits for function, do you have more than 2^16 pins or 2^16
> functions?
>
> If you really do we may need to go for u64 but ... really? Is there
> a rational reason for that other than "we did it like this first"?
>
> I do not understand the notion of "flags" here. I hope that is not referring

Flags refers to BI_DIR, SWIO_IN, and SWIO_OUT, from
https://patchwork.kernel.org/patch/9643047/

32-bit should be enough to cover pins, function, and flags.

> to pin config, because I expect that to use the standard pin config
> bindings outside of the pinmux value which should just define the
> pin+function combo:
>
> node {
>     pinmux = <PIN_NUMBER_PINMUX>;
>     GENERIC_PINCONFIG;
> };
>
> Example from Mediatek:
>
> i2c1_pins_a: i2c1@0 {
>     pins {
>         pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
>                         <MT8135_PIN_196_SCL1__FUNC_SCL1>;

If we follow this example, then we can list all combinations in
include/dt-bindings/pinctrl/r7s72100-pinctrl.h, instead of creating the value
by combining the bits using a macro where we need it in the DTS.

It's gonna be a long list, though...

>         bias-pull-up = <55>;
>     };
> };
>
> So this allows for a combine pin+function number but pull ups,
> bias etc are not baked into the thing, they have to be added on
> separately with the generic bindings, which is nice and very readable.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v2] clk/axs10x: introduce AXS10X pll driver
From: Vlad Zakharov @ 2017-03-29 11:20 UTC (permalink / raw)
  To: sboyd@codeaurora.org, mturquette@baylibre.com,
	Vladislav.Zakharov@synopsys.com
  Cc: Jose.Abreu@synopsys.com, robh@kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	mark.rutland@arm.com, linux-snps-arc@lists.infradead.org,
	linux-clk@vger.kernel.org
In-Reply-To: <20170303235005.GV25384@codeaurora.org>

Hi Stephen, Michael,

On Fri, 2017-03-03 at 15:50 -0800, Stephen Boyd wrote:
> On 03/03, Vlad Zakharov wrote:
> > 
> > Hi Michael, Stephen,
> > 
> > On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote:
> > > 
> > > AXS10X boards manages it's clocks using various PLLs. These PLL has same
> > > dividers and corresponding control registers mapped to different addresses.
> > > So we add one common driver for such PLLs.
> > > 
> > > Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and
> > > ODIV. Output clock value is managed using these dividers.
> > > 
> > > We add pre-defined tables with supported rate values and appropriate
> > > configurations of IDIV, FBDIV and ODIV for each value.
> > > 
> > > As of today we add support for PLLs that generate clock for the
> > > following devices:
> > >  * ARC core on AXC CPU tiles.
> > >  * ARC PGU on ARC SDP Mainboard.
> > > and more to come later.
> > > 
> > > Acked-by: Rob Herring <robh@kernel.org>
> > > Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com>
> > > Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> > > Cc: Michael Turquette <mturquette@baylibre.com>
> > > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > 
> > Maybe you have any comments or remarks about this patch? And if you don't could you please apply it.
> > 
> 
> I haven't reviewed it yet. The merge window is upon us right now
> so I'll probably get to going through the queue this weekend/next
> week.
> 

Please treat this message as a polite reminder to review my patch.
It is required for some subsystems on our boards, e.g. for ARC PGU.

Thanks.

-- 
Best regards,
Vlad Zakharov <vzakhar@synopsys.com>
_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply

* Re: [PATCH v2 2/8] arm64: mm: mark fault_info __ro_after_init
From: Mark Rutland @ 2017-03-29 11:23 UTC (permalink / raw)
  To: Doug Berger
  Cc: wangkefeng.wang, catalin.marinas, linus.walleij, will.deacon,
	mingo, f.fainelli, jonathanh, bgolaszewski,
	bcm-kernel-feedback-list, shijie.huang, treding, devicetree,
	suzuki.poulose, robh+dt, gregory.0xf0, sandeepa.s.prabhu,
	linux-arm-kernel, mirza.krak, linux-kernel, james.morse, olof,
	computersforpeace
In-Reply-To: <20170328213431.10904-3-opendmb@gmail.com>

On Tue, Mar 28, 2017 at 02:34:25PM -0700, Doug Berger wrote:
> The fault_info table must be made writeable to allow installation
> of custom memory abort handlers, but it can be made read-only
> after initialization to provide some protection.
> 
> Signed-off-by: Doug Berger <opendmb@gmail.com>

Thanks for putting this together. I agree that making this RO is good.

However, I also think that we should not allow arbitrary hooking of
fault codes, and thus this can be const.

Thanks,
Mark.

> ---
>  arch/arm64/mm/fault.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index cdf1260f1005..43319ed58a47 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -493,7 +493,7 @@ static struct fault_info {
>  	int	sig;
>  	int	code;
>  	const char *name;
> -} fault_info[] = {
> +} fault_info[] __ro_after_init = {
>  	{ do_bad,		SIGBUS,  0,		"ttbr address size fault"	},
>  	{ do_bad,		SIGBUS,  0,		"level 1 address size fault"	},
>  	{ do_bad,		SIGBUS,  0,		"level 2 address size fault"	},
> -- 
> 2.12.0
> 

^ permalink raw reply

* Re: [PATCH v2 8/8] bus: brcmstb_gisb: update to support new revision
From: Mark Rutland @ 2017-03-29 11:25 UTC (permalink / raw)
  To: Doug Berger
  Cc: robh+dt, catalin.marinas, will.deacon, computersforpeace,
	gregory.0xf0, f.fainelli, bcm-kernel-feedback-list,
	wangkefeng.wang, james.morse, mingo, sandeepa.s.prabhu,
	shijie.huang, linus.walleij, treding, jonathanh, olof, mirza.krak,
	suzuki.poulose, bgolaszewski, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20170328213431.10904-9-opendmb@gmail.com>

On Tue, Mar 28, 2017 at 02:34:31PM -0700, Doug Berger wrote:
> The 7278 introduces a new version of this core.  This
> commit adds support for that revision.
> 
> Signed-off-by: Doug Berger <opendmb@gmail.com>
> ---
>  Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt |  3 ++-
>  drivers/bus/brcmstb_gisb.c                              | 10 ++++++++++
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> index 1eceefb20f01..8a6c3c2e58fe 100644
> --- a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> +++ b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
> @@ -3,7 +3,8 @@ Broadcom GISB bus Arbiter controller
>  Required properties:
>  
>  - compatible:
> -    "brcm,gisb-arb" or "brcm,bcm7445-gisb-arb" for 28nm chips
> +    "brcm,bcm7278-gisb-arb" for V7 28nm chips
> +    "brcm,gisb-arb" or "brcm,bcm7445-gisb-arb" for other 28nm chips
>      "brcm,bcm7435-gisb-arb" for newer 40nm chips
>      "brcm,bcm7400-gisb-arb" for older 40nm chips and all 65nm chips
>      "brcm,bcm7038-gisb-arb" for 130nm chips

For the binding:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

^ permalink raw reply

* [PATCH v3 1/2] PCI: Add tango MSI controller support
From: Marc Gonzalez @ 2017-03-29 11:29 UTC (permalink / raw)
  To: Bjorn Helgaas, Marc Zyngier, Thomas Gleixner
  Cc: DT, Lorenzo Pieralisi, Mason, linux-pci, Thibaud Cornic,
	Liviu Dudau, LKML, David Laight, Phuong Nguyen, Robin Murphy,
	Linux ARM
In-Reply-To: <5309e718-5813-5b79-db57-9d702b50d0f9@sigmadesigns.com>

The MSI controller in Tango supports 256 message-signaled interrupts,
and a single doorbell address.

Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
Changes since v0.2
- Support 256 MSIs instead of only 32
- Use spinlock_t instead of struct mutex
- Add MSI_FLAG_PCI_MSIX flag

IRQs are acked in tango_msi_isr because handle_simple_irq leaves
ack, clear, mask and unmask up to the driver. For the same reason,
interrupt enable mask is updated from tango_irq_domain_alloc/free.
---
 drivers/pci/host/pcie-tango.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 194 insertions(+)

diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
new file mode 100644
index 000000000000..e88850983a1d
--- /dev/null
+++ b/drivers/pci/host/pcie-tango.c
@@ -0,0 +1,194 @@
+#include <linux/module.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/pci-ecam.h>
+#include <linux/msi.h>
+
+#define MSI_MAX 256
+
+struct tango_pcie {
+	DECLARE_BITMAP(bitmap, MSI_MAX);
+	spinlock_t lock;
+	void __iomem *mux;
+	void __iomem *msi_status;
+	void __iomem *msi_mask;
+	phys_addr_t msi_doorbell;
+	struct irq_domain *irq_domain;
+	struct irq_domain *msi_domain;
+	int irq;
+};
+
+/*** MSI CONTROLLER SUPPORT ***/
+
+static void dispatch(struct tango_pcie *pcie, unsigned long status, int base)
+{
+	unsigned int pos, virq;
+
+	for_each_set_bit(pos, &status, 32) {
+		virq = irq_find_mapping(pcie->irq_domain, base + pos);
+		generic_handle_irq(virq);
+	}
+}
+
+static void tango_msi_isr(struct irq_desc *desc)
+{
+	u32 status;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct tango_pcie *pcie = irq_desc_get_handler_data(desc);
+	unsigned int base, offset, pos = 0;
+
+	chained_irq_enter(chip, desc);
+
+	while ((pos = find_next_bit(pcie->bitmap, MSI_MAX, pos)) < MSI_MAX) {
+		base = round_down(pos, 32);
+		offset = (pos / 32) * 4;
+		status = readl_relaxed(pcie->msi_status + offset);
+		writel_relaxed(status, pcie->msi_status + offset);
+		dispatch(pcie, status, base);
+		pos = base + 32;
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip tango_msi_irq_chip = {
+	.name = "MSI",
+	.irq_mask = pci_msi_mask_irq,
+	.irq_unmask = pci_msi_unmask_irq,
+};
+
+#define USE_DEF_OPS (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS)
+
+static struct msi_domain_info msi_domain_info = {
+	.flags	= USE_DEF_OPS | MSI_FLAG_PCI_MSIX,
+	.chip	= &tango_msi_irq_chip,
+};
+
+static void tango_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct tango_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+	msg->address_lo = lower_32_bits(pcie->msi_doorbell);
+	msg->address_hi = upper_32_bits(pcie->msi_doorbell);
+	msg->data = data->hwirq;
+}
+
+static int tango_set_affinity(struct irq_data *irq_data,
+		const struct cpumask *mask, bool force)
+{
+	 return -EINVAL;
+}
+
+static struct irq_chip tango_msi_chip = {
+	.name			= "MSI",
+	.irq_compose_msi_msg	= tango_compose_msi_msg,
+	.irq_set_affinity	= tango_set_affinity,
+};
+
+static int find_free_msi(struct irq_domain *dom, unsigned int virq)
+{
+	u32 val;
+	struct tango_pcie *pcie = dom->host_data;
+	unsigned int offset, pos;
+
+	pos = find_first_zero_bit(pcie->bitmap, MSI_MAX);
+	if (pos >= MSI_MAX)
+		return -ENOSPC;
+
+	offset = (pos / 32) * 4;
+	val = readl_relaxed(pcie->msi_mask + offset);
+	writel_relaxed(val | BIT(pos % 32), pcie->msi_mask + offset);
+	__set_bit(pos, pcie->bitmap);
+
+	irq_domain_set_info(dom, virq, pos, &tango_msi_chip,
+			dom->host_data, handle_simple_irq, NULL, NULL);
+
+	return 0;
+}
+
+static int tango_irq_domain_alloc(struct irq_domain *dom,
+		unsigned int virq, unsigned int nr_irqs, void *args)
+{
+	int err;
+	struct tango_pcie *pcie = dom->host_data;
+
+	spin_lock(&pcie->lock);
+	err = find_free_msi(dom, virq);
+	spin_unlock(&pcie->lock);
+
+	return err;
+}
+
+static void tango_irq_domain_free(struct irq_domain *dom,
+		unsigned int virq, unsigned int nr_irqs)
+{
+	u32 val;
+	struct irq_data *d = irq_domain_get_irq_data(dom, virq);
+	struct tango_pcie *pcie = irq_data_get_irq_chip_data(d);
+	unsigned int offset, pos = d->hwirq;
+
+	spin_lock(&pcie->lock);
+
+	offset = (pos / 32) * 4;
+	val = readl_relaxed(pcie->msi_mask + offset);
+	writel_relaxed(val & ~BIT(pos % 32), pcie->msi_mask + offset);
+	__clear_bit(pos, pcie->bitmap);
+
+	spin_unlock(&pcie->lock);
+}
+
+static const struct irq_domain_ops msi_dom_ops = {
+	.alloc	= tango_irq_domain_alloc,
+	.free	= tango_irq_domain_free,
+};
+
+static int tango_msi_remove(struct platform_device *pdev)
+{
+	struct tango_pcie *msi = platform_get_drvdata(pdev);
+
+	irq_set_chained_handler_and_data(msi->irq, NULL, NULL);
+	irq_domain_remove(msi->msi_domain);
+	irq_domain_remove(msi->irq_domain);
+
+	return 0;
+}
+
+static int tango_msi_probe(struct platform_device *pdev, struct tango_pcie *pcie)
+{
+	int i, virq;
+	struct fwnode_handle *fwnode = of_node_to_fwnode(pdev->dev.of_node);
+	struct irq_domain *msi_dom, *irq_dom;
+
+	spin_lock_init(&pcie->lock);
+
+	for (i = 0; i < MSI_MAX / 32; ++i)
+		writel_relaxed(0, pcie->msi_mask + i * 4);
+
+	irq_dom = irq_domain_create_linear(fwnode, MSI_MAX, &msi_dom_ops, pcie);
+	if (!irq_dom) {
+		pr_err("Failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	msi_dom = pci_msi_create_irq_domain(fwnode, &msi_domain_info, irq_dom);
+	if (!msi_dom) {
+		pr_err("Failed to create MSI domain\n");
+		irq_domain_remove(irq_dom);
+		return -ENOMEM;
+	}
+
+	virq = platform_get_irq(pdev, 1);
+	if (virq <= 0) {
+		pr_err("Failed to map IRQ\n");
+		irq_domain_remove(msi_dom);
+		irq_domain_remove(irq_dom);
+		return -ENXIO;
+	}
+
+	pcie->irq_domain = irq_dom;
+	pcie->msi_domain = msi_dom;
+	pcie->irq = virq;
+	irq_set_chained_handler_and_data(virq, tango_msi_isr, pcie);
+
+	return 0;
+}
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH v2 1/8] arm64: mm: Allow installation of memory abort handlers
From: Mark Rutland @ 2017-03-29 11:32 UTC (permalink / raw)
  To: Doug Berger, catalin.marinas, will.deacon
  Cc: robh+dt, computersforpeace, gregory.0xf0, f.fainelli,
	bcm-kernel-feedback-list, wangkefeng.wang, james.morse, mingo,
	sandeepa.s.prabhu, shijie.huang, linus.walleij, treding,
	jonathanh, olof, mirza.krak, suzuki.poulose, bgolaszewski,
	devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20170328213431.10904-2-opendmb@gmail.com>

Hi,

On Tue, Mar 28, 2017 at 02:34:24PM -0700, Doug Berger wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
> 
> Similarly to what the ARM/Linux kernel provides, add a hook_fault_code()
> function which allows drivers or other parts of the kernel to install
> custom memory abort handlers. This is useful when a given SoC's busing
> does not propagate the exact faulting physical address, but there is a
> way to read it through e.g: a special arbiter driver.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Personally, I do not think that it makes sense to allow arbitrary code
to hook such low-level fault handling.

IMO, if it is truly necessary to allow drivers to handle particular
faults, that should be driven by data associated with the relevant
mapping (e.g. the VMA), rather than allowing code to hook *all* faults.

>From my PoV, NAK to this interface to take over low-level fault
handling.

Catalin and Will have the final say here, as the arm64 maintainers.

Thanks,
Mark.

> ---
>  arch/arm64/include/asm/system_misc.h |  3 +++
>  arch/arm64/mm/fault.c                | 15 ++++++++++++++-
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index bc812435bc76..e05f5b8c7c1c 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -38,6 +38,9 @@ void arm64_notify_die(const char *str, struct pt_regs *regs,
>  void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
>  					     struct pt_regs *),
>  			   int sig, int code, const char *name);
> +void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
> +				       struct pt_regs *),
> +		     int sig, int code, const char *name);
>  
>  struct mm_struct;
>  extern void show_pte(struct mm_struct *mm, unsigned long addr);
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 4bf899fb451b..cdf1260f1005 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -488,7 +488,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>  	return 1;
>  }
>  
> -static const struct fault_info {
> +static struct fault_info {
>  	int	(*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
>  	int	sig;
>  	int	code;
> @@ -560,6 +560,19 @@ static const struct fault_info {
>  	{ do_bad,		SIGBUS,  0,		"unknown 63"			},
>  };
>  
> +void __init hook_fault_code(int nr,
> +			    int (*fn)(unsigned long, unsigned int, struct pt_regs *),
> +			    int sig, int code, const char *name)
> +{
> +	BUG_ON(nr < 0 || nr >= ARRAY_SIZE(fault_info));
> +
> +	fault_info[nr].fn	= fn;
> +	fault_info[nr].sig	= sig;
> +	fault_info[nr].code	= code;
> +	fault_info[nr].name	= name;
> +}
> +
> +
>  static const char *fault_name(unsigned int esr)
>  {
>  	const struct fault_info *inf = fault_info + (esr & 63);
> -- 
> 2.12.0
> 

^ 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