linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/15] Allwinner sunxi message box support
@ 2019-03-02  4:29 Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical Samuel Holland
                   ` (14 more replies)
  0 siblings, 15 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

This series adds support for the "hardware message box" in sun8i, sun9i,
and sun50i SoCs, used for communication with the ARISC management
processor (the platform's equivalent of the ARM SCP). The end goal is to
use the arm_scpi driver as a client, communicating with firmware running
on the AR100 CPU, or to use the mailbox to forward NMIs that the
firmware picks up from R_INTC.

Unfortunately, the ARM SCPI client no longer works with this driver
since it now exposes all 8 hardware FIFOs individually. The SCPI client
could be made to work (and I posted proof-of-concept code to that effect
with v1 of this series), but that is a low priority, as Linux does not
directly use SCPI with the current firmware version; all SCPI use goes
through ATF via PSCI.

An example usage is included at the end of this patch series. The IRQ
forwarding code is WIP and not even RFC quality yet, but it does work.
To build the firmware component, run:

  git clone https://github.com/crust-firmware/meta meta
  git clone https://github.com/smaeul/crust -b linux-mailbox-example meta/crust
  cd meta
  make

That will by default produce a U-Boot + ATF + SCP firmware image in
[meta/]build/pinebook/u-boot-sunxi-with-spl.bin. See the top-level README.md
for more information (like cross-compiler setup). The IRQ-forwarding mailbox
server is implemented in [meta/crust/]common/irqf.c.

With that firmware and the full patch series here (on top of
torvalds/master), Linux boots and is able to receive NMIs from the PMIC
(i.e. use `showkey` to see that the power button works, and see that
/proc/interrupts updates). As an added bonus, suspend/resume also mostly
works :)

Changes from v2:
  - Merge patches 1-3
  - Add a comment in the code explaining the CLK_IS_CRITICAL usage
  - Add a patch to mark the AR100 clocks as critical
  - Use YAML for the device tree binding
  - Include a not-for-merge example usage of the mailbox.

Changes from v1:
  - Marked message box clocks as critical instead of hacks in the driver
  - 8 unidirectional channels instead of 4 bidirectional pairs
  - Use per-SoC compatible strings and an A31 fallback compatible
  - Dropped the mailbox framework patch
  - Include DT patches for SoCs that document the message box

Samuel Holland (15):
  clk: sunxi-ng: Mark msgbox clocks as critical
  clk: sunxi-ng: Mark AR100 clocks as critical
  dt-bindings: mailbox: Add a sunxi message box binding
  mailbox: sunxi-msgbox: Add a new mailbox driver
  ARM: dts: sunxi: a80: Add msgbox node
  ARM: dts: sunxi: a83t: Add msgbox node
  ARM: dts: sunxi: h3/h5: Add msgbox node
  arm64: dts: allwinner: a64: Add msgbox node
  arm64: dts: allwinner: h6: Add msgbox node
  [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM
    gates
  [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed
    interrupt controller
  [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip
    driver
  [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller
    node
  [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use
    msgbox_intc
  [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc

 .../interrupt-controller/mbox-intc.txt        |  33 ++
 .../mailbox/allwinner,sunxi-msgbox.yaml       |  79 +++++
 arch/arm/boot/dts/sun8i-a83t.dtsi             |  10 +
 arch/arm/boot/dts/sun9i-a80.dtsi              |  10 +
 arch/arm/boot/dts/sunxi-h3-h5.dtsi            |  10 +
 .../allwinner/sun50i-a64-amarula-relic.dts    |   4 +-
 .../dts/allwinner/sun50i-a64-bananapi-m64.dts |   4 +-
 .../dts/allwinner/sun50i-a64-nanopi-a64.dts   |   4 +-
 .../dts/allwinner/sun50i-a64-olinuxino.dts    |   4 +-
 .../dts/allwinner/sun50i-a64-orangepi-win.dts |   4 +-
 .../boot/dts/allwinner/sun50i-a64-pine64.dts  |   4 +-
 .../dts/allwinner/sun50i-a64-pinebook.dts     |   4 +-
 .../boot/dts/allwinner/sun50i-a64-sopine.dtsi |   4 +-
 .../boot/dts/allwinner/sun50i-a64-teres-i.dts |   4 +-
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  27 +-
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  |  10 +
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c         |   3 +-
 drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c        |   2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c          |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a23.c          |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c          |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c         |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-h3.c           |   3 +-
 drivers/clk/sunxi-ng/ccu-sun8i-r.c            |  20 +-
 drivers/clk/sunxi-ng/ccu-sun9i-a80.c          |   3 +-
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-mbox.c                    | 199 +++++++++++
 drivers/mailbox/Kconfig                       |  11 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/sunxi-msgbox.c                | 315 ++++++++++++++++++
 31 files changed, 750 insertions(+), 45 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
 create mode 100644 Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml
 create mode 100644 drivers/irqchip/irq-mbox.c
 create mode 100644 drivers/mailbox/sunxi-msgbox.c

-- 
2.19.2


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

* [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 02/15] clk: sunxi-ng: Mark AR100 " Samuel Holland
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The msgbox clock is critical because the hardware it controls is shared
between Linux and system firmware. The message box may be used by the
EL3 secure monitor's PSCI implementation. On 64-bit sunxi SoCs, this is
provided by ARM TF-A; 32-bit SoCs use a different implementation. The
secure monitor uses the message box to forward requests to power
management firmware running on a separate CPU.

It is not enough for the secure monitor to enable the clock each time
Linux performs a SMC into EL3, as both the firmware and Linux can run
concurrently on separate CPUs. So it is never safe for Linux to turn
this clock off, and it should be marked as critical.

At this time, such power management firmware only exists for the A64 and
H5 SoCs.  However, it makes sense to take care of all CCU drivers now
for consistency, and to ease the transition in the future once firmware
is ported to the other SoCs.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c  | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun8i-a23.c  | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c  | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun8i-h3.c   | 3 ++-
 drivers/clk/sunxi-ng/ccu-sun9i-a80.c  | 3 ++-
 7 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 932836d26e2b..22c8de3546e6 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -349,8 +349,9 @@ static SUNXI_CCU_GATE(bus_de_clk,	"bus-de",	"ahb1",
 		      0x064, BIT(12), 0);
 static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
 		      0x064, BIT(20), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x064, BIT(21), 0);
+		      0x064, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x064, BIT(22), 0);
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index 139e8389615c..02b10ba6f4ce 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -339,8 +339,9 @@ static SUNXI_CCU_GATE(bus_vp9_clk, "bus-vp9", "psi-ahb1-ahb2",
 static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2",
 		      0x70c, BIT(0), 0);
 
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "psi-ahb1-ahb2",
-		      0x71c, BIT(0), 0);
+		      0x71c, BIT(0), CLK_IS_CRITICAL);
 
 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "psi-ahb1-ahb2",
 		      0x72c, BIT(0), 0);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
index a4fa2945f230..d4eeef69de52 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -262,8 +262,9 @@ static SUNXI_CCU_GATE(bus_de_fe_clk,	"bus-de-fe",	"ahb1",
 		      0x064, BIT(14), 0);
 static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
 		      0x064, BIT(20), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x064, BIT(21), 0);
+		      0x064, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x064, BIT(22), 0);
 static SUNXI_CCU_GATE(bus_drc_clk,	"bus-drc",	"ahb1",
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index c7bf814dfd2b..66d958ba86cc 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -274,8 +274,9 @@ static SUNXI_CCU_GATE(bus_de_fe_clk,	"bus-de-fe",	"ahb1",
 		      0x064, BIT(14), 0);
 static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
 		      0x064, BIT(20), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x064, BIT(21), 0);
+		      0x064, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x064, BIT(22), 0);
 static SUNXI_CCU_GATE(bus_drc_clk,	"bus-drc",	"ahb1",
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
index 2d6555d73170..24166609fd03 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -346,8 +346,9 @@ static SUNXI_CCU_GATE(bus_de_clk,	"bus-de",	"ahb1",
 		      0x064, BIT(12), 0);
 static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
 		      0x064, BIT(20), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x064, BIT(21), 0);
+		      0x064, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x064, BIT(22), 0);
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index e71e2451c2e3..66777bff86e0 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -280,8 +280,9 @@ static SUNXI_CCU_GATE(bus_de_clk,	"bus-de",	"ahb1",
 		      0x064, BIT(12), 0);
 static SUNXI_CCU_GATE(bus_gpu_clk,	"bus-gpu",	"ahb1",
 		      0x064, BIT(20), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x064, BIT(21), 0);
+		      0x064, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x064, BIT(22), 0);
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
index 8936ef87652c..40b16cdcc98b 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
@@ -755,8 +755,9 @@ static SUNXI_CCU_GATE(bus_usb_clk,	"bus-usb",	"ahb1",
 		      0x584, BIT(1), 0);
 static SUNXI_CCU_GATE(bus_gmac_clk,	"bus-gmac",	"ahb1",
 		      0x584, BIT(17), 0);
+/* Used for communication between firmware components at runtime */
 static SUNXI_CCU_GATE(bus_msgbox_clk,	"bus-msgbox",	"ahb1",
-		      0x584, BIT(21), 0);
+		      0x584, BIT(21), CLK_IS_CRITICAL);
 static SUNXI_CCU_GATE(bus_spinlock_clk,	"bus-spinlock",	"ahb1",
 		      0x584, BIT(22), 0);
 static SUNXI_CCU_GATE(bus_hstimer_clk,	"bus-hstimer",	"ahb1",
-- 
2.19.2


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

* [PATCH v3 02/15] clk: sunxi-ng: Mark AR100 clocks as critical
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding Samuel Holland
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

On sun8i, sun9i, and sun50i SoCs, system suspend/resume support requires
firmware running on the AR100 coprocessor (the "SCP"). Such firmware can
provide additional features, such as thermal monitoring and poweron/off
support for boards without a PMIC.

Since the AR100 may be running critical firmware, even if Linux does not
know about it or directly interact with it (all requests may go through
an intermediary interface such as PSCI), Linux must not turn off its
clock.

At this time, such power management firmware only exists for the A64 and
H5 SoCs.  However, it makes sense to take care of all CCU drivers now
for consistency, and to ease the transition in the future once firmware
is ported to the other SoCs.

Leaving the clock running is safe even if no firmware is present, since
the AR100 stays in reset by default. In most cases, the AR100 clock is
kept enabled by Linux anyway, since it is the parent of all APB0 bus
peripherals. This change only prevents Linux from turning off the AR100
clock in the rare case that no peripherals are in use.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-r.c     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
index 27554eaf6929..4f822b598ade 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
@@ -45,7 +45,7 @@ static struct ccu_div ar100_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
 						      ar100_r_apb2_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_IS_CRITICAL),
 	},
 };
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
index 71feb7b24e8a..90b3530e2c18 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -50,7 +50,7 @@ static struct ccu_div ar100_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
 						      ar100_parents,
 						      &ccu_div_ops,
-						      0),
+						      CLK_IS_CRITICAL),
 	},
 };
 
-- 
2.19.2


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

* [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 02/15] clk: sunxi-ng: Mark AR100 " Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-12 13:36   ` Rob Herring
  2019-03-02  4:29 ` [PATCH v3 04/15] mailbox: sunxi-msgbox: Add a new mailbox driver Samuel Holland
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

This mailbox hardware is present in Allwinner sun8i, sun9i, and sun50i
SoCs. Add a device tree binding for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 .../mailbox/allwinner,sunxi-msgbox.yaml       | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml b/Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml
new file mode 100644
index 000000000000..f34a1909ab2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/allwinner,sunxi-msgbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner sunxi Message Box
+
+maintainers:
+  - Samuel Holland <samuel@sholland.org>
+
+description: |
+  The hardware message box on sun6i and newer sunxi SoCs is a two-user mailbox
+  controller containing 8 unidirectional FIFOs. An interrupt is raised for
+  received messages, but software must poll to know when a transmitted message
+  has been acknowledged by the remote user. Each FIFO can hold four 32-bit
+  messages; when a FIFO is full, clients must wait before more transmissions.
+
+  Refer to ./mailbox.txt for generic information about mailbox device-tree
+  bindings.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - allwinner,sun8i-a83t-msgbox
+              - allwinner,sun8i-h3-msgbox
+              - allwinner,sun9i-a80-msgbox
+              - allwinner,sun50i-a64-msgbox
+              - allwinner,sun50i-h6-msgbox
+          - const: allwinner,sun6i-a31-msgbox
+      - items:
+          - const: allwinner,sun6i-a31-msgbox
+
+  reg:
+    items:
+      - description: MMIO register range
+
+  clocks:
+    maxItems: 1
+    description: bus clock
+
+  resets:
+    maxItems: 1
+    description: bus reset
+
+  interrupts:
+    maxItems: 1
+    description: controller interrupt
+
+  '#mbox-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - interrupts
+  - '#mbox-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/sun8i-h3-ccu.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/sun8i-h3-ccu.h>
+
+    msgbox: mailbox@1c17000 {
+            compatible = "allwinner,sun8i-h3-msgbox",
+                         "allwinner,sun6i-a31-msgbox";
+            reg = <0x01c17000 0x1000>;
+            clocks = <&ccu CLK_BUS_MSGBOX>;
+            resets = <&ccu RST_BUS_MSGBOX>;
+            interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+            #mbox-cells = <1>;
+    };
+
+...
-- 
2.19.2


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

* [PATCH v3 04/15] mailbox: sunxi-msgbox: Add a new mailbox driver
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (2 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 05/15] ARM: dts: sunxi: a80: Add msgbox node Samuel Holland
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

Allwinner sun8i, sun9i, and sun50i SoCs contain a hardware message box
used for communication between the ARM CPUs and the ARISC management
coprocessor. The hardware contains 8 unidirectional 4-message FIFOs.

Add a driver for it, so it can be used for SCPI or other communication
protocols.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/mailbox/Kconfig        |  11 ++
 drivers/mailbox/Makefile       |   2 +
 drivers/mailbox/sunxi-msgbox.c | 315 +++++++++++++++++++++++++++++++++
 3 files changed, 328 insertions(+)
 create mode 100644 drivers/mailbox/sunxi-msgbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 3eeb12e93e98..6309e755d04a 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -205,4 +205,15 @@ config MTK_CMDQ_MBOX
 	  mailbox driver. The CMDQ is used to help read/write registers with
 	  critical time limitation, such as updating display configuration
 	  during the vblank.
+
+config SUNXI_MSGBOX
+	tristate "Allwinner sunxi Message Box"
+	depends on ARCH_SUNXI || COMPILE_TEST
+	default ARCH_SUNXI
+	help
+	  Mailbox implementation for the hardware message box present in
+	  Allwinner sun8i, sun9i, and sun50i SoCs. The hardware message box is
+	  used for communication between the application CPUs and the power
+	  management coprocessor.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index c818b5d011ae..f29a119a3fac 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -44,3 +44,5 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
+
+obj-$(CONFIG_SUNXI_MSGBOX)	+= sunxi-msgbox.o
diff --git a/drivers/mailbox/sunxi-msgbox.c b/drivers/mailbox/sunxi-msgbox.c
new file mode 100644
index 000000000000..fb0d733dd3b4
--- /dev/null
+++ b/drivers/mailbox/sunxi-msgbox.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2017-2019 Samuel Holland <samuel@sholland.org>
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+
+#define NUM_CHANS		8
+
+#define CTRL_REG(n)		(0x0000 + 0x4 * ((n) / 4))
+#define CTRL_RX(n)		BIT(0 + 8 * ((n) % 4))
+#define CTRL_TX(n)		BIT(4 + 8 * ((n) % 4))
+
+#define REMOTE_IRQ_EN_REG	0x0040
+#define REMOTE_IRQ_STATUS_REG	0x0050
+#define LOCAL_IRQ_EN_REG	0x0060
+#define LOCAL_IRQ_STATUS_REG	0x0070
+
+#define RX_IRQ(n)		BIT(0 + 2 * (n))
+#define RX_IRQ_MASK		0x5555
+#define TX_IRQ(n)		BIT(1 + 2 * (n))
+#define TX_IRQ_MASK		0xaaaa
+
+#define FIFO_STATUS_REG(n)	(0x0100 + 0x4 * (n))
+#define FIFO_STATUS_MASK	BIT(0)
+
+#define MSG_STATUS_REG(n)	(0x0140 + 0x4 * (n))
+#define MSG_STATUS_MASK		GENMASK(2, 0)
+
+#define MSG_DATA_REG(n)		(0x0180 + 0x4 * (n))
+
+#define mbox_dbg(mbox, ...)	dev_dbg((mbox)->controller.dev, __VA_ARGS__)
+
+struct sunxi_msgbox {
+	struct mbox_controller controller;
+	struct clk *clk;
+	spinlock_t lock;
+	void __iomem *regs;
+};
+
+static bool sunxi_msgbox_last_tx_done(struct mbox_chan *chan);
+static bool sunxi_msgbox_peek_data(struct mbox_chan *chan);
+
+static inline int channel_number(struct mbox_chan *chan)
+{
+	return chan - chan->mbox->chans;
+}
+
+static inline struct sunxi_msgbox *channel_to_msgbox(struct mbox_chan *chan)
+{
+	return (struct sunxi_msgbox *)chan->con_priv;
+}
+
+static irqreturn_t sunxi_msgbox_irq(int irq, void *dev_id)
+{
+	struct mbox_chan *chan;
+	struct sunxi_msgbox *mbox = dev_id;
+	int n;
+	uint32_t msg, status;
+
+	status = readl(mbox->regs + LOCAL_IRQ_STATUS_REG);
+	if (!(status & RX_IRQ_MASK))
+		return IRQ_NONE;
+
+	for (n = 0; n < NUM_CHANS; ++n) {
+		if (!(status & RX_IRQ(n)))
+			continue;
+		chan = &mbox->controller.chans[n];
+		while (sunxi_msgbox_peek_data(chan)) {
+			msg = readl(mbox->regs + MSG_DATA_REG(n));
+			mbox_dbg(mbox, "Channel %d received 0x%08x\n", n, msg);
+			mbox_chan_received_data(chan, &msg);
+		}
+		/* The IRQ can be cleared only when the FIFO is empty. */
+		writel(RX_IRQ(n), mbox->regs + LOCAL_IRQ_STATUS_REG);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_msgbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct sunxi_msgbox *mbox = channel_to_msgbox(chan);
+	int n = channel_number(chan);
+	uint32_t msg = *(uint32_t *)data;
+
+	/* Using a channel backwards gets the hardware into a bad state. */
+	if (WARN_ON_ONCE(!(readl(mbox->regs + CTRL_REG(n)) & CTRL_TX(n))))
+		return 0;
+
+	/* We cannot post a new message if the FIFO is full. */
+	if (readl(mbox->regs + FIFO_STATUS_REG(n)) & FIFO_STATUS_MASK) {
+		mbox_dbg(mbox, "Channel %d busy sending 0x%08x\n", n, msg);
+		return -EBUSY;
+	}
+
+	writel(msg, mbox->regs + MSG_DATA_REG(n));
+	mbox_dbg(mbox, "Channel %d sent 0x%08x\n", n, msg);
+
+	return 0;
+}
+
+static int sunxi_msgbox_startup(struct mbox_chan *chan)
+{
+	struct sunxi_msgbox *mbox = channel_to_msgbox(chan);
+	int n = channel_number(chan);
+
+	/* The coprocessor is responsible for setting channel directions. */
+	if (readl(mbox->regs + CTRL_REG(n)) & CTRL_RX(n)) {
+		/* Clear existing messages in the receive FIFO. */
+		while (sunxi_msgbox_peek_data(chan))
+			readl(mbox->regs + MSG_DATA_REG(n));
+		writel(RX_IRQ(n), mbox->regs + LOCAL_IRQ_STATUS_REG);
+
+		/* Enable the receive interrupt. */
+		spin_lock(&mbox->lock);
+		writel(readl(mbox->regs + LOCAL_IRQ_EN_REG) | RX_IRQ(n),
+		       mbox->regs + LOCAL_IRQ_EN_REG);
+		spin_unlock(&mbox->lock);
+	}
+
+	mbox_dbg(mbox, "Channel %d startup\n", n);
+
+	return 0;
+}
+
+static void sunxi_msgbox_shutdown(struct mbox_chan *chan)
+{
+	struct sunxi_msgbox *mbox = channel_to_msgbox(chan);
+	int n = channel_number(chan);
+
+	if (readl(mbox->regs + CTRL_REG(n)) & CTRL_RX(n)) {
+		/* Disable the receive interrupt. */
+		spin_lock(&mbox->lock);
+		writel(readl(mbox->regs + LOCAL_IRQ_EN_REG) & ~RX_IRQ(n),
+		       mbox->regs + LOCAL_IRQ_EN_REG);
+		spin_unlock(&mbox->lock);
+
+		/* Clear existing messages in the receive FIFO. */
+		while (sunxi_msgbox_peek_data(chan))
+			readl(mbox->regs + MSG_DATA_REG(n));
+		writel(RX_IRQ(n), mbox->regs + LOCAL_IRQ_STATUS_REG);
+	}
+
+	mbox_dbg(mbox, "Channel %d shutdown\n", n);
+}
+
+static bool sunxi_msgbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct sunxi_msgbox *mbox = channel_to_msgbox(chan);
+	int n = channel_number(chan);
+
+	/*
+	 * The hardware allows snooping on the remote user's IRQ status. We
+	 * consider a message to be acknowledged only when the receive IRQ for
+	 * that channel is cleared. As the hardware only allows clearing the
+	 * IRQ for a channel when the FIFO is empty, this still ensures that
+	 * the message has actually been read. It also gives the receiver an
+	 * opportunity to perform minimal processing before acknowledging a
+	 * message.
+	 */
+	return !(readl(mbox->regs + REMOTE_IRQ_STATUS_REG) & RX_IRQ(n));
+}
+
+static bool sunxi_msgbox_peek_data(struct mbox_chan *chan)
+{
+	struct sunxi_msgbox *mbox = channel_to_msgbox(chan);
+	int n = channel_number(chan);
+
+	return (readl(mbox->regs + MSG_STATUS_REG(n)) & MSG_STATUS_MASK) > 0;
+}
+
+static const struct mbox_chan_ops sunxi_msgbox_chan_ops = {
+	.send_data    = sunxi_msgbox_send_data,
+	.startup      = sunxi_msgbox_startup,
+	.shutdown     = sunxi_msgbox_shutdown,
+	.last_tx_done = sunxi_msgbox_last_tx_done,
+	.peek_data    = sunxi_msgbox_peek_data,
+};
+
+static int sunxi_msgbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mbox_chan *chans;
+	struct reset_control *reset;
+	struct resource *res;
+	struct sunxi_msgbox *mbox;
+	int i, ret;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kcalloc(dev, NUM_CHANS, sizeof(*chans), GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	for (i = 0; i < NUM_CHANS; ++i)
+		chans[i].con_priv = mbox;
+
+	mbox->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mbox->clk)) {
+		ret = PTR_ERR(mbox->clk);
+		dev_err(dev, "Failed to get clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(mbox->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable clock: %d\n", ret);
+		return ret;
+	}
+
+	reset = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(reset)) {
+		ret = PTR_ERR(reset);
+		dev_err(dev, "Failed to get reset control: %d\n", ret);
+		goto err_disable_unprepare;
+	}
+
+	ret = reset_control_deassert(reset);
+	if (ret) {
+		dev_err(dev, "Failed to deassert reset: %d\n", ret);
+		goto err_disable_unprepare;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto err_disable_unprepare;
+	}
+
+	mbox->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mbox->regs)) {
+		ret = PTR_ERR(mbox->regs);
+		dev_err(dev, "Failed to map MMIO resource: %d\n", ret);
+		goto err_disable_unprepare;
+	}
+
+	/* Disable all interrupts for this end of the msgbox. */
+	writel(0, mbox->regs + LOCAL_IRQ_EN_REG);
+
+	ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0),
+			       sunxi_msgbox_irq, 0, dev_name(dev), mbox);
+	if (ret) {
+		dev_err(dev, "Failed to register IRQ handler: %d\n", ret);
+		goto err_disable_unprepare;
+	}
+
+	mbox->controller.dev           = dev;
+	mbox->controller.ops           = &sunxi_msgbox_chan_ops;
+	mbox->controller.chans         = chans;
+	mbox->controller.num_chans     = NUM_CHANS;
+	mbox->controller.txdone_irq    = false;
+	mbox->controller.txdone_poll   = true;
+	mbox->controller.txpoll_period = 5;
+
+	spin_lock_init(&mbox->lock);
+	platform_set_drvdata(pdev, mbox);
+
+	ret = mbox_controller_register(&mbox->controller);
+	if (ret) {
+		dev_err(dev, "Failed to register controller: %d\n", ret);
+		goto err_disable_unprepare;
+	}
+
+	return 0;
+
+err_disable_unprepare:
+	clk_disable_unprepare(mbox->clk);
+
+	return ret;
+}
+
+static int sunxi_msgbox_remove(struct platform_device *pdev)
+{
+	struct sunxi_msgbox *mbox = platform_get_drvdata(pdev);
+
+	mbox_controller_unregister(&mbox->controller);
+	clk_disable_unprepare(mbox->clk);
+
+	return 0;
+}
+
+static const struct of_device_id sunxi_msgbox_of_match[] = {
+	{ .compatible = "allwinner,sun6i-a31-msgbox", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sunxi_msgbox_of_match);
+
+static struct platform_driver sunxi_msgbox_driver = {
+	.driver = {
+		.name = "sunxi-msgbox",
+		.of_match_table = sunxi_msgbox_of_match,
+	},
+	.probe  = sunxi_msgbox_probe,
+	.remove = sunxi_msgbox_remove,
+};
+module_platform_driver(sunxi_msgbox_driver);
+
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_DESCRIPTION("Allwinner sunxi Message Box");
+MODULE_LICENSE("GPL v2");
-- 
2.19.2


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

* [PATCH v3 05/15] ARM: dts: sunxi: a80: Add msgbox node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (3 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 04/15] mailbox: sunxi-msgbox: Add a new mailbox driver Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 06/15] ARM: dts: sunxi: a83t: " Samuel Holland
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The A80 SoC contains a message box that can be used to send messages and
interrupts back and forth between the ARM application CPUs and the ARISC
coprocessor. Add a device tree node for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm/boot/dts/sun9i-a80.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index d9532fb1ef65..10e878f94fc0 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -283,6 +283,16 @@
 			};
 		};
 
+		msgbox: mailbox@803000 {
+			compatible = "allwinner,sun9i-a80-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x00803000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		ehci0: usb@a00000 {
 			compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
 			reg = <0x00a00000 0x100>;
-- 
2.19.2


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

* [PATCH v3 06/15] ARM: dts: sunxi: a83t: Add msgbox node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (4 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 05/15] ARM: dts: sunxi: a80: Add msgbox node Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: " Samuel Holland
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The A83T SoC contains a message box that can be used to send messages
and interrupts back and forth between the ARM application CPUs and the
ARISC coprocessor. Add a device tree node for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index b099d2fbb5cd..c80c4f942439 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -546,6 +546,16 @@
 			reg = <0x1c14000 0x400>;
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun8i-a83t-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-a83t-musb",
 				     "allwinner,sun8i-a33-musb";
-- 
2.19.2


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

* [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: Add msgbox node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (5 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 06/15] ARM: dts: sunxi: a83t: " Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-06  3:39   ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 08/15] arm64: dts: allwinner: a64: " Samuel Holland
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The H3 and H5 SoCs contain a message box that can be used to send
messages and interrupts back and forth between the ARM application CPUs
and the ARISC coprocessor. Add a device tree node for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index a4c757c0b741..a42fd3f9739e 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -227,6 +227,16 @@
 			#size-cells = <0>;
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun8i-h3-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-h3-musb";
 			reg = <0x01c19000 0x400>;
-- 
2.19.2


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

* [PATCH v3 08/15] arm64: dts: allwinner: a64: Add msgbox node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (6 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: " Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 09/15] arm64: dts: allwinner: h6: " Samuel Holland
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The A64 SoC contains a message box that can be used to send messages and
interrupts back and forth between the ARM application CPUs and the ARISC
coprocessor. Add a device tree node for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 2abb335145a6..29ee8f0f833a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -447,6 +447,16 @@
 			reg = <0x1c14000 0x400>;
 		};
 
+		msgbox: mailbox@1c17000 {
+			compatible = "allwinner,sun50i-a64-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x01c17000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		usb_otg: usb@1c19000 {
 			compatible = "allwinner,sun8i-a33-musb";
 			reg = <0x01c19000 0x0400>;
-- 
2.19.2


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

* [PATCH v3 09/15] arm64: dts: allwinner: h6: Add msgbox node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (7 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 08/15] arm64: dts: allwinner: a64: " Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 10/15] [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM gates Samuel Holland
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

The H6 SoC contains a message box that can be used to send messages and
interrupts back and forth between the ARM application CPUs and the ARISC
coprocessor. Add a device tree node for it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d93a7add67e7..950681b2f7d9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -189,6 +189,16 @@
 			#interrupt-cells = <3>;
 		};
 
+		msgbox: mailbox@3003000 {
+			compatible = "allwinner,sun50i-h6-msgbox",
+				     "allwinner,sun6i-a31-msgbox";
+			reg = <0x03003000 0x1000>;
+			clocks = <&ccu CLK_BUS_MSGBOX>;
+			resets = <&ccu RST_BUS_MSGBOX>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		pio: pinctrl@300b000 {
 			compatible = "allwinner,sun50i-h6-pinctrl";
 			reg = <0x0300b000 0x400>;
-- 
2.19.2


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

* [PATCH v3 10/15] [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM gates
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (8 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 09/15] arm64: dts: allwinner: h6: " Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller Samuel Holland
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

Hardware attached to AHB0/APB0 and controlled in the PRCM is designed to
be used by firmware running on the ARISC core. However, some devices in
this block (specifically the I2C, RSB, PIO, and CIR-RX) have native
Linux drivers and are already in the device tree. In particular, the RSB
and I2C buses may have sound chips and display bridges hanging off of
them that cannot easily be driven from firmware.

To facilitate sharing this hardware block between Linux and system
firmware, avoid turning off PRCM clock gates that are unreferenced in
the device tree. We assume that firmware has already optimally
configured these clocks before booting Linux.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/clk/sunxi-ng/ccu-sun8i-r.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
index 90b3530e2c18..603de1e853e9 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -92,19 +92,19 @@ static struct ccu_div apb0_clk = {
 static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
 
 static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
-		      0x28, BIT(0), 0);
+		      0x28, BIT(0), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
-		      0x28, BIT(1), 0);
+		      0x28, BIT(1), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_timer_clk,	"apb0-timer",	"apb0",
-		      0x28, BIT(2), 0);
+		      0x28, BIT(2), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_rsb_clk,	"apb0-rsb",	"apb0",
-		      0x28, BIT(3), 0);
+		      0x28, BIT(3), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_uart_clk,	"apb0-uart",	"apb0",
-		      0x28, BIT(4), 0);
+		      0x28, BIT(4), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_i2c_clk,	"apb0-i2c",	"apb0",
-		      0x28, BIT(6), 0);
+		      0x28, BIT(6), CLK_IGNORE_UNUSED);
 static SUNXI_CCU_GATE(apb0_twd_clk,	"apb0-twd",	"apb0",
-		      0x28, BIT(7), 0);
+		      0x28, BIT(7), CLK_IGNORE_UNUSED);
 
 static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" };
 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
@@ -113,7 +113,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
 				  16, 2,	/* P */
 				  24, 2,	/* mux */
 				  BIT(31),	/* gate */
-				  0);
+				  CLK_IGNORE_UNUSED);
 
 static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" };
 static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = {
@@ -138,7 +138,7 @@ static struct ccu_mp a83t_ir_clk = {
 		.hw.init	= CLK_HW_INIT_PARENTS("ir",
 						      a83t_r_mod0_parents,
 						      &ccu_mp_ops,
-						      0),
+						      CLK_IGNORE_UNUSED),
 	},
 };
 
-- 
2.19.2


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

* [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (9 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 10/15] [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM gates Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-12 13:42   ` Rob Herring
  2019-03-02  4:29 ` [PATCH v3 12/15] [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip driver Samuel Holland
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

This is a somewhat generic binding for an interrupt controller/forwarder
implemented in firmware and communicated with using a mailbox.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 .../interrupt-controller/mbox-intc.txt        | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
new file mode 100644
index 000000000000..a0eb7904ca83
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
@@ -0,0 +1,33 @@
+Mailbox-backed Interrupt Controller
+===================================
+
+This binding represents an interrupt controller implemented in firmware,
+that uses a mailbox channel to signal and acknowledge interrupts.
+
+Device Node:
+============
+
+Required properties:
+--------------------
+- compatible:		Must be one of the following strings:
+			- allwinner,sunxi-msgbox-intc
+- interrupt-controller:	Signifies that this node is an interrupt controller.
+- #interrupt-cells:	Must be 1.
+- mboxes:		phandle for the mailbox controller and channel
+			specifier. If the mailbox controller has unidirectional
+			channels, two entries are required (see below).
+- mbox-names:		Only required for unidirectional mailbox channels. In
+			that case, it must contain the strings "tx" and "rx"
+			(where "tx" and "rx" are from Linux's perspective, not
+			the direction the interrupts are traveling).
+
+Example:
+--------
+
+	msgbox_intc: interrupt-controller {
+		compatible = "allwinner,sunxi-msgbox-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		mboxes = <&msgbox 6>, <&msgbox 7>;
+		mbox-names = "tx", "rx";
+	};
-- 
2.19.2


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

* [PATCH v3 12/15] [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip driver
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (10 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 13/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller node Samuel Holland
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

This driver implements a simple interrupt controller using message
passing over a mailbox channel. The intention is for the other end of
the channel to be implemented in firmware. This allows filtering and
forwarding interrupts from one processor to another.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/irqchip/Kconfig    |   9 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-mbox.c | 199 +++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)
 create mode 100644 drivers/irqchip/irq-mbox.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3d1e60779078..d22921276797 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -406,6 +406,15 @@ config IMX_IRQSTEER
 	help
 	  Support for the i.MX IRQSTEER interrupt multiplexer/remapper.
 
+config IRQ_MBOX
+	tristate "Simple mailbox-backed interrupt controller"
+	depends on MAILBOX
+	select IRQ_DOMAIN
+	help
+	  Support for interrupt controllers attached via a mailbox channel.
+	  This allows a coprocessor to inject interrupts via a simple
+	  message-based protocol.
+
 endmenu
 
 config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c93713d24b86..9de16ab4e69a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -94,3 +94,4 @@ obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
+obj-$(CONFIG_IRQ_MBOX)			+= irq-mbox.o
diff --git a/drivers/irqchip/irq-mbox.c b/drivers/irqchip/irq-mbox.c
new file mode 100644
index 000000000000..f7f6b47bc5b9
--- /dev/null
+++ b/drivers/irqchip/irq-mbox.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018-2019 Samuel Holland <samuel@sholland.org>
+
+/*
+ * Simple mailbox-backed interrupt controller driver using 32-bit messages.
+ * The mailbox controller is expected to take a (uint32_t *) message argument.
+ *
+ * Client-to-server messages:
+ *   Byte 3 (MSB) : Reserved
+ *   Byte 2       : Reserved
+ *   Byte 1       : Message type (enumerated below)
+ *   Byte 0 (LSB) : IRQ number
+ *
+ * Server-to-client messages:
+ *   Byte 3 (MSB) : Reserved
+ *   Byte 2       : Reserved
+ *   Byte 1       : Message type (must be zero == interrupt received)
+ *   Byte 0 (LSB) : IRQ number
+ *
+ * IRQ lines must be unmasked before they can be used (generic irqchip code
+ * takes care of that in this driver).
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+#define MBOX_INTC_MAX_IRQS 32
+
+enum {
+	MSG_EOI    = 0,
+	MSG_MASK   = 1,
+	MSG_UNMASK = 2,
+};
+
+struct mbox_intc {
+	struct irq_chip chip;
+	struct irq_domain *domain;
+	struct mbox_chan *rx_chan;
+	struct mbox_chan *tx_chan;
+	struct mbox_client cl;
+};
+
+static int mbox_intc_map(struct irq_domain *domain, unsigned int virq,
+			 irq_hw_number_t hwirq)
+{
+	struct mbox_intc *intc = domain->host_data;
+
+	if (hwirq >= MBOX_INTC_MAX_IRQS)
+		return -ENODEV;
+
+	irq_set_chip_data(virq, intc);
+	irq_set_chip_and_handler(virq, &intc->chip, handle_fasteoi_irq);
+	irq_set_status_flags(virq, IRQ_LEVEL);
+
+	return 0;
+}
+
+static const struct irq_domain_ops mbox_intc_domain_ops = {
+	.map   = mbox_intc_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static void mbox_intc_rx_callback(struct mbox_client *cl, void *msg)
+{
+	struct mbox_intc *intc = container_of(cl, struct mbox_intc, cl);
+	uint32_t hwirq = *(uint32_t *)msg;
+
+	if (hwirq >= MBOX_INTC_MAX_IRQS)
+		return;
+
+	generic_handle_irq(irq_linear_revmap(intc->domain, hwirq));
+}
+
+static void mbox_intc_tx_msg(struct irq_data *d, uint8_t request)
+{
+	struct mbox_intc *intc = irq_data_get_irq_chip_data(d);
+	uint32_t msg = (request << 8) | (d->hwirq & GENMASK(0, 7));
+
+	/* Since we don't expect an ACK for this message, immediately complete
+	 * the transmission. This ensures that each message is sent out without
+	 * sleeping, and 'data' remains in scope until actual transmission. */
+	if (mbox_send_message(intc->tx_chan, &msg) >= 0)
+		mbox_client_txdone(intc->tx_chan, 0);
+}
+
+static void mbox_intc_irq_mask(struct irq_data *d)
+{
+	mbox_intc_tx_msg(d, MSG_MASK);
+}
+
+static void mbox_intc_irq_unmask(struct irq_data *d)
+{
+	mbox_intc_tx_msg(d, MSG_UNMASK);
+}
+
+static void mbox_intc_irq_eoi(struct irq_data *d)
+{
+	mbox_intc_tx_msg(d, MSG_EOI);
+}
+
+static int mbox_intc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mbox_intc *intc;
+	int ret;
+
+	intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL);
+	if (!intc)
+		return -ENOMEM;
+
+	intc->cl.dev          = dev;
+	intc->cl.knows_txdone = true;
+	intc->cl.rx_callback  = mbox_intc_rx_callback;
+
+	if (of_get_property(dev->of_node, "mbox-names", NULL)) {
+		intc->rx_chan = mbox_request_channel_byname(&intc->cl, "rx");
+		if (IS_ERR(intc->rx_chan)) {
+			ret = PTR_ERR(intc->rx_chan);
+			dev_err(dev, "Failed to request rx mailbox channel\n");
+			goto err;
+		}
+		intc->tx_chan = mbox_request_channel_byname(&intc->cl, "tx");
+		if (IS_ERR(intc->tx_chan)) {
+			ret = PTR_ERR(intc->tx_chan);
+			dev_err(dev, "Failed to request tx mailbox channel\n");
+			goto err_free_rx_chan;
+		}
+	} else {
+		intc->rx_chan = mbox_request_channel(&intc->cl, 0);
+		intc->tx_chan = intc->rx_chan;
+		if (IS_ERR(intc->tx_chan)) {
+			ret = PTR_ERR(intc->tx_chan);
+			dev_err(dev, "Failed to request mailbox channel\n");
+			goto err;
+		}
+	}
+
+	intc->chip.name       = dev_name(dev);
+	intc->chip.irq_mask   = mbox_intc_irq_mask;
+	intc->chip.irq_unmask = mbox_intc_irq_unmask;
+	intc->chip.irq_eoi    = mbox_intc_irq_eoi;
+
+	intc->domain = irq_domain_add_linear(dev->of_node, MBOX_INTC_MAX_IRQS,
+					     &mbox_intc_domain_ops, intc);
+	if (IS_ERR(intc->domain)) {
+		ret = PTR_ERR(intc->domain);
+		dev_err(dev, "Failed to allocate IRQ domain: %d\n", ret);
+		goto err_free_tx_chan;
+	}
+
+	platform_set_drvdata(pdev, intc);
+
+	return 0;
+
+err_free_tx_chan:
+	if (intc->tx_chan != intc->rx_chan)
+		mbox_free_channel(intc->tx_chan);
+err_free_rx_chan:
+	mbox_free_channel(intc->rx_chan);
+err:
+	return ret;
+}
+
+static int mbox_intc_remove(struct platform_device *pdev)
+{
+	struct mbox_intc *intc = platform_get_drvdata(pdev);
+
+	irq_domain_remove(intc->domain);
+	if (intc->tx_chan != intc->rx_chan)
+		mbox_free_channel(intc->tx_chan);
+	mbox_free_channel(intc->rx_chan);
+
+	return 0;
+}
+
+static const struct of_device_id mbox_intc_of_match[] = {
+	{ .compatible = "allwinner,sunxi-msgbox-intc" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mbox_intc_of_match);
+
+static struct platform_driver mbox_intc_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = mbox_intc_of_match,
+	},
+	.probe  = mbox_intc_probe,
+	.remove = mbox_intc_remove,
+};
+module_platform_driver(mbox_intc_driver);
+
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_DESCRIPTION("Simple mailbox-backed interrupt controller");
+MODULE_LICENSE("GPL v2");
-- 
2.19.2


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

* [PATCH v3 13/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller node
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (11 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 12/15] [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip driver Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 14/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use msgbox_intc Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 15/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc Samuel Holland
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

In order to give firmware full access to r_intc, Linux needs to avoid
using it in the device tree. Most IRQ lines attached to r_intc are also
attached to the GIC. Unfortunately, the NMI is not. For it to be used in
Linux, we have to forward it in firmware over the mailbox.

Add a node representing this virtual interrupt controller.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 29ee8f0f833a..63e33215dea0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -128,6 +128,14 @@
 		status = "disabled";
 	};
 
+	msgbox_intc: interrupt-controller {
+		compatible = "allwinner,sunxi-msgbox-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		mboxes = <&msgbox 6>, <&msgbox 7>;
+		mbox-names = "tx", "rx";
+	};
+
 	osc24M: osc24M_clk {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
-- 
2.19.2


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

* [PATCH v3 14/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use msgbox_intc
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (12 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 13/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller node Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  2019-03-02  4:29 ` [PATCH v3 15/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc Samuel Holland
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

Now that there is an alternate way for Linux to receive NMIs from the
PMIC, replace references to r_intc with references to the new interrupt
controller.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts  | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts    | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts     | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts  | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts        | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts      | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi       | 4 ++--
 arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts       | 4 ++--
 9 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
index 6cb2b7f0c817..57690fc3f65e 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
@@ -78,8 +78,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 		x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
 	};
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
index 9d0afd7d50ec..0d5693710cb2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
@@ -214,8 +214,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 		x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
 	};
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
index 31884dbc8838..33d89c2d7b60 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
@@ -179,8 +179,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
index f7a4bccaa5d4..6f9da1cc6c79 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -169,8 +169,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 		x-powers,drive-vbus-en;	/* set N_VBUSEN as output pin */
 	};
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
index 8974b5a1d3b1..94bc6fadc58f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
@@ -186,8 +186,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 		x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
 	};
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 216f2f5db5ef..ceb6d7353cc7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -162,8 +162,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
index d22736a62481..02b5dfabc181 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -169,8 +169,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
index d2651f284aa0..9555dce6703b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
@@ -68,8 +68,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
index c455b24dd079..63aba1519ce3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -137,8 +137,8 @@
 	axp803: pmic@3a3 {
 		compatible = "x-powers,axp803";
 		reg = <0x3a3>;
-		interrupt-parent = <&r_intc>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&msgbox_intc>;
+		interrupts = <0>;
 		wakeup-source;
 	};
 };
-- 
2.19.2


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

* [PATCH v3 15/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc
  2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
                   ` (13 preceding siblings ...)
  2019-03-02  4:29 ` [PATCH v3 14/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use msgbox_intc Samuel Holland
@ 2019-03-02  4:29 ` Samuel Holland
  14 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-02  4:29 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel,
	linux-sunxi, Samuel Holland

Now that r_intc is no longer used directly by Linux, it can be removed
from the SoC device tree.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 63e33215dea0..163ee3576329 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -989,15 +989,6 @@
 			#clock-cells = <1>;
 		};
 
-		r_intc: interrupt-controller@1f00c00 {
-			compatible = "allwinner,sun50i-a64-r-intc",
-				     "allwinner,sun6i-a31-r-intc";
-			interrupt-controller;
-			#interrupt-cells = <2>;
-			reg = <0x01f00c00 0x400>;
-			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
 		r_ccu: clock@1f01400 {
 			compatible = "allwinner,sun50i-a64-r-ccu";
 			reg = <0x01f01400 0x100>;
-- 
2.19.2


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

* Re: [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: Add msgbox node
  2019-03-02  4:29 ` [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: " Samuel Holland
@ 2019-03-06  3:39   ` Samuel Holland
  0 siblings, 0 replies; 19+ messages in thread
From: Samuel Holland @ 2019-03-06  3:39 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland
  Cc: devicetree, linux-arm-kernel, linux-clk, linux-kernel, linux-sunxi

On 03/01/19 22:29, Samuel Holland wrote:
> The H3 and H5 SoCs contain a message box that can be used to send
> messages and interrupts back and forth between the ARM application CPUs
> and the ARISC coprocessor. Add a device tree node for it.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>
> ---
>  arch/arm/boot/dts/sunxi-h3-h5.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
> index a4c757c0b741..a42fd3f9739e 100644
> --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
> +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
> @@ -227,6 +227,16 @@
>  			#size-cells = <0>;
>  		};
>  
> +		msgbox: mailbox@1c17000 {
> +			compatible = "allwinner,sun8i-h3-msgbox",
> +				     "allwinner,sun6i-a31-msgbox";
> +			reg = <0x01c17000 0x1000>;
> +			clocks = <&ccu CLK_BUS_MSGBOX>;
> +			resets = <&ccu RST_BUS_MSGBOX>;
> +			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> +			#mbox-cells = <2>;

This should be 1. And it was caught by the new DTB schema validation :)

> +		};
> +
>  		usb_otg: usb@1c19000 {
>  			compatible = "allwinner,sun8i-h3-musb";
>  			reg = <0x01c19000 0x400>;
> 


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

* Re: [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding
  2019-03-02  4:29 ` [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding Samuel Holland
@ 2019-03-12 13:36   ` Rob Herring
  0 siblings, 0 replies; 19+ messages in thread
From: Rob Herring @ 2019-03-12 13:36 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Mark Rutland, devicetree, linux-arm-kernel,
	linux-clk, linux-kernel, linux-sunxi, Samuel Holland

On Fri,  1 Mar 2019 22:29:39 -0600, Samuel Holland wrote:
> This mailbox hardware is present in Allwinner sun8i, sun9i, and sun50i
> SoCs. Add a device tree binding for it.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>
> ---
>  .../mailbox/allwinner,sunxi-msgbox.yaml       | 79 +++++++++++++++++++
>  1 file changed, 79 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml
> 

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

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

* Re: [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller
  2019-03-02  4:29 ` [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller Samuel Holland
@ 2019-03-12 13:42   ` Rob Herring
  0 siblings, 0 replies; 19+ messages in thread
From: Rob Herring @ 2019-03-12 13:42 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Maxime Ripard, Chen-Yu Tsai, Jassi Brar, Michael Turquette,
	Stephen Boyd, Mark Rutland, devicetree, linux-arm-kernel,
	linux-clk, linux-kernel, linux-sunxi

On Fri, Mar 01, 2019 at 10:29:47PM -0600, Samuel Holland wrote:
> This is a somewhat generic binding for an interrupt controller/forwarder
> implemented in firmware and communicated with using a mailbox.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>
> ---
>  .../interrupt-controller/mbox-intc.txt        | 33 +++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
> new file mode 100644
> index 000000000000..a0eb7904ca83
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/mbox-intc.txt
> @@ -0,0 +1,33 @@
> +Mailbox-backed Interrupt Controller
> +===================================

Probably never really going to be generic as every mailbox protocol is 
different.

> +
> +This binding represents an interrupt controller implemented in firmware,
> +that uses a mailbox channel to signal and acknowledge interrupts.
> +
> +Device Node:
> +============
> +
> +Required properties:
> +--------------------
> +- compatible:		Must be one of the following strings:
> +			- allwinner,sunxi-msgbox-intc
> +- interrupt-controller:	Signifies that this node is an interrupt controller.
> +- #interrupt-cells:	Must be 1.

No edge/level control?

> +- mboxes:		phandle for the mailbox controller and channel
> +			specifier. If the mailbox controller has unidirectional
> +			channels, two entries are required (see below).
> +- mbox-names:		Only required for unidirectional mailbox channels. In
> +			that case, it must contain the strings "tx" and "rx"
> +			(where "tx" and "rx" are from Linux's perspective, not

/Linux/the OS/

> +			the direction the interrupts are traveling).
> +
> +Example:
> +--------
> +
> +	msgbox_intc: interrupt-controller {
> +		compatible = "allwinner,sunxi-msgbox-intc";
> +		interrupt-controller;
> +		#interrupt-cells = <1>;
> +		mboxes = <&msgbox 6>, <&msgbox 7>;
> +		mbox-names = "tx", "rx";
> +	};
> -- 
> 2.19.2
> 

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

end of thread, other threads:[~2019-03-12 13:42 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-02  4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
2019-03-02  4:29 ` [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical Samuel Holland
2019-03-02  4:29 ` [PATCH v3 02/15] clk: sunxi-ng: Mark AR100 " Samuel Holland
2019-03-02  4:29 ` [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding Samuel Holland
2019-03-12 13:36   ` Rob Herring
2019-03-02  4:29 ` [PATCH v3 04/15] mailbox: sunxi-msgbox: Add a new mailbox driver Samuel Holland
2019-03-02  4:29 ` [PATCH v3 05/15] ARM: dts: sunxi: a80: Add msgbox node Samuel Holland
2019-03-02  4:29 ` [PATCH v3 06/15] ARM: dts: sunxi: a83t: " Samuel Holland
2019-03-02  4:29 ` [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: " Samuel Holland
2019-03-06  3:39   ` Samuel Holland
2019-03-02  4:29 ` [PATCH v3 08/15] arm64: dts: allwinner: a64: " Samuel Holland
2019-03-02  4:29 ` [PATCH v3 09/15] arm64: dts: allwinner: h6: " Samuel Holland
2019-03-02  4:29 ` [PATCH v3 10/15] [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM gates Samuel Holland
2019-03-02  4:29 ` [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller Samuel Holland
2019-03-12 13:42   ` Rob Herring
2019-03-02  4:29 ` [PATCH v3 12/15] [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip driver Samuel Holland
2019-03-02  4:29 ` [PATCH v3 13/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller node Samuel Holland
2019-03-02  4:29 ` [PATCH v3 14/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use msgbox_intc Samuel Holland
2019-03-02  4:29 ` [PATCH v3 15/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc Samuel Holland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).