All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Support for Fujitsu MB86S7X SoCs
@ 2014-11-20 12:27 ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:27 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang

Hello,

  Fujitsu have a series of SoC already shipping based around
variations of 2xCA7+2xCA15 big.LITTLE architecture, and we would like
to upstream the basic support in this series.

  MB86S70 is a big.LITTLE platform with 2xCA7+2xCA15 and an additional
CM3 as the master. MB86S73 is a simple 2xCA7 and an additional CM3
master.

  The DT includes references to sdhci patches which are being sent to
  the mmc list at the same time.
  We welcome any comments or questions.

Thanks.

Vincent Yang (9):
  ARM: Add platform support for Fujitsu MB86S7X SoCs
  mailbox: arm_mhu: add driver for ARM MHU controller
  ARM: MB86S7X: Add MCPM support
  clk: Add clock driver for mb86s7x
  gpio: Add Fujitsu MB86S7x GPIO driver
  mmc: sdhci: host: add new f_sdh30
  dt: mb86s7x: add dt files for MB86S7x evbs
  of: add Fujitsu vendor prefix
  ARM: MB86S7x: Add configs

 Documentation/devicetree/bindings/arm/mb86s7x.txt  |   8 +
 .../bindings/clock/fujitsu,mb86s70-clk.txt         |  34 ++
 .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 +
 .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++
 .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 ++
 .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt    |  35 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/mb86s70.dtsi                     |  91 ++++
 arch/arm/boot/dts/mb86s70eb.dts                    |  52 ++
 arch/arm/boot/dts/mb86s73.dtsi                     |  49 ++
 arch/arm/boot/dts/mb86s73eb.dts                    |  39 ++
 arch/arm/boot/dts/mb86s7x.dtsi                     | 595 +++++++++++++++++++++
 arch/arm/configs/fujitsu_defconfig                 | 232 ++++++++
 arch/arm/configs/multi_v7_defconfig                |   5 +
 arch/arm/mach-mb86s7x/Kconfig                      |  19 +
 arch/arm/mach-mb86s7x/Makefile                     |   1 +
 arch/arm/mach-mb86s7x/board.c                      |  23 +
 arch/arm/mach-mb86s7x/mcpm.c                       | 360 +++++++++++++
 arch/arm/mach-mb86s7x/smc.S                        |  27 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-mb86s7x.c                          | 359 +++++++++++++
 drivers/gpio/Kconfig                               |   6 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mb86s7x.c                        | 211 ++++++++
 drivers/mailbox/Kconfig                            |   7 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/arm_mhu.c                          | 196 +++++++
 drivers/mmc/host/Kconfig                           |   9 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++
 drivers/soc/Makefile                               |   1 +
 drivers/soc/mb86s7x/Makefile                       |   4 +
 drivers/soc/mb86s7x/scb_mhu.c                      | 516 ++++++++++++++++++
 include/dt-bindings/clock/mb86s70-clk.h            |  22 +
 include/soc/mb86s7x/scb_mhu.h                      |  97 ++++
 39 files changed, 3420 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
 create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
 create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
 create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
 create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi
 create mode 100644 arch/arm/configs/fujitsu_defconfig
 create mode 100644 arch/arm/mach-mb86s7x/Kconfig
 create mode 100644 arch/arm/mach-mb86s7x/Makefile
 create mode 100644 arch/arm/mach-mb86s7x/board.c
 create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
 create mode 100644 arch/arm/mach-mb86s7x/smc.S
 create mode 100644 drivers/clk/clk-mb86s7x.c
 create mode 100644 drivers/gpio/gpio-mb86s7x.c
 create mode 100644 drivers/mailbox/arm_mhu.c
 create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
 create mode 100644 drivers/soc/mb86s7x/Makefile
 create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
 create mode 100644 include/dt-bindings/clock/mb86s70-clk.h
 create mode 100644 include/soc/mb86s7x/scb_mhu.h

-- 
1.9.0

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

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

* [PATCH 0/9] Support for Fujitsu MB86S7X SoCs
@ 2014-11-20 12:27 ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

  Fujitsu have a series of SoC already shipping based around
variations of 2xCA7+2xCA15 big.LITTLE architecture, and we would like
to upstream the basic support in this series.

  MB86S70 is a big.LITTLE platform with 2xCA7+2xCA15 and an additional
CM3 as the master. MB86S73 is a simple 2xCA7 and an additional CM3
master.

  The DT includes references to sdhci patches which are being sent to
  the mmc list at the same time.
  We welcome any comments or questions.

Thanks.

Vincent Yang (9):
  ARM: Add platform support for Fujitsu MB86S7X SoCs
  mailbox: arm_mhu: add driver for ARM MHU controller
  ARM: MB86S7X: Add MCPM support
  clk: Add clock driver for mb86s7x
  gpio: Add Fujitsu MB86S7x GPIO driver
  mmc: sdhci: host: add new f_sdh30
  dt: mb86s7x: add dt files for MB86S7x evbs
  of: add Fujitsu vendor prefix
  ARM: MB86S7x: Add configs

 Documentation/devicetree/bindings/arm/mb86s7x.txt  |   8 +
 .../bindings/clock/fujitsu,mb86s70-clk.txt         |  34 ++
 .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 +
 .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++
 .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 ++
 .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt    |  35 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/mb86s70.dtsi                     |  91 ++++
 arch/arm/boot/dts/mb86s70eb.dts                    |  52 ++
 arch/arm/boot/dts/mb86s73.dtsi                     |  49 ++
 arch/arm/boot/dts/mb86s73eb.dts                    |  39 ++
 arch/arm/boot/dts/mb86s7x.dtsi                     | 595 +++++++++++++++++++++
 arch/arm/configs/fujitsu_defconfig                 | 232 ++++++++
 arch/arm/configs/multi_v7_defconfig                |   5 +
 arch/arm/mach-mb86s7x/Kconfig                      |  19 +
 arch/arm/mach-mb86s7x/Makefile                     |   1 +
 arch/arm/mach-mb86s7x/board.c                      |  23 +
 arch/arm/mach-mb86s7x/mcpm.c                       | 360 +++++++++++++
 arch/arm/mach-mb86s7x/smc.S                        |  27 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-mb86s7x.c                          | 359 +++++++++++++
 drivers/gpio/Kconfig                               |   6 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mb86s7x.c                        | 211 ++++++++
 drivers/mailbox/Kconfig                            |   7 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/arm_mhu.c                          | 196 +++++++
 drivers/mmc/host/Kconfig                           |   9 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++
 drivers/soc/Makefile                               |   1 +
 drivers/soc/mb86s7x/Makefile                       |   4 +
 drivers/soc/mb86s7x/scb_mhu.c                      | 516 ++++++++++++++++++
 include/dt-bindings/clock/mb86s70-clk.h            |  22 +
 include/soc/mb86s7x/scb_mhu.h                      |  97 ++++
 39 files changed, 3420 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
 create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
 create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
 create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
 create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi
 create mode 100644 arch/arm/configs/fujitsu_defconfig
 create mode 100644 arch/arm/mach-mb86s7x/Kconfig
 create mode 100644 arch/arm/mach-mb86s7x/Makefile
 create mode 100644 arch/arm/mach-mb86s7x/board.c
 create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
 create mode 100644 arch/arm/mach-mb86s7x/smc.S
 create mode 100644 drivers/clk/clk-mb86s7x.c
 create mode 100644 drivers/gpio/gpio-mb86s7x.c
 create mode 100644 drivers/mailbox/arm_mhu.c
 create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
 create mode 100644 drivers/soc/mb86s7x/Makefile
 create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
 create mode 100644 include/dt-bindings/clock/mb86s70-clk.h
 create mode 100644 include/soc/mb86s7x/scb_mhu.h

-- 
1.9.0

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

* [PATCH 1/9] ARM: Add platform support for Fujitsu MB86S7X SoCs
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:30     ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:30 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

The MB86S7X is a bigLITTLE configuration of 2xCA7 & 2xCA15 under Linux.
And the remote master firmware (called SCB) running on CM3. Linux asks
for things to be done over Mailbox API, to SCB which controls most of
the important things. variations S70 & S73 are supported.

Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/mb86s7x.txt  |   8 +
 .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt    |  35 ++
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/mach-mb86s7x/Kconfig                      |  19 +
 arch/arm/mach-mb86s7x/Makefile                     |   1 +
 arch/arm/mach-mb86s7x/board.c                      |  23 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/mb86s7x/Makefile                       |   4 +
 drivers/soc/mb86s7x/scb_mhu.c                      | 516 +++++++++++++++++++++
 include/soc/mb86s7x/scb_mhu.h                      |  97 ++++
 12 files changed, 714 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
 create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
 create mode 100644 arch/arm/mach-mb86s7x/Kconfig
 create mode 100644 arch/arm/mach-mb86s7x/Makefile
 create mode 100644 arch/arm/mach-mb86s7x/board.c
 create mode 100644 drivers/soc/mb86s7x/Makefile
 create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
 create mode 100644 include/soc/mb86s7x/scb_mhu.h

diff --git a/Documentation/devicetree/bindings/arm/mb86s7x.txt b/Documentation/devicetree/bindings/arm/mb86s7x.txt
new file mode 100644
index 0000000..fbaad20
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mb86s7x.txt
@@ -0,0 +1,8 @@
+Fujitsu MB86S7X Device Tree Bindings
+
+Fujitsu has a few closely related platforms that are basically different
+configurations of each others. Like MB86S7{0,1,2,3}.
+
+The EVB boards with S70/S73 have the following property:
+Required root node property:
+	compatible: must contain "fujitsu,mb86s70-evb" or "fujitsu,mb86s73-evb"
diff --git a/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
new file mode 100644
index 0000000..ad6ebe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
@@ -0,0 +1,35 @@
+Fujitsu SCB (Mailbox's Remote Firmware) bindings
+------------------------------------------------
+
+The firmware (running of a remote Cortex-M3 master) on Fujitsu's MB86S7X
+platforms is named SCB. The SCB owns most of core h/w IPs like Clock,
+CPUFreq/DVFS, CPUIdle/SMP, Thermal, a recovery block device and even an
+I2C controller. Linux has to map all of these functionalities on to
+the Mailbox API and get things done by the remote master.
+ Let the current state of SCB firmware be versioned 1.0.
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-scb-1.0"
+- reg : Point to SharedMemory used for Mailbox protocol.
+- mboxes : phandle to the mailbox controller:channel node.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+	mhu: mhu0@2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+		clocks = <&clk_alw_2_1>;
+		clock-names = "clk";
+	};
+
+	mhu_client: scb@2e000000 {
+		compatible = "fujitsu,mb86s70-scb-1.0";
+		reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+		mboxes = <&mhu 1>;
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index c444907..34a1d0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1087,6 +1087,13 @@ M:	Lennert Buytenhek <kernel-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org>
 L:	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
 S:	Maintained
 
+ARM/MB86S7X SOC SUPPORT
+M:	Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
+M:	Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
+L:	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
+S:	Supported
+F:	arch/arm/mach-mb86s7x/
+
 ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
 M:	Santosh Shilimkar <ssantosh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
 L:	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 89c4b5c..4e0ce55 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -894,6 +894,8 @@ source "arch/arm/mach-keystone/Kconfig"
 
 source "arch/arm/mach-ks8695/Kconfig"
 
+source "arch/arm/mach-mb86s7x/Kconfig"
+
 source "arch/arm/mach-meson/Kconfig"
 
 source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 034a949..a7adf99 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 machine-$(CONFIG_ARCH_KS8695)		+= ks8695
 machine-$(CONFIG_ARCH_LPC32XX)		+= lpc32xx
+machine-$(CONFIG_ARCH_MB86S7X)		+= mb86s7x
 machine-$(CONFIG_ARCH_MESON)		+= meson
 machine-$(CONFIG_ARCH_MMP)		+= mmp
 machine-$(CONFIG_ARCH_MOXART)		+= moxart
diff --git a/arch/arm/mach-mb86s7x/Kconfig b/arch/arm/mach-mb86s7x/Kconfig
new file mode 100644
index 0000000..f58b104
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Kconfig
@@ -0,0 +1,19 @@
+config ARCH_MB86S7X
+	bool "Fujitsu MB86S7x platforms" if ARCH_MULTI_V7
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select ARM_CCI
+	select ARM_GIC
+	select ARM_TIMER_SP804
+	select BIG_LITTLE
+	select HAVE_ARM_ARCH_TIMER
+	select MAILBOX
+	select PINCTRL
+	select PINCTRL_MB86S7X
+	select PM_OPP
+	select ZONE_DMA if ARM_LPAE
+	help
+	  Support for Fujitsu MB86S7x based platforms
diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
new file mode 100644
index 0000000..97640b6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MB86S7X)	+= board.o
diff --git a/arch/arm/mach-mb86s7x/board.c b/arch/arm/mach-mb86s7x/board.c
new file mode 100644
index 0000000..02c2ea6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/board.c
@@ -0,0 +1,23 @@
+/*
+ * Support for the Fujitsu's MB86S7x based devices.
+ *
+ * Copyright (C) 2014 Linaro, LTD
+ *
+ * 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, version 2 of the License.
+ *
+ */
+
+#include <linux/of.h>
+#include <asm/mach/arch.h>
+
+static const char *mb86s7x_dt_match[] __initconst = {
+	"fujitsu,mb86s70-evb",
+	"fujitsu,mb86s73-evb",
+	NULL,
+};
+
+DT_MACHINE_START(MB86S7X_DT, "Fujitsu MB86S7X-based board")
+	.dt_compat	= mb86s7x_dt_match,
+MACHINE_END
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 063113d..fb64bf2 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_ARCH_MB86S7X)	+= mb86s7x/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
diff --git a/drivers/soc/mb86s7x/Makefile b/drivers/soc/mb86s7x/Makefile
new file mode 100644
index 0000000..f6b96cf
--- /dev/null
+++ b/drivers/soc/mb86s7x/Makefile
@@ -0,0 +1,4 @@
+#
+# Fujitsu's MB86S7X drivers
+#
+obj-$(CONFIG_ARCH_MB86S7X)	+= scb_mhu.o
diff --git a/drivers/soc/mb86s7x/scb_mhu.c b/drivers/soc/mb86s7x/scb_mhu.c
new file mode 100644
index 0000000..72070f1
--- /dev/null
+++ b/drivers/soc/mb86s7x/scb_mhu.c
@@ -0,0 +1,516 @@
+/*
+ * arch/arm/mach-mb86s7x/scb_mhu.c Shim 'server' for Mailbox clients
+ *
+ * Created by: Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Copyright:	(C) 2013-2014 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <asm/system_misc.h>
+
+#define INTR_STAT_OFS	0x0
+#define INTR_SET_OFS	0x8
+#define INTR_CLR_OFS	0x10
+
+static LIST_HEAD(free_xfers);
+static LIST_HEAD(pending_xfers);
+static DEFINE_SPINLOCK(fsm_lock);
+static struct completion fsm_rsp;
+static struct mbox_client mhu_cl;
+static struct mbox_chan *mhu_chan;
+static mb86s7x_mhu_handler_t handler[MHU_NUM_CMDS];
+
+void __iomem *mhu_base, *mb86s7x_shm_base;
+static void __iomem *cmd_to_scb, *rsp_to_scb;
+static void __iomem *cmd_from_scb, *rsp_from_scb;
+
+static enum {
+	MHU_PARK = 0,
+	MHU_WRR, /* Waiting to get Remote's Reply */
+	MHU_WRL, /* Waiting to send Reply */
+	MHU_WRRL, /* WAIT_Ra && WAIT_Rb */
+	MHU_INVLD,
+} fsm_state;
+
+enum fsm_event {
+	EV_LC = 0, /* Local sent a command */
+	EV_RC, /* Remote sent a command */
+	EV_RR, /* Remote sent a reply */
+	EV_LR, /* Local sent a reply */
+};
+
+static int mhu_fsm[4][4] = {
+	[MHU_PARK] = {
+		[EV_LC] = MHU_WRR,
+		[EV_RC] = MHU_WRL,
+		[EV_RR] = MHU_INVLD,
+		[EV_LR] = MHU_INVLD,
+	},
+	[MHU_WRR] = {
+		[EV_LC] = MHU_INVLD,
+		[EV_RC] = MHU_WRRL,
+		[EV_RR] = MHU_PARK,
+		[EV_LR] = MHU_INVLD,
+	},
+	[MHU_WRL] = {
+		[EV_LC] = MHU_WRRL,
+		[EV_RC] = MHU_INVLD,
+		[EV_RR] = MHU_INVLD,
+		[EV_LR] = MHU_PARK,
+	},
+	[MHU_WRRL] = {
+		[EV_LC] = MHU_INVLD,
+		[EV_RC] = MHU_INVLD,
+		[EV_RR] = MHU_WRL,
+		[EV_LR] = MHU_WRR,
+	},
+};
+
+struct mhu_xfer {
+	int code;
+	int len;
+	void *buf;
+	struct completion *c;
+	struct list_head node;
+};
+
+static struct mhu_xfer *ax; /* stages of xfer */
+
+static int mhu_alloc_xfers(int n, struct list_head *list)
+{
+	struct mhu_xfer *x = kcalloc(n, sizeof(struct mhu_xfer), GFP_ATOMIC);
+	int i;
+
+	if (!x)
+		return -ENOMEM;
+
+	for (i = 0; i < n; i++)
+		list_add(&x[i].node, &free_xfers);
+
+	return 0;
+}
+
+static void got_data(u32 code)
+{
+	mb86s7x_mhu_handler_t hndlr = NULL;
+	unsigned long flags;
+	int ev;
+
+	if (code & RESP_BIT)
+		ev = EV_RR;
+	else
+		ev = EV_RC;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		pr_err("State-%d EV-%d FSM Broken!\n", fsm_state, ev);
+		return;
+	}
+	fsm_state = mhu_fsm[fsm_state][ev];
+
+	if (code & RESP_BIT) {
+		memcpy_fromio(ax->buf, rsp_from_scb, ax->len);
+		if (ax->c)
+			complete(ax->c);
+		list_move(&ax->node, &free_xfers);
+		ax = NULL;
+	} else {
+		/* Find and dispatch relevant registered handler */
+		if (code < MHU_NUM_CMDS)
+			hndlr = handler[code];
+		if (hndlr)
+			hndlr(code, cmd_from_scb);
+		else
+			pr_err("No handler for CMD_%u\n", code);
+	}
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+}
+
+static int do_xfer(void)
+{
+	unsigned long flags;
+	struct mhu_xfer *x;
+	int ev, code;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (list_empty(&pending_xfers)) {
+		struct mbox_chan *_ch = NULL;
+		int cmd;
+
+		for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+			;
+		/* Don't free channel if any user is listening */
+		if (cmd != MHU_NUM_CMDS) {
+			spin_unlock_irqrestore(&fsm_lock, flags);
+			return 0;
+		}
+
+		if (fsm_state == MHU_PARK) {
+			_ch = mhu_chan;
+			mhu_chan = NULL;
+		}
+
+		spin_unlock_irqrestore(&fsm_lock, flags);
+
+		if (_ch)
+			mbox_free_channel(_ch);
+
+		return 0;
+	}
+
+	x = list_first_entry(&pending_xfers, struct mhu_xfer, node);
+	code = x->code;
+
+	ev = code & RESP_BIT ? EV_LR : EV_LC;
+	if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		return 1;
+	}
+	list_del_init(&x->node);
+
+	/* Layout the SHM */
+	if (code & RESP_BIT)
+		memcpy_toio(rsp_to_scb, x->buf, x->len);
+	else
+		memcpy_toio(cmd_to_scb, x->buf, x->len);
+
+	if (ev == EV_LC)
+		ax = x;
+	else
+		list_move(&x->node, &free_xfers);
+	fsm_state = mhu_fsm[fsm_state][ev];
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	/* Prefer mailbox API */
+	if (!mhu_chan) {
+		struct mbox_chan *_ch;
+
+		_ch = mbox_request_channel(&mhu_cl, 0);
+		if (!IS_ERR(_ch))
+			mhu_chan = _ch;
+	}
+
+	if (mhu_chan) {
+		int ret;
+
+		init_completion(&fsm_rsp);
+
+		/* Send via generic api */
+		ret = mbox_send_message(mhu_chan, (void *)code);
+		if (ret < 0) {
+			pr_err("%s:%d CMD_%d Send Failed\n",
+			       __func__, __LINE__, code);
+			BUG();
+		}
+		if (!(code & RESP_BIT)) {
+			ret = wait_for_completion_timeout(&fsm_rsp,
+						msecs_to_jiffies(1000));
+			if (!ret) {
+				pr_err("%s:%d CMD_%d Got No Reply\n",
+				       __func__, __LINE__, code);
+				BUG();
+			}
+			got_data(ax->code);
+		}
+	} else {
+		void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+		void __iomem *rx_reg = mhu_base + 0x20; /* HP-NonSec */
+		u32 val, count;
+
+		/* Send via early-boot api */
+		val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+		if (val) {
+			pr_err("Last CMD not yet read by SCB\n");
+			writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+		}
+
+		writel_relaxed(x->code, tx_reg + INTR_SET_OFS);
+
+		/* Wait until this message is read */
+		count = 0x1000000;
+		do {
+			cpu_relax();
+			val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+		} while (--count && val);
+		if (val)
+			pr_err("%s:%d SCB not listening!\n",
+			       __func__, __LINE__);
+
+		if (!ax) {
+			/* A quick poll for pending remote cmd */
+			val = readl_relaxed(rx_reg + INTR_STAT_OFS);
+			if (val) {
+				got_data(val);
+				writel_relaxed(val, rx_reg + INTR_CLR_OFS);
+			}
+		} else {
+			do {
+				/* Wait until we get reply */
+				count = 0x1000000;
+				do {
+					cpu_relax();
+					val = readl_relaxed(
+						rx_reg + INTR_STAT_OFS);
+				} while (--count && !val);
+
+				if (val) {
+					got_data(val);
+					writel_relaxed(val,
+						     rx_reg + INTR_CLR_OFS);
+				} else {
+					pr_err("%s:%d SCB didn't reply\n",
+					       __func__, __LINE__);
+					return 1;
+				}
+			} while (!(val & RESP_BIT));
+		}
+		if (list_empty(&pending_xfers))
+			return 0;
+	}
+
+	return do_xfer();
+}
+
+static void mhu_recv(struct mbox_client *cl, void *data)
+{
+	if ((u32)data & RESP_BIT) {
+		/* Now that we got a reply to last TX, that
+		 * must mean the last TX was successful */
+		mbox_client_txdone(mhu_chan, 0);
+
+		ax->code = (u32)data; /* Save response */
+		complete(&fsm_rsp);
+		return;
+	}
+
+	got_data((u32)data);
+}
+
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+	if (cmd < MHU_NUM_CMDS && !handler[cmd]) {
+		ret = 0;
+		handler[cmd] = hndlr;
+	}
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	if (!mhu_chan) {
+		struct mbox_chan *_ch;
+
+		_ch = mbox_request_channel(&mhu_cl, 0);
+		if (!IS_ERR(_ch))
+			mhu_chan = _ch;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_set);
+
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (cmd < MHU_NUM_CMDS && handler[cmd] == hndlr)
+		handler[cmd] = NULL;
+
+	if (list_empty(&pending_xfers)) {
+		struct mbox_chan *_ch = NULL;
+
+		for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+			;
+		/* Don't free channel if any user is listening */
+		if (cmd != MHU_NUM_CMDS) {
+			spin_unlock_irqrestore(&fsm_lock, flags);
+			return;
+		}
+
+		if (fsm_state == MHU_PARK) {
+			_ch = mhu_chan;
+			mhu_chan = NULL;
+		}
+
+		spin_unlock_irqrestore(&fsm_lock, flags);
+
+		if (_ch)
+			mbox_free_channel(_ch);
+
+		return;
+	}
+	spin_unlock_irqrestore(&fsm_lock, flags);
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_clr);
+
+static int setup_mhu(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "arm,mbox-mhu");
+	mhu_base = of_iomap(node, 0);
+	if (mhu_base == NULL) {
+		pr_err("Can't work without MHU\n");
+		return -ENODEV;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+	mb86s7x_shm_base = of_iomap(node, 0);
+	if (mb86s7x_shm_base == NULL) {
+		pr_err("Can't work without SHM SRAM\n");
+		return -ENODEV;
+	}
+
+	cmd_from_scb = mb86s7x_shm_base + 0x3800;
+	rsp_from_scb = mb86s7x_shm_base + 0x3900;
+	cmd_to_scb = mb86s7x_shm_base + 0x3a00;
+	rsp_to_scb = mb86s7x_shm_base + 0x3b00;
+
+	return 0;
+}
+
+int mb86s7x_send_packet(int code, void *buf, int len)
+{
+	struct completion got_rsp;
+	unsigned long flags;
+	struct mhu_xfer *x;
+	int ret;
+
+	/*
+	 * The first caller could be as early as system clocksource,
+	 * when the platform devices are not populated yet.
+	 */
+	if (unlikely(!mb86s7x_shm_base) && setup_mhu())
+		return -ENODEV;
+
+	if ((code & ~0xff) || ((code & RESP_BIT)
+				&& fsm_state != MHU_WRRL
+				&& fsm_state != MHU_WRL)) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	init_completion(&got_rsp);
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (list_empty(&free_xfers) && mhu_alloc_xfers(5, &free_xfers)) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		pr_err("%s:%d OOM\n", __func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	x = list_first_entry(&free_xfers, struct mhu_xfer, node);
+	x->code = code;
+	x->buf = buf;
+	x->len = len;
+	x->c = &got_rsp;
+
+	if (code & RESP_BIT)
+		list_move(&x->node, &pending_xfers);
+	else
+		list_move_tail(&x->node, &pending_xfers);
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	ret = do_xfer();
+	if (ret > 0) {
+		ret = wait_for_completion_timeout(&got_rsp,
+						  msecs_to_jiffies(1000));
+		return ret ? 0 : -EIO;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_send_packet);
+
+struct mb86s7x_hard_reset {
+	u32 payload_size;
+	u32 delay;
+};
+
+static void mb86s7x_reboot(u32 delay)
+{
+	void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+	struct mb86s7x_hard_reset cmd;
+	u32 val;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.delay = delay;
+
+	val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+	if (val) /* Flush anything pending */
+		writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+
+	memcpy_toio(cmd_to_scb, &cmd, sizeof(cmd));
+	writel_relaxed(CMD_HARD_RESET_REQ, tx_reg + INTR_SET_OFS);
+}
+
+static void
+mb86s7x_restart(enum reboot_mode reboot_mode, const char *unused)
+{
+	/* Reboot immediately (after 50ms) */
+	mb86s7x_reboot(50);
+}
+
+static void mb86s7x_poweroff(void)
+{
+	/* Reboot never, remain dead */
+	mb86s7x_reboot(~0);
+}
+
+static int f_scb_probe(struct platform_device *pdev)
+{
+	mhu_cl.tx_block = true;
+	mhu_cl.knows_txdone = true;
+	mhu_cl.rx_callback = mhu_recv;
+	mhu_cl.dev = &pdev->dev;
+
+	arm_pm_restart = mb86s7x_restart;
+	pm_power_off = mb86s7x_poweroff;
+
+	return 0;
+}
+
+static const struct of_device_id scb_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-scb-1.0" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, scb_dt_ids);
+
+static struct platform_driver f_scb_driver = {
+	.driver		= {
+		.name	= "f_scb",
+		.of_match_table = scb_dt_ids,
+	},
+	.probe = f_scb_probe,
+};
+
+static int __init f_scb_init(void)
+{
+	return platform_driver_register(&f_scb_driver);
+}
+module_init(f_scb_init);
diff --git a/include/soc/mb86s7x/scb_mhu.h b/include/soc/mb86s7x/scb_mhu.h
new file mode 100644
index 0000000..a7e3484
--- /dev/null
+++ b/include/soc/mb86s7x/scb_mhu.h
@@ -0,0 +1,97 @@
+/*
+ * include/soc/mb86s7x/scb_mhu.h
+ *
+ * Created by: Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Copyright:	(C) 2013-2014 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef __MB86S7X_SCB_MHU_H
+#define __MB86S7X_SCB_MHU_H
+
+#define CMD_MASK    0x7f    /* 128 possible commands */
+#define RESP_BIT    (1 << 7) /* If it's a response */
+
+#define ENC_CMD(c)  ((c) & CMD_MASK)
+#define DEC_CMD(v)  (((v) & ~CMD_MASK) ? CMD_INVALID : ((v) & CMD_MASK))
+
+#define ENC_REP(r)  (((r) & CMD_MASK) | RESP_BIT)
+
+/* If v is the reply to command c */
+#define IS_A_REP(v, c)  (((v) & RESP_BIT) && (((v) & CMD_MASK) == (c)))
+
+enum {
+	CMD_INVALID = 0,
+	CMD_I2C_XFER_REQ = 1,
+	CMD_PERI_POWER_SET_REQ = 2,
+	CMD_PERI_CLOCK_GATE_SET_REQ = 3,
+	CMD_PERI_CLOCK_GATE_GET_REQ = 4,
+	CMD_PERI_CLOCK_RATE_SET_REQ = 5,
+	CMD_PERI_CLOCK_RATE_GET_REQ = 6,
+	CMD_CPU_CLOCK_GATE_SET_REQ = 7,
+	CMD_CPU_CLOCK_GATE_GET_REQ = 8,
+	CMD_CPU_CLOCK_RATE_SET_REQ = 9,
+	CMD_CPU_CLOCK_RATE_GET_REQ = 0xa,
+	CMD_CLUSTER_OPP_GET_REQ = 0xb,
+	CMD_CLOCK_DSI_PIXEL_REQ = 0xc,
+	CMD_SCB_CAPABILITY_GET_REQ = 0xd,
+	CMD_SYS_RESET_CAUSE_GET_REQ = 0xe,
+	CMD_SYS_SPECIFIC_INFO_GET_REQ = 0xf,
+	CMD_REBOOT_AP_AFTER_REQ = 0x10,
+	CMD_TAIKI_REQ = 0x11,
+	CMD_TAIKI_ASYNC_MSG_REQ = 0x12,
+	CMD_GET_WORD_REQ = 0x13,
+	CMD_HARD_RESET_REQ = 0x14,
+	CMD_MAINTENANCE_MODE_REQ = 0x15,
+	CMD_STG_GET_SIZE_REQ = 0x16,
+	CMD_STG_BLOCK_READ_REQ = 0x17,
+	CMD_STG_BLOCK_WRITE_REQ = 0x18,
+	CMD_MEMORY_LAYOUT_GET_REQ = 0x19,
+	CMD_POWERDOMAIN_GET_REQ = 0x1a,
+	CMD_POWERDOMAIN_SET_REQ = 0x1b,
+	CMD_STG_BLOCK_ERASE_REQ = 0x1c,
+
+	/* Do NOT add new commands below this line */
+	MHU_NUM_CMDS,
+};
+
+#define CMD_I2C_XFER_REP	ENC_REP(CMD_I2C_XFER_REQ)
+#define CMD_PERI_POWER_SET_REP	ENC_REP(CMD_PERI_POWER_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_SET_REP	ENC_REP(CMD_PERI_CLOCK_GATE_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_GET_REP	ENC_REP(CMD_PERI_CLOCK_GATE_GET_REQ)
+#define CMD_PERI_CLOCK_RATE_SET_REP	ENC_REP(CMD_PERI_CLOCK_RATE_SET_REQ)
+#define CMD_PERI_CLOCK_RATE_GET_REP	ENC_REP(CMD_PERI_CLOCK_RATE_GET_REQ)
+#define CMD_CPU_CLOCK_GATE_SET_REP	ENC_REP(CMD_CPU_CLOCK_GATE_SET_REQ)
+#define CMD_CPU_CLOCK_GATE_GET_REP	ENC_REP(CMD_CPU_CLOCK_GATE_GET_REQ)
+#define CMD_CPU_CLOCK_RATE_SET_REP	ENC_REP(CMD_CPU_CLOCK_RATE_SET_REQ)
+#define CMD_CPU_CLOCK_RATE_GET_REP	ENC_REP(CMD_CPU_CLOCK_RATE_GET_REQ)
+#define CMD_CLUSTER_OPP_GET_REP	ENC_REP(CMD_CLUSTER_OPP_GET_REQ)
+#define CMD_CLOCK_DSI_PIXEL_REP	ENC_REP(CMD_CLOCK_DSI_PIXEL_REQ)
+#define CMD_SCB_CAPABILITY_GET_REP	ENC_REP(CMD_SCB_CAPABILITY_GET_REQ)
+#define CMD_SYS_RESET_CAUSE_GET_REP	ENC_REP(CMD_SYS_RESET_CAUSE_GET_REQ)
+#define CMD_SYS_SPECIFIC_INFO_GET_REP	ENC_REP(CMD_SYS_SPECIFIC_INFO_GET_REQ)
+#define CMD_GET_WORD_REP	ENC_REP(CMD_GET_WORD_REQ)
+#define CMD_REBOOT_AP_AFTER_REP	ENC_REP(CMD_REBOOT_AP_AFTER_REQ)
+#define CMD_TAIKI_REP			ENC_REP(CMD_TAIKI_REQ)
+#define CMD_TAIKI_ASYNC_MSG_REP		ENC_REP(CMD_TAIKI_ASYNC_MSG_REQ)
+#define CMD_HARD_RESET_REP		ENC_REP(CMD_HARD_RESET_REQ)
+#define CMD_MAINTENANCE_MODE_REP	ENC_RSP(CMD_MAINTENANCE_MODE_REQ)
+#define CMD_STG_GET_SIZE_REP		ENC_REP(CMD_STG_GET_SIZE_REQ)
+#define CMD_STG_BLOCK_READ_REP		ENC_REP(CMD_STG_BLOCK_READ_REQ)
+#define CMD_STG_BLOCK_WRITE_REP		ENC_REP(CMD_STG_BLOCK_WRITE_REQ)
+#define CMD_MEMORY_LAYOUT_GET_REP	ENC_REP(CMD_MEMORY_LAYOUT_GET_REQ)
+#define CMD_POWERDOMAIN_GET_REP		ENC_REP(CMD_POWERDOMAIN_GET_REQ)
+#define CMD_POWERDOMAIN_SET_REP		ENC_REP(CMD_POWERDOMAIN_SET_REQ)
+#define CMD_STG_BLOCK_ERASE_REP		ENC_REP(CMD_STG_BLOCK_ERASE_REQ)
+
+/* Helper functions to talk to remote */
+int mb86s7x_send_packet(int cmd, void *buf, int len);
+
+typedef void (*mb86s7x_mhu_handler_t)(u32 cmd, u8 rcbuf[]);
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t);
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t);
+
+#endif /* __MB86S7X_SCB_MHU_H */
-- 
1.9.0

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

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

* [PATCH 1/9] ARM: Add platform support for Fujitsu MB86S7X SoCs
@ 2014-11-20 12:30     ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:30 UTC (permalink / raw)
  To: linux-arm-kernel

The MB86S7X is a bigLITTLE configuration of 2xCA7 & 2xCA15 under Linux.
And the remote master firmware (called SCB) running on CM3. Linux asks
for things to be done over Mailbox API, to SCB which controls most of
the important things. variations S70 & S73 are supported.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 Documentation/devicetree/bindings/arm/mb86s7x.txt  |   8 +
 .../devicetree/bindings/soc/mb86s7x/scb_mhu.txt    |  35 ++
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/mach-mb86s7x/Kconfig                      |  19 +
 arch/arm/mach-mb86s7x/Makefile                     |   1 +
 arch/arm/mach-mb86s7x/board.c                      |  23 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/mb86s7x/Makefile                       |   4 +
 drivers/soc/mb86s7x/scb_mhu.c                      | 516 +++++++++++++++++++++
 include/soc/mb86s7x/scb_mhu.h                      |  97 ++++
 12 files changed, 714 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
 create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
 create mode 100644 arch/arm/mach-mb86s7x/Kconfig
 create mode 100644 arch/arm/mach-mb86s7x/Makefile
 create mode 100644 arch/arm/mach-mb86s7x/board.c
 create mode 100644 drivers/soc/mb86s7x/Makefile
 create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
 create mode 100644 include/soc/mb86s7x/scb_mhu.h

diff --git a/Documentation/devicetree/bindings/arm/mb86s7x.txt b/Documentation/devicetree/bindings/arm/mb86s7x.txt
new file mode 100644
index 0000000..fbaad20
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mb86s7x.txt
@@ -0,0 +1,8 @@
+Fujitsu MB86S7X Device Tree Bindings
+
+Fujitsu has a few closely related platforms that are basically different
+configurations of each others. Like MB86S7{0,1,2,3}.
+
+The EVB boards with S70/S73 have the following property:
+Required root node property:
+	compatible: must contain "fujitsu,mb86s70-evb" or "fujitsu,mb86s73-evb"
diff --git a/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
new file mode 100644
index 0000000..ad6ebe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
@@ -0,0 +1,35 @@
+Fujitsu SCB (Mailbox's Remote Firmware) bindings
+------------------------------------------------
+
+The firmware (running of a remote Cortex-M3 master) on Fujitsu's MB86S7X
+platforms is named SCB. The SCB owns most of core h/w IPs like Clock,
+CPUFreq/DVFS, CPUIdle/SMP, Thermal, a recovery block device and even an
+I2C controller. Linux has to map all of these functionalities on to
+the Mailbox API and get things done by the remote master.
+ Let the current state of SCB firmware be versioned 1.0.
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-scb-1.0"
+- reg : Point to SharedMemory used for Mailbox protocol.
+- mboxes : phandle to the mailbox controller:channel node.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+	mhu: mhu0 at 2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+		clocks = <&clk_alw_2_1>;
+		clock-names = "clk";
+	};
+
+	mhu_client: scb at 2e000000 {
+		compatible = "fujitsu,mb86s70-scb-1.0";
+		reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+		mboxes = <&mhu 1>;
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index c444907..34a1d0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1087,6 +1087,13 @@ M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 
+ARM/MB86S7X SOC SUPPORT
+M:	Vincent Yang <Vincent.Yang@tw.fujitsu.com>
+M:	Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Supported
+F:	arch/arm/mach-mb86s7x/
+
 ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
 M:	Santosh Shilimkar <ssantosh@kernel.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 89c4b5c..4e0ce55 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -894,6 +894,8 @@ source "arch/arm/mach-keystone/Kconfig"
 
 source "arch/arm/mach-ks8695/Kconfig"
 
+source "arch/arm/mach-mb86s7x/Kconfig"
+
 source "arch/arm/mach-meson/Kconfig"
 
 source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 034a949..a7adf99 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 machine-$(CONFIG_ARCH_KS8695)		+= ks8695
 machine-$(CONFIG_ARCH_LPC32XX)		+= lpc32xx
+machine-$(CONFIG_ARCH_MB86S7X)		+= mb86s7x
 machine-$(CONFIG_ARCH_MESON)		+= meson
 machine-$(CONFIG_ARCH_MMP)		+= mmp
 machine-$(CONFIG_ARCH_MOXART)		+= moxart
diff --git a/arch/arm/mach-mb86s7x/Kconfig b/arch/arm/mach-mb86s7x/Kconfig
new file mode 100644
index 0000000..f58b104
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Kconfig
@@ -0,0 +1,19 @@
+config ARCH_MB86S7X
+	bool "Fujitsu MB86S7x platforms" if ARCH_MULTI_V7
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select ARM_CCI
+	select ARM_GIC
+	select ARM_TIMER_SP804
+	select BIG_LITTLE
+	select HAVE_ARM_ARCH_TIMER
+	select MAILBOX
+	select PINCTRL
+	select PINCTRL_MB86S7X
+	select PM_OPP
+	select ZONE_DMA if ARM_LPAE
+	help
+	  Support for Fujitsu MB86S7x based platforms
diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
new file mode 100644
index 0000000..97640b6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MB86S7X)	+= board.o
diff --git a/arch/arm/mach-mb86s7x/board.c b/arch/arm/mach-mb86s7x/board.c
new file mode 100644
index 0000000..02c2ea6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/board.c
@@ -0,0 +1,23 @@
+/*
+ * Support for the Fujitsu's MB86S7x based devices.
+ *
+ * Copyright (C) 2014 Linaro, LTD
+ *
+ * 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, version 2 of the License.
+ *
+ */
+
+#include <linux/of.h>
+#include <asm/mach/arch.h>
+
+static const char *mb86s7x_dt_match[] __initconst = {
+	"fujitsu,mb86s70-evb",
+	"fujitsu,mb86s73-evb",
+	NULL,
+};
+
+DT_MACHINE_START(MB86S7X_DT, "Fujitsu MB86S7X-based board")
+	.dt_compat	= mb86s7x_dt_match,
+MACHINE_END
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 063113d..fb64bf2 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_ARCH_MB86S7X)	+= mb86s7x/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
diff --git a/drivers/soc/mb86s7x/Makefile b/drivers/soc/mb86s7x/Makefile
new file mode 100644
index 0000000..f6b96cf
--- /dev/null
+++ b/drivers/soc/mb86s7x/Makefile
@@ -0,0 +1,4 @@
+#
+# Fujitsu's MB86S7X drivers
+#
+obj-$(CONFIG_ARCH_MB86S7X)	+= scb_mhu.o
diff --git a/drivers/soc/mb86s7x/scb_mhu.c b/drivers/soc/mb86s7x/scb_mhu.c
new file mode 100644
index 0000000..72070f1
--- /dev/null
+++ b/drivers/soc/mb86s7x/scb_mhu.c
@@ -0,0 +1,516 @@
+/*
+ * arch/arm/mach-mb86s7x/scb_mhu.c Shim 'server' for Mailbox clients
+ *
+ * Created by: Jassi Brar <jassisinghbrar@gmail.com>
+ * Copyright:	(C) 2013-2014 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <asm/system_misc.h>
+
+#define INTR_STAT_OFS	0x0
+#define INTR_SET_OFS	0x8
+#define INTR_CLR_OFS	0x10
+
+static LIST_HEAD(free_xfers);
+static LIST_HEAD(pending_xfers);
+static DEFINE_SPINLOCK(fsm_lock);
+static struct completion fsm_rsp;
+static struct mbox_client mhu_cl;
+static struct mbox_chan *mhu_chan;
+static mb86s7x_mhu_handler_t handler[MHU_NUM_CMDS];
+
+void __iomem *mhu_base, *mb86s7x_shm_base;
+static void __iomem *cmd_to_scb, *rsp_to_scb;
+static void __iomem *cmd_from_scb, *rsp_from_scb;
+
+static enum {
+	MHU_PARK = 0,
+	MHU_WRR, /* Waiting to get Remote's Reply */
+	MHU_WRL, /* Waiting to send Reply */
+	MHU_WRRL, /* WAIT_Ra && WAIT_Rb */
+	MHU_INVLD,
+} fsm_state;
+
+enum fsm_event {
+	EV_LC = 0, /* Local sent a command */
+	EV_RC, /* Remote sent a command */
+	EV_RR, /* Remote sent a reply */
+	EV_LR, /* Local sent a reply */
+};
+
+static int mhu_fsm[4][4] = {
+	[MHU_PARK] = {
+		[EV_LC] = MHU_WRR,
+		[EV_RC] = MHU_WRL,
+		[EV_RR] = MHU_INVLD,
+		[EV_LR] = MHU_INVLD,
+	},
+	[MHU_WRR] = {
+		[EV_LC] = MHU_INVLD,
+		[EV_RC] = MHU_WRRL,
+		[EV_RR] = MHU_PARK,
+		[EV_LR] = MHU_INVLD,
+	},
+	[MHU_WRL] = {
+		[EV_LC] = MHU_WRRL,
+		[EV_RC] = MHU_INVLD,
+		[EV_RR] = MHU_INVLD,
+		[EV_LR] = MHU_PARK,
+	},
+	[MHU_WRRL] = {
+		[EV_LC] = MHU_INVLD,
+		[EV_RC] = MHU_INVLD,
+		[EV_RR] = MHU_WRL,
+		[EV_LR] = MHU_WRR,
+	},
+};
+
+struct mhu_xfer {
+	int code;
+	int len;
+	void *buf;
+	struct completion *c;
+	struct list_head node;
+};
+
+static struct mhu_xfer *ax; /* stages of xfer */
+
+static int mhu_alloc_xfers(int n, struct list_head *list)
+{
+	struct mhu_xfer *x = kcalloc(n, sizeof(struct mhu_xfer), GFP_ATOMIC);
+	int i;
+
+	if (!x)
+		return -ENOMEM;
+
+	for (i = 0; i < n; i++)
+		list_add(&x[i].node, &free_xfers);
+
+	return 0;
+}
+
+static void got_data(u32 code)
+{
+	mb86s7x_mhu_handler_t hndlr = NULL;
+	unsigned long flags;
+	int ev;
+
+	if (code & RESP_BIT)
+		ev = EV_RR;
+	else
+		ev = EV_RC;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		pr_err("State-%d EV-%d FSM Broken!\n", fsm_state, ev);
+		return;
+	}
+	fsm_state = mhu_fsm[fsm_state][ev];
+
+	if (code & RESP_BIT) {
+		memcpy_fromio(ax->buf, rsp_from_scb, ax->len);
+		if (ax->c)
+			complete(ax->c);
+		list_move(&ax->node, &free_xfers);
+		ax = NULL;
+	} else {
+		/* Find and dispatch relevant registered handler */
+		if (code < MHU_NUM_CMDS)
+			hndlr = handler[code];
+		if (hndlr)
+			hndlr(code, cmd_from_scb);
+		else
+			pr_err("No handler for CMD_%u\n", code);
+	}
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+}
+
+static int do_xfer(void)
+{
+	unsigned long flags;
+	struct mhu_xfer *x;
+	int ev, code;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (list_empty(&pending_xfers)) {
+		struct mbox_chan *_ch = NULL;
+		int cmd;
+
+		for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+			;
+		/* Don't free channel if any user is listening */
+		if (cmd != MHU_NUM_CMDS) {
+			spin_unlock_irqrestore(&fsm_lock, flags);
+			return 0;
+		}
+
+		if (fsm_state == MHU_PARK) {
+			_ch = mhu_chan;
+			mhu_chan = NULL;
+		}
+
+		spin_unlock_irqrestore(&fsm_lock, flags);
+
+		if (_ch)
+			mbox_free_channel(_ch);
+
+		return 0;
+	}
+
+	x = list_first_entry(&pending_xfers, struct mhu_xfer, node);
+	code = x->code;
+
+	ev = code & RESP_BIT ? EV_LR : EV_LC;
+	if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		return 1;
+	}
+	list_del_init(&x->node);
+
+	/* Layout the SHM */
+	if (code & RESP_BIT)
+		memcpy_toio(rsp_to_scb, x->buf, x->len);
+	else
+		memcpy_toio(cmd_to_scb, x->buf, x->len);
+
+	if (ev == EV_LC)
+		ax = x;
+	else
+		list_move(&x->node, &free_xfers);
+	fsm_state = mhu_fsm[fsm_state][ev];
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	/* Prefer mailbox API */
+	if (!mhu_chan) {
+		struct mbox_chan *_ch;
+
+		_ch = mbox_request_channel(&mhu_cl, 0);
+		if (!IS_ERR(_ch))
+			mhu_chan = _ch;
+	}
+
+	if (mhu_chan) {
+		int ret;
+
+		init_completion(&fsm_rsp);
+
+		/* Send via generic api */
+		ret = mbox_send_message(mhu_chan, (void *)code);
+		if (ret < 0) {
+			pr_err("%s:%d CMD_%d Send Failed\n",
+			       __func__, __LINE__, code);
+			BUG();
+		}
+		if (!(code & RESP_BIT)) {
+			ret = wait_for_completion_timeout(&fsm_rsp,
+						msecs_to_jiffies(1000));
+			if (!ret) {
+				pr_err("%s:%d CMD_%d Got No Reply\n",
+				       __func__, __LINE__, code);
+				BUG();
+			}
+			got_data(ax->code);
+		}
+	} else {
+		void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+		void __iomem *rx_reg = mhu_base + 0x20; /* HP-NonSec */
+		u32 val, count;
+
+		/* Send via early-boot api */
+		val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+		if (val) {
+			pr_err("Last CMD not yet read by SCB\n");
+			writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+		}
+
+		writel_relaxed(x->code, tx_reg + INTR_SET_OFS);
+
+		/* Wait until this message is read */
+		count = 0x1000000;
+		do {
+			cpu_relax();
+			val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+		} while (--count && val);
+		if (val)
+			pr_err("%s:%d SCB not listening!\n",
+			       __func__, __LINE__);
+
+		if (!ax) {
+			/* A quick poll for pending remote cmd */
+			val = readl_relaxed(rx_reg + INTR_STAT_OFS);
+			if (val) {
+				got_data(val);
+				writel_relaxed(val, rx_reg + INTR_CLR_OFS);
+			}
+		} else {
+			do {
+				/* Wait until we get reply */
+				count = 0x1000000;
+				do {
+					cpu_relax();
+					val = readl_relaxed(
+						rx_reg + INTR_STAT_OFS);
+				} while (--count && !val);
+
+				if (val) {
+					got_data(val);
+					writel_relaxed(val,
+						     rx_reg + INTR_CLR_OFS);
+				} else {
+					pr_err("%s:%d SCB didn't reply\n",
+					       __func__, __LINE__);
+					return 1;
+				}
+			} while (!(val & RESP_BIT));
+		}
+		if (list_empty(&pending_xfers))
+			return 0;
+	}
+
+	return do_xfer();
+}
+
+static void mhu_recv(struct mbox_client *cl, void *data)
+{
+	if ((u32)data & RESP_BIT) {
+		/* Now that we got a reply to last TX, that
+		 * must mean the last TX was successful */
+		mbox_client_txdone(mhu_chan, 0);
+
+		ax->code = (u32)data; /* Save response */
+		complete(&fsm_rsp);
+		return;
+	}
+
+	got_data((u32)data);
+}
+
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+	if (cmd < MHU_NUM_CMDS && !handler[cmd]) {
+		ret = 0;
+		handler[cmd] = hndlr;
+	}
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	if (!mhu_chan) {
+		struct mbox_chan *_ch;
+
+		_ch = mbox_request_channel(&mhu_cl, 0);
+		if (!IS_ERR(_ch))
+			mhu_chan = _ch;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_set);
+
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (cmd < MHU_NUM_CMDS && handler[cmd] == hndlr)
+		handler[cmd] = NULL;
+
+	if (list_empty(&pending_xfers)) {
+		struct mbox_chan *_ch = NULL;
+
+		for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+			;
+		/* Don't free channel if any user is listening */
+		if (cmd != MHU_NUM_CMDS) {
+			spin_unlock_irqrestore(&fsm_lock, flags);
+			return;
+		}
+
+		if (fsm_state == MHU_PARK) {
+			_ch = mhu_chan;
+			mhu_chan = NULL;
+		}
+
+		spin_unlock_irqrestore(&fsm_lock, flags);
+
+		if (_ch)
+			mbox_free_channel(_ch);
+
+		return;
+	}
+	spin_unlock_irqrestore(&fsm_lock, flags);
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_clr);
+
+static int setup_mhu(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "arm,mbox-mhu");
+	mhu_base = of_iomap(node, 0);
+	if (mhu_base == NULL) {
+		pr_err("Can't work without MHU\n");
+		return -ENODEV;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+	mb86s7x_shm_base = of_iomap(node, 0);
+	if (mb86s7x_shm_base == NULL) {
+		pr_err("Can't work without SHM SRAM\n");
+		return -ENODEV;
+	}
+
+	cmd_from_scb = mb86s7x_shm_base + 0x3800;
+	rsp_from_scb = mb86s7x_shm_base + 0x3900;
+	cmd_to_scb = mb86s7x_shm_base + 0x3a00;
+	rsp_to_scb = mb86s7x_shm_base + 0x3b00;
+
+	return 0;
+}
+
+int mb86s7x_send_packet(int code, void *buf, int len)
+{
+	struct completion got_rsp;
+	unsigned long flags;
+	struct mhu_xfer *x;
+	int ret;
+
+	/*
+	 * The first caller could be as early as system clocksource,
+	 * when the platform devices are not populated yet.
+	 */
+	if (unlikely(!mb86s7x_shm_base) && setup_mhu())
+		return -ENODEV;
+
+	if ((code & ~0xff) || ((code & RESP_BIT)
+				&& fsm_state != MHU_WRRL
+				&& fsm_state != MHU_WRL)) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	init_completion(&got_rsp);
+
+	spin_lock_irqsave(&fsm_lock, flags);
+
+	if (list_empty(&free_xfers) && mhu_alloc_xfers(5, &free_xfers)) {
+		spin_unlock_irqrestore(&fsm_lock, flags);
+		pr_err("%s:%d OOM\n", __func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	x = list_first_entry(&free_xfers, struct mhu_xfer, node);
+	x->code = code;
+	x->buf = buf;
+	x->len = len;
+	x->c = &got_rsp;
+
+	if (code & RESP_BIT)
+		list_move(&x->node, &pending_xfers);
+	else
+		list_move_tail(&x->node, &pending_xfers);
+
+	spin_unlock_irqrestore(&fsm_lock, flags);
+
+	ret = do_xfer();
+	if (ret > 0) {
+		ret = wait_for_completion_timeout(&got_rsp,
+						  msecs_to_jiffies(1000));
+		return ret ? 0 : -EIO;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_send_packet);
+
+struct mb86s7x_hard_reset {
+	u32 payload_size;
+	u32 delay;
+};
+
+static void mb86s7x_reboot(u32 delay)
+{
+	void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+	struct mb86s7x_hard_reset cmd;
+	u32 val;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.delay = delay;
+
+	val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+	if (val) /* Flush anything pending */
+		writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+
+	memcpy_toio(cmd_to_scb, &cmd, sizeof(cmd));
+	writel_relaxed(CMD_HARD_RESET_REQ, tx_reg + INTR_SET_OFS);
+}
+
+static void
+mb86s7x_restart(enum reboot_mode reboot_mode, const char *unused)
+{
+	/* Reboot immediately (after 50ms) */
+	mb86s7x_reboot(50);
+}
+
+static void mb86s7x_poweroff(void)
+{
+	/* Reboot never, remain dead */
+	mb86s7x_reboot(~0);
+}
+
+static int f_scb_probe(struct platform_device *pdev)
+{
+	mhu_cl.tx_block = true;
+	mhu_cl.knows_txdone = true;
+	mhu_cl.rx_callback = mhu_recv;
+	mhu_cl.dev = &pdev->dev;
+
+	arm_pm_restart = mb86s7x_restart;
+	pm_power_off = mb86s7x_poweroff;
+
+	return 0;
+}
+
+static const struct of_device_id scb_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-scb-1.0" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, scb_dt_ids);
+
+static struct platform_driver f_scb_driver = {
+	.driver		= {
+		.name	= "f_scb",
+		.of_match_table = scb_dt_ids,
+	},
+	.probe = f_scb_probe,
+};
+
+static int __init f_scb_init(void)
+{
+	return platform_driver_register(&f_scb_driver);
+}
+module_init(f_scb_init);
diff --git a/include/soc/mb86s7x/scb_mhu.h b/include/soc/mb86s7x/scb_mhu.h
new file mode 100644
index 0000000..a7e3484
--- /dev/null
+++ b/include/soc/mb86s7x/scb_mhu.h
@@ -0,0 +1,97 @@
+/*
+ * include/soc/mb86s7x/scb_mhu.h
+ *
+ * Created by: Jassi Brar <jassisinghbrar@gmail.com>
+ * Copyright:	(C) 2013-2014 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef __MB86S7X_SCB_MHU_H
+#define __MB86S7X_SCB_MHU_H
+
+#define CMD_MASK    0x7f    /* 128 possible commands */
+#define RESP_BIT    (1 << 7) /* If it's a response */
+
+#define ENC_CMD(c)  ((c) & CMD_MASK)
+#define DEC_CMD(v)  (((v) & ~CMD_MASK) ? CMD_INVALID : ((v) & CMD_MASK))
+
+#define ENC_REP(r)  (((r) & CMD_MASK) | RESP_BIT)
+
+/* If v is the reply to command c */
+#define IS_A_REP(v, c)  (((v) & RESP_BIT) && (((v) & CMD_MASK) == (c)))
+
+enum {
+	CMD_INVALID = 0,
+	CMD_I2C_XFER_REQ = 1,
+	CMD_PERI_POWER_SET_REQ = 2,
+	CMD_PERI_CLOCK_GATE_SET_REQ = 3,
+	CMD_PERI_CLOCK_GATE_GET_REQ = 4,
+	CMD_PERI_CLOCK_RATE_SET_REQ = 5,
+	CMD_PERI_CLOCK_RATE_GET_REQ = 6,
+	CMD_CPU_CLOCK_GATE_SET_REQ = 7,
+	CMD_CPU_CLOCK_GATE_GET_REQ = 8,
+	CMD_CPU_CLOCK_RATE_SET_REQ = 9,
+	CMD_CPU_CLOCK_RATE_GET_REQ = 0xa,
+	CMD_CLUSTER_OPP_GET_REQ = 0xb,
+	CMD_CLOCK_DSI_PIXEL_REQ = 0xc,
+	CMD_SCB_CAPABILITY_GET_REQ = 0xd,
+	CMD_SYS_RESET_CAUSE_GET_REQ = 0xe,
+	CMD_SYS_SPECIFIC_INFO_GET_REQ = 0xf,
+	CMD_REBOOT_AP_AFTER_REQ = 0x10,
+	CMD_TAIKI_REQ = 0x11,
+	CMD_TAIKI_ASYNC_MSG_REQ = 0x12,
+	CMD_GET_WORD_REQ = 0x13,
+	CMD_HARD_RESET_REQ = 0x14,
+	CMD_MAINTENANCE_MODE_REQ = 0x15,
+	CMD_STG_GET_SIZE_REQ = 0x16,
+	CMD_STG_BLOCK_READ_REQ = 0x17,
+	CMD_STG_BLOCK_WRITE_REQ = 0x18,
+	CMD_MEMORY_LAYOUT_GET_REQ = 0x19,
+	CMD_POWERDOMAIN_GET_REQ = 0x1a,
+	CMD_POWERDOMAIN_SET_REQ = 0x1b,
+	CMD_STG_BLOCK_ERASE_REQ = 0x1c,
+
+	/* Do NOT add new commands below this line */
+	MHU_NUM_CMDS,
+};
+
+#define CMD_I2C_XFER_REP	ENC_REP(CMD_I2C_XFER_REQ)
+#define CMD_PERI_POWER_SET_REP	ENC_REP(CMD_PERI_POWER_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_SET_REP	ENC_REP(CMD_PERI_CLOCK_GATE_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_GET_REP	ENC_REP(CMD_PERI_CLOCK_GATE_GET_REQ)
+#define CMD_PERI_CLOCK_RATE_SET_REP	ENC_REP(CMD_PERI_CLOCK_RATE_SET_REQ)
+#define CMD_PERI_CLOCK_RATE_GET_REP	ENC_REP(CMD_PERI_CLOCK_RATE_GET_REQ)
+#define CMD_CPU_CLOCK_GATE_SET_REP	ENC_REP(CMD_CPU_CLOCK_GATE_SET_REQ)
+#define CMD_CPU_CLOCK_GATE_GET_REP	ENC_REP(CMD_CPU_CLOCK_GATE_GET_REQ)
+#define CMD_CPU_CLOCK_RATE_SET_REP	ENC_REP(CMD_CPU_CLOCK_RATE_SET_REQ)
+#define CMD_CPU_CLOCK_RATE_GET_REP	ENC_REP(CMD_CPU_CLOCK_RATE_GET_REQ)
+#define CMD_CLUSTER_OPP_GET_REP	ENC_REP(CMD_CLUSTER_OPP_GET_REQ)
+#define CMD_CLOCK_DSI_PIXEL_REP	ENC_REP(CMD_CLOCK_DSI_PIXEL_REQ)
+#define CMD_SCB_CAPABILITY_GET_REP	ENC_REP(CMD_SCB_CAPABILITY_GET_REQ)
+#define CMD_SYS_RESET_CAUSE_GET_REP	ENC_REP(CMD_SYS_RESET_CAUSE_GET_REQ)
+#define CMD_SYS_SPECIFIC_INFO_GET_REP	ENC_REP(CMD_SYS_SPECIFIC_INFO_GET_REQ)
+#define CMD_GET_WORD_REP	ENC_REP(CMD_GET_WORD_REQ)
+#define CMD_REBOOT_AP_AFTER_REP	ENC_REP(CMD_REBOOT_AP_AFTER_REQ)
+#define CMD_TAIKI_REP			ENC_REP(CMD_TAIKI_REQ)
+#define CMD_TAIKI_ASYNC_MSG_REP		ENC_REP(CMD_TAIKI_ASYNC_MSG_REQ)
+#define CMD_HARD_RESET_REP		ENC_REP(CMD_HARD_RESET_REQ)
+#define CMD_MAINTENANCE_MODE_REP	ENC_RSP(CMD_MAINTENANCE_MODE_REQ)
+#define CMD_STG_GET_SIZE_REP		ENC_REP(CMD_STG_GET_SIZE_REQ)
+#define CMD_STG_BLOCK_READ_REP		ENC_REP(CMD_STG_BLOCK_READ_REQ)
+#define CMD_STG_BLOCK_WRITE_REP		ENC_REP(CMD_STG_BLOCK_WRITE_REQ)
+#define CMD_MEMORY_LAYOUT_GET_REP	ENC_REP(CMD_MEMORY_LAYOUT_GET_REQ)
+#define CMD_POWERDOMAIN_GET_REP		ENC_REP(CMD_POWERDOMAIN_GET_REQ)
+#define CMD_POWERDOMAIN_SET_REP		ENC_REP(CMD_POWERDOMAIN_SET_REQ)
+#define CMD_STG_BLOCK_ERASE_REP		ENC_REP(CMD_STG_BLOCK_ERASE_REQ)
+
+/* Helper functions to talk to remote */
+int mb86s7x_send_packet(int cmd, void *buf, int len);
+
+typedef void (*mb86s7x_mhu_handler_t)(u32 cmd, u8 rcbuf[]);
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t);
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t);
+
+#endif /* __MB86S7X_SCB_MHU_H */
-- 
1.9.0

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

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:34     ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:34 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, sudeep.holla-5wv7dgnIgG8,
	andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

Add driver for the ARM Message-Handling-Unit (MHU).

Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
 .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
 drivers/mailbox/Kconfig                            |   7 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/arm_mhu.c                          | 196 +++++++++++++++++++++
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
 create mode 100644 drivers/mailbox/arm_mhu.c

diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
new file mode 100644
index 0000000..b1b9888
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
@@ -0,0 +1,33 @@
+ARM MHU Mailbox Driver
+======================
+
+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
+3 independent channels/links to communicate with remote processor(s).
+ MHU links are hardwired on a platform. A link raises interrupt for any
+received data. However, there is no specified way of knowing if the sent
+data has been read by the remote. This driver assumes the sender polls
+STAT register and the remote clears it after having read the data.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible:		Shall be "arm,mbox-mhu"
+- reg:			Contains the mailbox register address range (base
+			address and length)
+- #mbox-cells		Shall be 1
+- interrupts:		Contains the interrupt information corresponding to
+			each of the 3 links of MHU.
+
+Example:
+--------
+
+	mhu: mailbox@2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>,
+			     <0 35 4>,
+			     <0 37 4>;
+	};
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 9fd9c67..da4cb9a 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -6,6 +6,13 @@ menuconfig MAILBOX
 	  signals. Say Y if your platform supports hardware mailboxes.
 
 if MAILBOX
+
+config ARM_MHU
+	tristate "ARM MHU Mailbox"
+	depends on ARM
+	help
+	  Say Y here if you want to build the ARM MHU controller driver
+
 config PL320_MBOX
 	bool "ARM PL320 Mailbox"
 	depends on ARM_AMBA
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 94ed7ce..43fd931 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,6 +2,8 @@
 
 obj-$(CONFIG_MAILBOX)		+= mailbox.o
 
+obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o
+
 obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
 
 obj-$(CONFIG_OMAP2PLUS_MBOX)	+= omap-mailbox.o
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
new file mode 100644
index 0000000..7c6b3cb
--- /dev/null
+++ b/drivers/mailbox/arm_mhu.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2013-2014 Fujitsu Semiconductor Ltd.
+ * Copyright (C) 2014 Linaro Ltd.
+ * Author: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@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, version 2 of the License.
+ *
+ * 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/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/mailbox_controller.h>
+#include <linux/platform_device.h>
+
+#define INTR_STAT_OFS	0x0
+#define INTR_SET_OFS	0x8
+#define INTR_CLR_OFS	0x10
+
+struct mhu_link {
+	unsigned irq;
+	void __iomem *tx_reg;
+	void __iomem *rx_reg;
+};
+
+struct arm_mhu {
+	void __iomem *base;
+	struct clk *clk;
+	struct mhu_link mlink[3];
+	struct mbox_chan chan[3];
+	struct mbox_controller mbox;
+};
+
+static irqreturn_t mhu_rx_interrupt(int irq, void *p)
+{
+	struct mbox_chan *chan = p;
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS);
+	mbox_chan_received_data(chan, (void *)val);
+
+	writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS);
+
+	return IRQ_HANDLED;
+}
+
+static bool mhu_last_tx_done(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+
+	return (val == 0);
+}
+
+static int mhu_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	if (!mhu_last_tx_done(chan)) {
+		pr_err("%s:%d Shouldn't have seen the day!\n",
+		       __func__, __LINE__);
+		return -EBUSY;
+	}
+
+	writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
+
+	return 0;
+}
+
+static int mhu_startup(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+	int ret;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+	writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS);
+
+	ret = request_irq(mlink->irq, mhu_rx_interrupt,
+			  IRQF_SHARED, "mhu_link", chan);
+	if (unlikely(ret)) {
+		pr_err("Unable to aquire IRQ\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mhu_shutdown(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	free_irq(mlink->irq, chan);
+}
+
+static struct mbox_chan_ops mhu_ops = {
+	.send_data = mhu_send_data,
+	.startup = mhu_startup,
+	.shutdown = mhu_shutdown,
+	.last_tx_done = mhu_last_tx_done,
+};
+
+static int arm_mhu_probe(struct platform_device *pdev)
+{
+	int i, err;
+	struct arm_mhu *mhu;
+	struct resource *res;
+	int mhu_reg[3] = {0x0, 0x20, 0x200};
+
+	/* Allocate memory for device */
+	mhu = kzalloc(sizeof(*mhu), GFP_KERNEL);
+	if (!mhu)
+		return -ENOMEM;
+
+	mhu->clk = clk_get(&pdev->dev, "clk");
+	if (unlikely(IS_ERR(mhu->clk)))
+		dev_info(&pdev->dev, "unable to init clock\n");
+	else
+		clk_prepare_enable(mhu->clk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mhu->base = ioremap(res->start, resource_size(res));
+	if (!mhu->base) {
+		dev_err(&pdev->dev, "ioremap failed.\n");
+		kfree(mhu);
+		return -EBUSY;
+	}
+
+	for (i = 0; i < 3; i++) {
+		mhu->chan[i].con_priv = &mhu->mlink[i];
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+		mhu->mlink[i].irq = res->start;
+		mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
+		mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
+	}
+
+	mhu->mbox.dev = &pdev->dev;
+	mhu->mbox.chans = &mhu->chan[0];
+	mhu->mbox.num_chans = 3;
+	mhu->mbox.ops = &mhu_ops;
+	mhu->mbox.txdone_irq = false;
+	mhu->mbox.txdone_poll = true;
+	mhu->mbox.txpoll_period = 10;
+
+	platform_set_drvdata(pdev, mhu);
+
+	err = mbox_controller_register(&mhu->mbox);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to register mailboxes %d\n", err);
+		iounmap(mhu->base);
+		kfree(mhu);
+	} else {
+		dev_info(&pdev->dev, "ARM MHU Mailbox registered\n");
+	}
+
+	return 0;
+}
+
+static const struct of_device_id arm_mhu_dt_ids[] = {
+	{ .compatible = "arm,mbox-mhu" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, arm_mhu_dt_ids);
+
+static struct platform_driver arm_mhu_driver = {
+	.driver		= {
+		.name	= "arm_mhu",
+		.of_match_table = arm_mhu_dt_ids,
+	},
+	.probe		= arm_mhu_probe,
+};
+module_platform_driver(arm_mhu_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ARM MHU Driver");
+MODULE_AUTHOR("Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
-- 
1.9.0

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

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

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-20 12:34     ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:34 UTC (permalink / raw)
  To: linux-arm-kernel

Add driver for the ARM Message-Handling-Unit (MHU).

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
 drivers/mailbox/Kconfig                            |   7 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/arm_mhu.c                          | 196 +++++++++++++++++++++
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
 create mode 100644 drivers/mailbox/arm_mhu.c

diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
new file mode 100644
index 0000000..b1b9888
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
@@ -0,0 +1,33 @@
+ARM MHU Mailbox Driver
+======================
+
+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
+3 independent channels/links to communicate with remote processor(s).
+ MHU links are hardwired on a platform. A link raises interrupt for any
+received data. However, there is no specified way of knowing if the sent
+data has been read by the remote. This driver assumes the sender polls
+STAT register and the remote clears it after having read the data.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible:		Shall be "arm,mbox-mhu"
+- reg:			Contains the mailbox register address range (base
+			address and length)
+- #mbox-cells		Shall be 1
+- interrupts:		Contains the interrupt information corresponding to
+			each of the 3 links of MHU.
+
+Example:
+--------
+
+	mhu: mailbox at 2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>,
+			     <0 35 4>,
+			     <0 37 4>;
+	};
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 9fd9c67..da4cb9a 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -6,6 +6,13 @@ menuconfig MAILBOX
 	  signals. Say Y if your platform supports hardware mailboxes.
 
 if MAILBOX
+
+config ARM_MHU
+	tristate "ARM MHU Mailbox"
+	depends on ARM
+	help
+	  Say Y here if you want to build the ARM MHU controller driver
+
 config PL320_MBOX
 	bool "ARM PL320 Mailbox"
 	depends on ARM_AMBA
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 94ed7ce..43fd931 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,6 +2,8 @@
 
 obj-$(CONFIG_MAILBOX)		+= mailbox.o
 
+obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o
+
 obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
 
 obj-$(CONFIG_OMAP2PLUS_MBOX)	+= omap-mailbox.o
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
new file mode 100644
index 0000000..7c6b3cb
--- /dev/null
+++ b/drivers/mailbox/arm_mhu.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2013-2014 Fujitsu Semiconductor Ltd.
+ * Copyright (C) 2014 Linaro Ltd.
+ * Author: Jassi Brar <jaswinder.singh@linaro.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, version 2 of the License.
+ *
+ * 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/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/mailbox_controller.h>
+#include <linux/platform_device.h>
+
+#define INTR_STAT_OFS	0x0
+#define INTR_SET_OFS	0x8
+#define INTR_CLR_OFS	0x10
+
+struct mhu_link {
+	unsigned irq;
+	void __iomem *tx_reg;
+	void __iomem *rx_reg;
+};
+
+struct arm_mhu {
+	void __iomem *base;
+	struct clk *clk;
+	struct mhu_link mlink[3];
+	struct mbox_chan chan[3];
+	struct mbox_controller mbox;
+};
+
+static irqreturn_t mhu_rx_interrupt(int irq, void *p)
+{
+	struct mbox_chan *chan = p;
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS);
+	mbox_chan_received_data(chan, (void *)val);
+
+	writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS);
+
+	return IRQ_HANDLED;
+}
+
+static bool mhu_last_tx_done(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+
+	return (val == 0);
+}
+
+static int mhu_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	if (!mhu_last_tx_done(chan)) {
+		pr_err("%s:%d Shouldn't have seen the day!\n",
+		       __func__, __LINE__);
+		return -EBUSY;
+	}
+
+	writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
+
+	return 0;
+}
+
+static int mhu_startup(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+	u32 val;
+	int ret;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+	writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS);
+
+	ret = request_irq(mlink->irq, mhu_rx_interrupt,
+			  IRQF_SHARED, "mhu_link", chan);
+	if (unlikely(ret)) {
+		pr_err("Unable to aquire IRQ\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mhu_shutdown(struct mbox_chan *chan)
+{
+	struct mhu_link *mlink = (struct mhu_link *)chan->con_priv;
+
+	pr_debug("%s:%d\n", __func__, __LINE__);
+	free_irq(mlink->irq, chan);
+}
+
+static struct mbox_chan_ops mhu_ops = {
+	.send_data = mhu_send_data,
+	.startup = mhu_startup,
+	.shutdown = mhu_shutdown,
+	.last_tx_done = mhu_last_tx_done,
+};
+
+static int arm_mhu_probe(struct platform_device *pdev)
+{
+	int i, err;
+	struct arm_mhu *mhu;
+	struct resource *res;
+	int mhu_reg[3] = {0x0, 0x20, 0x200};
+
+	/* Allocate memory for device */
+	mhu = kzalloc(sizeof(*mhu), GFP_KERNEL);
+	if (!mhu)
+		return -ENOMEM;
+
+	mhu->clk = clk_get(&pdev->dev, "clk");
+	if (unlikely(IS_ERR(mhu->clk)))
+		dev_info(&pdev->dev, "unable to init clock\n");
+	else
+		clk_prepare_enable(mhu->clk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mhu->base = ioremap(res->start, resource_size(res));
+	if (!mhu->base) {
+		dev_err(&pdev->dev, "ioremap failed.\n");
+		kfree(mhu);
+		return -EBUSY;
+	}
+
+	for (i = 0; i < 3; i++) {
+		mhu->chan[i].con_priv = &mhu->mlink[i];
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+		mhu->mlink[i].irq = res->start;
+		mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
+		mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
+	}
+
+	mhu->mbox.dev = &pdev->dev;
+	mhu->mbox.chans = &mhu->chan[0];
+	mhu->mbox.num_chans = 3;
+	mhu->mbox.ops = &mhu_ops;
+	mhu->mbox.txdone_irq = false;
+	mhu->mbox.txdone_poll = true;
+	mhu->mbox.txpoll_period = 10;
+
+	platform_set_drvdata(pdev, mhu);
+
+	err = mbox_controller_register(&mhu->mbox);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to register mailboxes %d\n", err);
+		iounmap(mhu->base);
+		kfree(mhu);
+	} else {
+		dev_info(&pdev->dev, "ARM MHU Mailbox registered\n");
+	}
+
+	return 0;
+}
+
+static const struct of_device_id arm_mhu_dt_ids[] = {
+	{ .compatible = "arm,mbox-mhu" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, arm_mhu_dt_ids);
+
+static struct platform_driver arm_mhu_driver = {
+	.driver		= {
+		.name	= "arm_mhu",
+		.of_match_table = arm_mhu_dt_ids,
+	},
+	.probe		= arm_mhu_probe,
+};
+module_platform_driver(arm_mhu_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ARM MHU Driver");
+MODULE_AUTHOR("Jassi Brar <jassisinghbrar@gmail.com>");
-- 
1.9.0

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-20 12:27 ` Vincent Yang
  (?)
@ 2014-11-20 12:35 ` Vincent Yang
  2014-11-21 13:02   ` Arnd Bergmann
                     ` (2 more replies)
  -1 siblings, 3 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:35 UTC (permalink / raw)
  To: linux-arm-kernel

The remote firmware(SCB) owns the SMP control. This MCPM driver gets
CPU/CLUSTER power up/down done by SCB over mailbox.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 arch/arm/mach-mb86s7x/Makefile |   2 +-
 arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-mb86s7x/smc.S    |  27 ++++
 3 files changed, 388 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
 create mode 100644 arch/arm/mach-mb86s7x/smc.S

diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
index 97640b6..b0fa34b 100644
--- a/arch/arm/mach-mb86s7x/Makefile
+++ b/arch/arm/mach-mb86s7x/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_ARCH_MB86S7X)	+= board.o
+obj-$(CONFIG_ARCH_MB86S7X)	+= board.o mcpm.o smc.o
diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
new file mode 100644
index 0000000..bf1b50a
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/mcpm.c
@@ -0,0 +1,360 @@
+/*
+ * arch/arm/mach-mb86s7x/mcpm.c
+ * Copyright:	(C) 2013-2014 Fujitsu Semiconductor Limited
+ * Copyright:	(C) 2014 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/arm-cci.h>
+#include <linux/spinlock.h>
+#include <linux/suspend.h>
+#include <linux/of_device.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <asm/mcpm.h>
+#include <asm/cp15.h>
+#include <asm/cputype.h>
+#include <asm/suspend.h>
+#include <asm/idmap.h>
+
+#define S7X_MAX_CLUSTER	2
+#define S7X_MAX_CPU	2
+
+#define MHU_SHM_OFFSET		0x3800
+#define WFI_COLOR_OFFSET	0x3f00
+#define TRAMPOLINE_OFFSET	0x3c00
+#define RESET_OFFSET		(TRAMPOLINE_OFFSET + 0x3fc)
+
+static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
+extern void __iomem *mb86s7x_shm_base;
+
+#define AT_WFI_DO_NOTHING	0x0
+#define AT_WFI_DO_SUSPEND	0x1
+#define AT_WFI_DO_POWEROFF	0x2
+#define AT_WFI_COLOR_MASK	0x3
+
+struct mb86s7x_cpu_gate {
+	u32 payload_size;
+	u32 cluster_class;
+	u32 cluster_id;
+	u32 cpu_id;
+#define SCB_CPU_STATE_OFF	0x0
+#define SCB_CPU_STATE_ON	0x1
+#define SCB_CPU_STATE_SUSP	0x2
+	u32 cpu_state;
+};
+
+asmlinkage void mb86s70evb_outer_flush_all(void)
+{
+	outer_flush_all();
+}
+
+#define mb86s70evb_exit_coherency_flush(level) { \
+	asm volatile( \
+	"stmfd	sp!, {fp, ip}\n\t" \
+	"mrc	p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
+	"bic	r0, r0, #"__stringify(CR_C)"\n\t" \
+	"mcr	p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
+	"isb\n\t" \
+	"bl	v7_flush_dcache_"__stringify(level)"\n\t" \
+	"bl	mb86s70evb_outer_flush_all\n\t" \
+	"mrc	p15, 0, r0, c1, c0, 1   @ get ACTLR\n\t" \
+	"bic	r0, r0, #(1 << 6)       @ disable local coherency\n\t" \
+	"mcr	p15, 0, r0, c1, c0, 1   @ set ACTLR\n\t" \
+	"isb\n\t" \
+	"dsb\n\t" \
+	"ldmfd	sp!, {fp, ip}" \
+		: : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+		"r9", "r10", "lr", "memory"); \
+	}
+
+static void
+mb86s7x_set_wficolor(unsigned clstr, unsigned cpu, unsigned clr)
+{
+	u8 val;
+
+	if (clr & ~AT_WFI_COLOR_MASK)
+		return;
+
+	val = readb_relaxed(mb86s7x_shm_base
+			    + WFI_COLOR_OFFSET + clstr * 2 + cpu);
+	val &= ~AT_WFI_COLOR_MASK;
+	val |= clr;
+	writeb_relaxed(val, mb86s7x_shm_base
+		       + WFI_COLOR_OFFSET + clstr * 2 + cpu);
+}
+
+static int mb86s7x_pm_power_up(unsigned int cpu, unsigned int cluster)
+{
+	int ret = 0;
+
+	if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
+		return -EINVAL;
+
+	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+
+	local_irq_disable();
+	arch_spin_lock(&mb86s7x_pm_lock);
+
+	mb86s7x_pm_use_count[cluster][cpu]++;
+
+	if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
+		struct mb86s7x_cpu_gate cmd;
+
+		arch_spin_unlock(&mb86s7x_pm_lock);
+		local_irq_enable();
+		cmd.payload_size = sizeof(cmd);
+		cmd.cluster_class = 0;
+		cmd.cluster_id = cluster;
+		cmd.cpu_id = cpu;
+		cmd.cpu_state = SCB_CPU_STATE_ON;
+
+		pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
+			 __func__, __LINE__, cmd.cluster_class,
+			 cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
+
+		mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
+		ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_SET_REQ,
+					  &cmd, sizeof(cmd));
+		if (ret < 0) {
+			pr_err("%s:%d failed!\n", __func__, __LINE__);
+			return ret;
+		}
+
+		pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
+			 __func__, __LINE__, cmd.cluster_class,
+			 cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
+
+		if (cmd.cpu_state != SCB_CPU_STATE_ON)
+			return -ENODEV;
+	} else if (mb86s7x_pm_use_count[cluster][cpu] != 2) {
+		/*
+		 * The only possible values are:
+		 * 0 = CPU down
+		 * 1 = CPU (still) up
+		 * 2 = CPU requested to be up before it had a chance
+		 *     to actually make itself down.
+		 * Any other value is a bug.
+		 */
+		BUG();
+	}
+
+	return 0;
+}
+
+static void mb86s7x_pm_suspend(u64 ignored)
+{
+	unsigned int mpidr, cpu, cluster;
+	bool last_man = false, skip_wfi = false;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+	__mcpm_cpu_going_down(cpu, cluster);
+
+	arch_spin_lock(&mb86s7x_pm_lock);
+	BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+
+	mb86s7x_pm_use_count[cluster][cpu]--;
+
+	if (mb86s7x_pm_use_count[cluster][cpu] == 0) {
+		if (!mb86s7x_pm_use_count[cluster][0] &&
+		    !mb86s7x_pm_use_count[cluster][1])
+			last_man = true;
+		mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_POWEROFF);
+	} else if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
+		skip_wfi = true; /* Overtaken by a power up */
+	} else {
+		BUG();
+	}
+
+	if (!skip_wfi)
+		gic_cpu_if_down();
+
+	if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
+		arch_spin_unlock(&mb86s7x_pm_lock);
+
+		if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
+			/*
+			 * On the Cortex-A15 we need to disable
+			 * L2 prefetching before flushing the cache.
+			 */
+			asm volatile(
+			"mcr p15, 1, %0, c15, c0, 3\n\t"
+			"isb\n\t"
+			"dsb"
+			: : "r" (0x400));
+		}
+
+		mb86s70evb_exit_coherency_flush(all);
+
+		cci_disable_port_by_cpu(mpidr);
+
+		__mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
+	} else {
+		arch_spin_unlock(&mb86s7x_pm_lock);
+		mb86s70evb_exit_coherency_flush(louis);
+	}
+
+	__mcpm_cpu_down(cpu, cluster);
+
+	/* Now we are prepared for power-down, do it: */
+	if (!skip_wfi)
+		wfi();
+}
+
+static void mb86s7x_pm_power_down(void)
+{
+	mb86s7x_pm_suspend(0);
+}
+
+static int mb86s7x_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+	struct mb86s7x_cpu_gate cmd;
+	int i, ret;
+
+	if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
+		return 0;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cluster_class = 0;
+	cmd.cluster_id = cluster;
+	cmd.cpu_id = cpu;
+	cmd.cpu_state = SCB_CPU_STATE_ON;
+
+	for (i = 0; i < 50; i++) {
+		ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_GET_REQ,
+					  &cmd, sizeof(cmd));
+		if (ret < 0) {
+			pr_err("%s:%d failed to get CPU status\n",
+			       __func__, __LINE__);
+			return ret;
+		}
+
+		pr_debug("%s:%d Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u\n",
+			 __func__, __LINE__,
+			 cmd.cluster_class, cmd.cluster_id,
+			 cmd.cpu_id, cmd.cpu_state);
+
+		if (cmd.cpu_state == SCB_CPU_STATE_OFF)
+			return 0;
+
+		msleep(20);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void mb86s7x_pm_powered_up(void)
+{
+	unsigned int mpidr, cpu, cluster;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	arch_spin_lock(&mb86s7x_pm_lock);
+	if (!mb86s7x_pm_use_count[cluster][cpu])
+		mb86s7x_pm_use_count[cluster][cpu] = 1;
+	arch_spin_unlock(&mb86s7x_pm_lock);
+}
+
+static const struct mcpm_platform_ops mb86s7x_pm_power_ops = {
+	.power_up		= mb86s7x_pm_power_up,
+	.power_down		= mb86s7x_pm_power_down,
+	.wait_for_powerdown	= mb86s7x_wait_for_powerdown,
+	.suspend		= mb86s7x_pm_suspend,
+	.powered_up		= mb86s7x_pm_powered_up,
+};
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ */
+static void __naked mb86s7x_pm_power_up_setup(unsigned int affinity_level)
+{
+	asm volatile ("\n"
+"	cmp	r0, #1\n"
+"	bxne	lr\n"
+"	b	cci_enable_port_for_self");
+}
+
+static void __init mb86s7x_cache_off(void)
+{
+	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
+		/* disable L2 prefetching on the Cortex-A15 */
+		asm volatile(
+		"mcr	p15, 1, %0, c15, c0, 3\n\t"
+		"isb\n\t"
+		"dsb"
+		: : "r" (0x400));
+	}
+	mb86s70evb_exit_coherency_flush(all);
+}
+
+struct mb86s7x_scb_version {
+	u32 payload_size;
+	u32 version;
+	u32 config_version;
+};
+
+extern void mb86s7x_cpu_entry(unsigned long secondary_entry);
+
+static int __init mb86s7x_mcpm_init(void)
+{
+	unsigned int mpidr, cpu, cluster;
+	struct mb86s7x_scb_version cmd;
+	int ret;
+
+	if (!cci_probed())
+		return -ENODEV;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	pr_info("Booting on cpu_%u cluster_%u\n", cpu, cluster);
+	mb86s7x_pm_use_count[cluster][cpu] = 1;
+
+	/* reset the wfi 'color' for primary cpu */
+	mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
+
+	/* Do SMC to set entry address for CPUs coming online */
+	mb86s7x_cpu_entry(virt_to_phys(mcpm_entry_point));
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.version = 0;
+	cmd.config_version = 0;
+	ret = mb86s7x_send_packet(CMD_SCB_CAPABILITY_GET_REQ,
+				  &cmd, sizeof(cmd));
+	if (ret < 0)
+		pr_err("%s:%d failed to get SCB version\n",
+		       __func__, __LINE__);
+
+	pr_info("MB86S7x MCPM initialized: SCB version 0x%x:0x%x\n",
+		cmd.version, cmd.config_version);
+
+	ret = mcpm_platform_register(&mb86s7x_pm_power_ops);
+	if (!ret)
+		ret = mcpm_sync_init(mb86s7x_pm_power_up_setup);
+	if (!ret)
+		ret = mcpm_loopback(mb86s7x_cache_off); /* turn on the CCI */
+	mcpm_smp_set_ops();
+
+	return ret;
+}
+early_initcall(mb86s7x_mcpm_init);
diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
new file mode 100644
index 0000000..a14330b
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/smc.S
@@ -0,0 +1,27 @@
+/*
+ * SMC command interface to set secondary entry point
+ * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
+ * Copyright: (C) 2014 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+.arch_extension sec
+
+/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
+ENTRY(mb86s7x_cpu_entry)
+	stmfd   sp!, {r1-r11, lr}
+	mov r1, r0
+	ldr r0, =1
+	mrc p15, 0, r3, c1, c0, 0
+	mov r4, r3
+	and r3, #0xbfffffff
+	mcr p15, 0, r3, c1, c0, 0
+	smc #0
+	mcr p15, 0, r4, c1, c0, 0
+	ldmfd   sp!, {r1-r11, pc}
+ENDPROC(mb86s7x_cpu_entry)
-- 
1.9.0

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

* [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:36     ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:36 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-QSEj5FYQhm4dnm+yROfE0A,
	andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

 The CRG11 clock controller is managed by remote f/w.
This driver simply maps Linux CLK ops onto mailbox api.

Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
 .../bindings/clock/fujitsu,mb86s70-clk.txt         |  34 ++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-mb86s7x.c                          | 359 +++++++++++++++++++++
 include/dt-bindings/clock/mb86s70-clk.h            |  22 ++
 4 files changed, 416 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
 create mode 100644 drivers/clk/clk-mb86s7x.c
 create mode 100644 include/dt-bindings/clock/mb86s70-clk.h

diff --git a/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
new file mode 100644
index 0000000..7aeb1ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
@@ -0,0 +1,34 @@
+Fujitsu CRG11 clock driver bindings
+-----------------------------------
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-clk"
+- #clock-cells : Shall be 0
+- cntrlr : 0->ALW, 1->DDR3, 2->MAIN, 3->CA15, 4->HDMI, 5->DPHY
+- domain : [0, 15]
+- port : [0,7] -> Gateable Clock Ports.  [8]->UngatedCLK
+	  The UngatedCLK is the source of 8 maskable clock ports
+	  as well as having its own output port which can't be masked.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+	clk_alw_2_1: clk_alw_2_1 {
+		compatible = "fujitsu,mb86s70-clk";
+		#clock-cells = <0>;
+		cntrlr = <0>;
+		domain = <2>;
+		port = <1>;
+	};
+
+	mhu: mhu0@2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2B1F0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+		clocks = <&clk_alw_2_1>;
+		clock-names = "clk";
+	};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..19d73a1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1)		+= clk-ls1x.o
 obj-$(CONFIG_COMMON_CLK_MAX_GEN)	+= clk-max-gen.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)	+= clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_MAX77802)	+= clk-max77802.o
+obj-$(CONFIG_ARCH_MB86S7X)		+= clk-mb86s7x.o
 obj-$(CONFIG_ARCH_MOXART)		+= clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)		+= clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
new file mode 100644
index 0000000..e585fb3
--- /dev/null
+++ b/drivers/clk/clk-mb86s7x.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ *
+ * 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/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <dt-bindings/clock/mb86s70-clk.h>
+
+#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
+#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
+
+struct mb86s7x_peri_clk {
+	u32 payload_size;
+	u32 cntrlr;
+	u32 domain;
+	u32 port;
+	u32 en;
+	u64 freqency;
+} __packed __attribute__((aligned(4)));
+
+struct hack_rate {
+	unsigned clk_id;
+	unsigned long rate;
+	int gated;
+};
+
+struct crg_clk {
+	struct clk_hw hw;
+	u8 cntrlr, domain, port;
+};
+
+static int crg_gate_control(struct clk_hw *hw, int en)
+{
+	struct crg_clk *crgclk = to_crg_clk(hw);
+	struct mb86s7x_peri_clk cmd;
+	int ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cntrlr = crgclk->cntrlr;
+	cmd.domain = crgclk->domain;
+	cmd.port = crgclk->port;
+	cmd.en = en;
+
+	/* Port is UngatedCLK */
+	if (cmd.port == MB86S70_CRG11_UNGPRT)
+		return en ? 0 : -EINVAL;
+
+	pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+		 __func__, __LINE__, cmd.cntrlr,
+		 cmd.domain, cmd.port, cmd.en);
+
+	ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
+				  &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return ret;
+	}
+
+	pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+		 __func__, __LINE__, cmd.cntrlr,
+		 cmd.domain, cmd.port, cmd.en);
+
+	/* If the request was rejected */
+	if (cmd.en != en)
+		ret = -EINVAL;
+	else
+		ret = 0;
+
+	return ret;
+}
+
+static int crg_port_prepare(struct clk_hw *hw)
+{
+	return crg_gate_control(hw, 1);
+}
+
+static void crg_port_unprepare(struct clk_hw *hw)
+{
+	crg_gate_control(hw, 0);
+}
+
+static int
+crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
+{
+	struct crg_clk *crgclk = to_crg_clk(hw);
+	struct mb86s7x_peri_clk cmd;
+	int code, ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cntrlr = crgclk->cntrlr;
+	cmd.domain = crgclk->domain;
+	cmd.port = crgclk->port;
+	cmd.freqency = *rate;
+
+	if (set) {
+		code = CMD_PERI_CLOCK_RATE_SET_REQ;
+		pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+	} else {
+		code = CMD_PERI_CLOCK_RATE_GET_REQ;
+		pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port);
+	}
+
+	ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return ret;
+	}
+
+	if (set)
+		pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+	else
+		pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+
+	*rate = cmd.freqency;
+	return 0;
+}
+
+static unsigned long
+crg_port_recalc_rate(struct clk_hw *hw,	unsigned long parent_rate)
+{
+	unsigned long rate;
+
+	crg_rate_control(hw, 0, &rate);
+
+	return rate;
+}
+
+static long
+crg_port_round_rate(struct clk_hw *hw,
+		    unsigned long rate, unsigned long *pr)
+{
+	return rate;
+}
+
+static int
+crg_port_set_rate(struct clk_hw *hw,
+		  unsigned long rate, unsigned long parent_rate)
+{
+	return crg_rate_control(hw, 1, &rate);
+}
+
+const struct clk_ops crg_port_ops = {
+	.prepare = crg_port_prepare,
+	.unprepare = crg_port_unprepare,
+	.recalc_rate = crg_port_recalc_rate,
+	.round_rate = crg_port_round_rate,
+	.set_rate = crg_port_set_rate,
+};
+
+static void __init crg_port_init(struct device_node *node)
+{
+	struct clk_init_data init;
+	u32 cntrlr, domain, port;
+	struct crg_clk *crgclk;
+	struct clk *clk;
+	char clkp[20];
+	int rc;
+
+	rc = of_property_read_u32(node, "cntrlr", &cntrlr);
+	if (WARN_ON(rc))
+		return;
+	rc = of_property_read_u32(node, "domain", &domain);
+	if (WARN_ON(rc))
+		return;
+	rc = of_property_read_u32(node, "port", &port);
+	if (WARN_ON(rc))
+		return;
+
+	if (port > 7)
+		snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
+	else
+		snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
+
+	clk = __clk_lookup(clkp);
+	if (clk)
+		return;
+
+	crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
+	if (!crgclk)
+		return;
+	init.name = clkp;
+	init.num_parents = 0;
+	init.ops = &crg_port_ops;
+	init.flags = CLK_IS_ROOT;
+	crgclk->hw.init = &init;
+	crgclk->cntrlr = cntrlr;
+	crgclk->domain = domain;
+	crgclk->port = port;
+	clk = clk_register(NULL, &crgclk->hw);
+	if (IS_ERR(clk))
+		pr_err("%s:%d Error!\n", __func__, __LINE__);
+	else
+		pr_debug("Registered %s\n", clkp);
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	clk_register_clkdev(clk, clkp, NULL);
+}
+CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-clk", crg_port_init);
+
+struct cl_clk {
+	struct clk_hw hw;
+	int cluster;
+};
+
+struct mb86s7x_cpu_freq {
+	u32 payload_size;
+	u32 cluster_class;
+	u32 cluster_id;
+	u32 cpu_id;
+	u64 freqency;
+};
+
+static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
+{
+	struct cl_clk *clc = to_clc_clk(hw);
+	struct mb86s7x_cpu_freq cmd;
+	int code, ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cluster_class = 0;
+	cmd.cluster_id = clc->cluster;
+	cmd.cpu_id = 0;
+	cmd.freqency = *rate;
+
+	if (get)
+		code = CMD_CPU_CLOCK_RATE_GET_REQ;
+	else
+		code = CMD_CPU_CLOCK_RATE_SET_REQ;
+
+	pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+		 __func__, __LINE__, cmd.cluster_class,
+		 cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+	ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return;
+	}
+
+	pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+		 __func__, __LINE__, cmd.cluster_class,
+		 cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+	*rate = cmd.freqency;
+}
+
+static unsigned long
+clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
+{
+	unsigned long rate;
+
+	mhu_cluster_rate(hw, &rate, 1);
+	return rate;
+}
+
+static long
+clc_round_rate(struct clk_hw *hw, unsigned long rate,
+	       unsigned long *unused)
+{
+	return rate;
+}
+
+static int
+clc_set_rate(struct clk_hw *hw, unsigned long rate,
+	     unsigned long unused)
+{
+	unsigned long res = rate;
+
+	mhu_cluster_rate(hw, &res, 0);
+
+	return (res == rate) ? 0 : -EINVAL;
+}
+
+static struct clk_ops clk_clc_ops = {
+	.recalc_rate = clc_recalc_rate,
+	.round_rate = clc_round_rate,
+	.set_rate = clc_set_rate,
+};
+
+struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
+{
+	struct clk_init_data init;
+	struct cl_clk *clc;
+
+	clc = kzalloc(sizeof(*clc), GFP_KERNEL);
+	if (!clc)
+		return ERR_PTR(-ENOMEM);
+
+	clc->hw.init = &init;
+	clc->cluster = topology_physical_package_id(cpu_dev->id);
+
+	init.name = dev_name(cpu_dev);
+	init.ops = &clk_clc_ops;
+	init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+	init.num_parents = 0;
+
+	return devm_clk_register(cpu_dev, &clc->hw);
+}
+
+static int mb86s7x_clclk_of_init(void)
+{
+	int cpu;
+	struct clk *clk;
+
+	for_each_possible_cpu(cpu) {
+		struct device *cpu_dev = get_cpu_device(cpu);
+
+		if (!cpu_dev) {
+			pr_err("failed to get cpu%d device\n", cpu);
+			continue;
+		}
+
+		clk = mb86s7x_clclk_register(cpu_dev);
+		if (IS_ERR(clk)) {
+			pr_err("failed to register cpu%d clock\n", cpu);
+			continue;
+		}
+		if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+			pr_err("failed to register cpu%d clock lookup\n", cpu);
+			continue;
+		}
+		pr_debug("registered clk for %s\n", dev_name(cpu_dev));
+	}
+
+	platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
+
+	return 0;
+}
+module_init(mb86s7x_clclk_of_init);
diff --git a/include/dt-bindings/clock/mb86s70-clk.h b/include/dt-bindings/clock/mb86s70-clk.h
new file mode 100644
index 0000000..d6f370b
--- /dev/null
+++ b/include/dt-bindings/clock/mb86s70-clk.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#ifndef	__DTS_MB86S70_CLK_H
+#define __DTS_MB86S70_CLK_H
+
+#define MB86S70_CRG11_ALW	0
+#define MB86S70_CRG11_DDR3	1
+#define MB86S70_CRG11_MAIN	2
+#define MB86S70_CRG11_CA15	3
+#define MB86S70_CRG11_HDMI	4
+#define MB86S70_CRG11_DPHY	5
+
+#define MB86S70_CRG11_UNGPRT	8
+
+#endif
-- 
1.9.0

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

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

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-20 12:36     ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:36 UTC (permalink / raw)
  To: linux-arm-kernel

 The CRG11 clock controller is managed by remote f/w.
This driver simply maps Linux CLK ops onto mailbox api.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 .../bindings/clock/fujitsu,mb86s70-clk.txt         |  34 ++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-mb86s7x.c                          | 359 +++++++++++++++++++++
 include/dt-bindings/clock/mb86s70-clk.h            |  22 ++
 4 files changed, 416 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
 create mode 100644 drivers/clk/clk-mb86s7x.c
 create mode 100644 include/dt-bindings/clock/mb86s70-clk.h

diff --git a/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
new file mode 100644
index 0000000..7aeb1ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-clk.txt
@@ -0,0 +1,34 @@
+Fujitsu CRG11 clock driver bindings
+-----------------------------------
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-clk"
+- #clock-cells : Shall be 0
+- cntrlr : 0->ALW, 1->DDR3, 2->MAIN, 3->CA15, 4->HDMI, 5->DPHY
+- domain : [0, 15]
+- port : [0,7] -> Gateable Clock Ports.  [8]->UngatedCLK
+	  The UngatedCLK is the source of 8 maskable clock ports
+	  as well as having its own output port which can't be masked.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+	clk_alw_2_1: clk_alw_2_1 {
+		compatible = "fujitsu,mb86s70-clk";
+		#clock-cells = <0>;
+		cntrlr = <0>;
+		domain = <2>;
+		port = <1>;
+	};
+
+	mhu: mhu0 at 2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2B1F0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+		clocks = <&clk_alw_2_1>;
+		clock-names = "clk";
+	};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..19d73a1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1)		+= clk-ls1x.o
 obj-$(CONFIG_COMMON_CLK_MAX_GEN)	+= clk-max-gen.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)	+= clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_MAX77802)	+= clk-max77802.o
+obj-$(CONFIG_ARCH_MB86S7X)		+= clk-mb86s7x.o
 obj-$(CONFIG_ARCH_MOXART)		+= clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)		+= clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)		+= clk-nspire.o
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
new file mode 100644
index 0000000..e585fb3
--- /dev/null
+++ b/drivers/clk/clk-mb86s7x.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ *
+ * 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/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <dt-bindings/clock/mb86s70-clk.h>
+
+#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
+#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
+
+struct mb86s7x_peri_clk {
+	u32 payload_size;
+	u32 cntrlr;
+	u32 domain;
+	u32 port;
+	u32 en;
+	u64 freqency;
+} __packed __attribute__((aligned(4)));
+
+struct hack_rate {
+	unsigned clk_id;
+	unsigned long rate;
+	int gated;
+};
+
+struct crg_clk {
+	struct clk_hw hw;
+	u8 cntrlr, domain, port;
+};
+
+static int crg_gate_control(struct clk_hw *hw, int en)
+{
+	struct crg_clk *crgclk = to_crg_clk(hw);
+	struct mb86s7x_peri_clk cmd;
+	int ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cntrlr = crgclk->cntrlr;
+	cmd.domain = crgclk->domain;
+	cmd.port = crgclk->port;
+	cmd.en = en;
+
+	/* Port is UngatedCLK */
+	if (cmd.port == MB86S70_CRG11_UNGPRT)
+		return en ? 0 : -EINVAL;
+
+	pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+		 __func__, __LINE__, cmd.cntrlr,
+		 cmd.domain, cmd.port, cmd.en);
+
+	ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
+				  &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return ret;
+	}
+
+	pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+		 __func__, __LINE__, cmd.cntrlr,
+		 cmd.domain, cmd.port, cmd.en);
+
+	/* If the request was rejected */
+	if (cmd.en != en)
+		ret = -EINVAL;
+	else
+		ret = 0;
+
+	return ret;
+}
+
+static int crg_port_prepare(struct clk_hw *hw)
+{
+	return crg_gate_control(hw, 1);
+}
+
+static void crg_port_unprepare(struct clk_hw *hw)
+{
+	crg_gate_control(hw, 0);
+}
+
+static int
+crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
+{
+	struct crg_clk *crgclk = to_crg_clk(hw);
+	struct mb86s7x_peri_clk cmd;
+	int code, ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cntrlr = crgclk->cntrlr;
+	cmd.domain = crgclk->domain;
+	cmd.port = crgclk->port;
+	cmd.freqency = *rate;
+
+	if (set) {
+		code = CMD_PERI_CLOCK_RATE_SET_REQ;
+		pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+	} else {
+		code = CMD_PERI_CLOCK_RATE_GET_REQ;
+		pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port);
+	}
+
+	ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return ret;
+	}
+
+	if (set)
+		pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+	else
+		pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
+			 __func__, __LINE__, cmd.cntrlr,
+			 cmd.domain, cmd.port, cmd.freqency);
+
+	*rate = cmd.freqency;
+	return 0;
+}
+
+static unsigned long
+crg_port_recalc_rate(struct clk_hw *hw,	unsigned long parent_rate)
+{
+	unsigned long rate;
+
+	crg_rate_control(hw, 0, &rate);
+
+	return rate;
+}
+
+static long
+crg_port_round_rate(struct clk_hw *hw,
+		    unsigned long rate, unsigned long *pr)
+{
+	return rate;
+}
+
+static int
+crg_port_set_rate(struct clk_hw *hw,
+		  unsigned long rate, unsigned long parent_rate)
+{
+	return crg_rate_control(hw, 1, &rate);
+}
+
+const struct clk_ops crg_port_ops = {
+	.prepare = crg_port_prepare,
+	.unprepare = crg_port_unprepare,
+	.recalc_rate = crg_port_recalc_rate,
+	.round_rate = crg_port_round_rate,
+	.set_rate = crg_port_set_rate,
+};
+
+static void __init crg_port_init(struct device_node *node)
+{
+	struct clk_init_data init;
+	u32 cntrlr, domain, port;
+	struct crg_clk *crgclk;
+	struct clk *clk;
+	char clkp[20];
+	int rc;
+
+	rc = of_property_read_u32(node, "cntrlr", &cntrlr);
+	if (WARN_ON(rc))
+		return;
+	rc = of_property_read_u32(node, "domain", &domain);
+	if (WARN_ON(rc))
+		return;
+	rc = of_property_read_u32(node, "port", &port);
+	if (WARN_ON(rc))
+		return;
+
+	if (port > 7)
+		snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
+	else
+		snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
+
+	clk = __clk_lookup(clkp);
+	if (clk)
+		return;
+
+	crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
+	if (!crgclk)
+		return;
+	init.name = clkp;
+	init.num_parents = 0;
+	init.ops = &crg_port_ops;
+	init.flags = CLK_IS_ROOT;
+	crgclk->hw.init = &init;
+	crgclk->cntrlr = cntrlr;
+	crgclk->domain = domain;
+	crgclk->port = port;
+	clk = clk_register(NULL, &crgclk->hw);
+	if (IS_ERR(clk))
+		pr_err("%s:%d Error!\n", __func__, __LINE__);
+	else
+		pr_debug("Registered %s\n", clkp);
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	clk_register_clkdev(clk, clkp, NULL);
+}
+CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-clk", crg_port_init);
+
+struct cl_clk {
+	struct clk_hw hw;
+	int cluster;
+};
+
+struct mb86s7x_cpu_freq {
+	u32 payload_size;
+	u32 cluster_class;
+	u32 cluster_id;
+	u32 cpu_id;
+	u64 freqency;
+};
+
+static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
+{
+	struct cl_clk *clc = to_clc_clk(hw);
+	struct mb86s7x_cpu_freq cmd;
+	int code, ret;
+
+	cmd.payload_size = sizeof(cmd);
+	cmd.cluster_class = 0;
+	cmd.cluster_id = clc->cluster;
+	cmd.cpu_id = 0;
+	cmd.freqency = *rate;
+
+	if (get)
+		code = CMD_CPU_CLOCK_RATE_GET_REQ;
+	else
+		code = CMD_CPU_CLOCK_RATE_SET_REQ;
+
+	pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+		 __func__, __LINE__, cmd.cluster_class,
+		 cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+	ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+	if (ret < 0) {
+		pr_err("%s:%d failed!\n", __func__, __LINE__);
+		return;
+	}
+
+	pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+		 __func__, __LINE__, cmd.cluster_class,
+		 cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+	*rate = cmd.freqency;
+}
+
+static unsigned long
+clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
+{
+	unsigned long rate;
+
+	mhu_cluster_rate(hw, &rate, 1);
+	return rate;
+}
+
+static long
+clc_round_rate(struct clk_hw *hw, unsigned long rate,
+	       unsigned long *unused)
+{
+	return rate;
+}
+
+static int
+clc_set_rate(struct clk_hw *hw, unsigned long rate,
+	     unsigned long unused)
+{
+	unsigned long res = rate;
+
+	mhu_cluster_rate(hw, &res, 0);
+
+	return (res == rate) ? 0 : -EINVAL;
+}
+
+static struct clk_ops clk_clc_ops = {
+	.recalc_rate = clc_recalc_rate,
+	.round_rate = clc_round_rate,
+	.set_rate = clc_set_rate,
+};
+
+struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
+{
+	struct clk_init_data init;
+	struct cl_clk *clc;
+
+	clc = kzalloc(sizeof(*clc), GFP_KERNEL);
+	if (!clc)
+		return ERR_PTR(-ENOMEM);
+
+	clc->hw.init = &init;
+	clc->cluster = topology_physical_package_id(cpu_dev->id);
+
+	init.name = dev_name(cpu_dev);
+	init.ops = &clk_clc_ops;
+	init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+	init.num_parents = 0;
+
+	return devm_clk_register(cpu_dev, &clc->hw);
+}
+
+static int mb86s7x_clclk_of_init(void)
+{
+	int cpu;
+	struct clk *clk;
+
+	for_each_possible_cpu(cpu) {
+		struct device *cpu_dev = get_cpu_device(cpu);
+
+		if (!cpu_dev) {
+			pr_err("failed to get cpu%d device\n", cpu);
+			continue;
+		}
+
+		clk = mb86s7x_clclk_register(cpu_dev);
+		if (IS_ERR(clk)) {
+			pr_err("failed to register cpu%d clock\n", cpu);
+			continue;
+		}
+		if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+			pr_err("failed to register cpu%d clock lookup\n", cpu);
+			continue;
+		}
+		pr_debug("registered clk for %s\n", dev_name(cpu_dev));
+	}
+
+	platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
+
+	return 0;
+}
+module_init(mb86s7x_clclk_of_init);
diff --git a/include/dt-bindings/clock/mb86s70-clk.h b/include/dt-bindings/clock/mb86s70-clk.h
new file mode 100644
index 0000000..d6f370b
--- /dev/null
+++ b/include/dt-bindings/clock/mb86s70-clk.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#ifndef	__DTS_MB86S70_CLK_H
+#define __DTS_MB86S70_CLK_H
+
+#define MB86S70_CRG11_ALW	0
+#define MB86S70_CRG11_DDR3	1
+#define MB86S70_CRG11_MAIN	2
+#define MB86S70_CRG11_CA15	3
+#define MB86S70_CRG11_HDMI	4
+#define MB86S70_CRG11_DPHY	5
+
+#define MB86S70_CRG11_UNGPRT	8
+
+#endif
-- 
1.9.0

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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:37   ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:37 UTC (permalink / raw)
  To: devicetree, linux-gpio, linux-arm-kernel
  Cc: arnd, olof, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, grant.likely, linus.walleij, gnurou, andy.green, patches,
	jaswinder.singh, Vincent Yang, Tetsuya Nuriya

Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
 drivers/gpio/Kconfig                               |   6 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
 create mode 100644 drivers/gpio/gpio-mb86s7x.c

diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
new file mode 100644
index 0000000..38300ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
@@ -0,0 +1,18 @@
+Fujitsu MB86S7x GPIO Controller
+-------------------------------
+
+Required properties:
+- compatible: Should be "fujitsu,mb86s70-gpio"
+- gpio-controller: Marks the device node as a gpio controller.
+- #gpio-cells: Should be <2>. The first cell is the pin number and the
+  second cell is used to specify optional parameters:
+   - bit 0 specifies polarity (0 for normal, 1 for inverted).
+
+Examples:
+	gpio0: gpio@31000000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31000000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0959ca9..493b7fe 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -181,6 +181,12 @@ config GPIO_F7188X
 	  To compile this driver as a module, choose M here: the module will
 	  be called f7188x-gpio.
 
+config GPIO_MB86S7X
+	bool "GPIO support for Fujitsu MB86S7x Platforms"
+	depends on ARCH_MB86S7X
+	help
+	  Say yes here to support the GPIO controller in LSI ZEVIO SoCs.
+
 config GPIO_MOXART
 	bool "MOXART GPIO support"
 	depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index e5d346c..eec0664 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X)	+= gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= gpio-max7301.o
 obj-$(CONFIG_GPIO_MAX732X)	+= gpio-max732x.o
+obj-$(CONFIG_GPIO_MB86S7X)	+= gpio-mb86s7x.o
 obj-$(CONFIG_GPIO_MC33880)	+= gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)	+= gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)	+= gpio-mcp23s08.o
diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
new file mode 100644
index 0000000..f0b2dc0
--- /dev/null
+++ b/drivers/gpio/gpio-mb86s7x.c
@@ -0,0 +1,211 @@
+/*
+ *  linux/drivers/gpio/gpio-mb86s7x.c
+ *
+ *  Copyright (C) 2014 Fujitsu Semiconductor Limited
+ *  Copyright (C) 2014 Linaro Ltd.
+ *
+ *  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, version 2 of the License.
+ *
+ *  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/io.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#define PDR(x)	(0x0 + x)
+#define DDR(x)	(0x10 + x)
+#define PFR(x)	(0x20 + x)
+
+struct mb86s70_gpio_chip {
+	spinlock_t lock;
+	struct clk *clk;
+	void __iomem *base;
+	struct gpio_chip gc;
+};
+
+static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip = container_of(gc,
+					struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + PFR(offset / 8 * 4));
+	val &= ~(1 << (offset % 8)); /* as gpio-port */
+	writel(val, gchip->base + PFR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static void mb86s70_gpio_free(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip = container_of(gc,
+					struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + PFR(offset / 8 * 4));
+	val |= (1 << (offset % 8)); /* as peri-port */
+	writel(val, gchip->base + PFR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+}
+
+static int mb86s70_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + DDR(offset / 8 * 4));
+	val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + DDR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static int mb86s70_gpio_direction_output(struct gpio_chip *gc,
+					 unsigned offset, int value)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	if (value)
+		val |= (1 << (offset % 8));
+	else
+		val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + PDR(offset / 8 * 4));
+
+	val = readl(gchip->base + DDR(offset / 8 * 4));
+	val |= (1 << (offset % 8));
+	writel(val, gchip->base + DDR(offset / 8 * 4));
+
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned char val;
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	val &= (1 << (offset % 8));
+	return val ? 1 : 0;
+}
+
+static void mb86s70_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	if (value)
+		val |= (1 << (offset % 8));
+	else
+		val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + PDR(offset / 8 * 4));
+
+	spin_unlock_irqrestore(&gchip->lock, flags);
+}
+
+static int mb86s70_gpio_probe(struct platform_device *pdev)
+{
+	struct mb86s70_gpio_chip *gchip;
+	struct resource *res;
+	int ret;
+
+	gchip = devm_kzalloc(&pdev->dev, sizeof(*gchip), GFP_KERNEL);
+	if (gchip == NULL)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, gchip);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	gchip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gchip->base))
+		return PTR_ERR(gchip->base);
+
+	gchip->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(gchip->clk))
+		return PTR_ERR(gchip->clk);
+
+	clk_prepare_enable(gchip->clk);
+
+	spin_lock_init(&gchip->lock);
+
+	gchip->gc.direction_output = mb86s70_gpio_direction_output;
+	gchip->gc.direction_input = mb86s70_gpio_direction_input;
+	gchip->gc.request = mb86s70_gpio_request;
+	gchip->gc.free = mb86s70_gpio_free;
+	gchip->gc.get = mb86s70_gpio_get;
+	gchip->gc.set = mb86s70_gpio_set;
+	gchip->gc.label = dev_name(&pdev->dev);
+	gchip->gc.ngpio = 32;
+	gchip->gc.owner = THIS_MODULE;
+	gchip->gc.dev = &pdev->dev;
+	gchip->gc.base = -1;
+
+	ret = gpiochip_add(&gchip->gc);
+	if (ret) {
+		dev_err(&pdev->dev, "couldn't register gpio driver\n");
+		clk_disable_unprepare(gchip->clk);
+	}
+
+	return ret;
+}
+
+static const struct of_device_id mb86s70_gpio_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-gpio" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mb86s70_gpio_dt_ids);
+
+static struct platform_driver mb86s70_gpio_driver = {
+	.probe     = mb86s70_gpio_probe,
+	.driver    = {
+		.name  = "mb86s70-gpio",
+		.of_match_table = mb86s70_gpio_dt_ids,
+	},
+};
+
+static int __init mb86s70_gpio_init(void)
+{
+	return platform_driver_register(&mb86s70_gpio_driver);
+}
+subsys_initcall(mb86s70_gpio_init);
+
+MODULE_DESCRIPTION("MB86S7x GPIO Driver");
+MODULE_ALIAS("platform:mb86s70-gpio");
+MODULE_LICENSE("GPL");
-- 
1.9.0


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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
@ 2014-11-20 12:37   ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
 drivers/gpio/Kconfig                               |   6 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
 create mode 100644 drivers/gpio/gpio-mb86s7x.c

diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
new file mode 100644
index 0000000..38300ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
@@ -0,0 +1,18 @@
+Fujitsu MB86S7x GPIO Controller
+-------------------------------
+
+Required properties:
+- compatible: Should be "fujitsu,mb86s70-gpio"
+- gpio-controller: Marks the device node as a gpio controller.
+- #gpio-cells: Should be <2>. The first cell is the pin number and the
+  second cell is used to specify optional parameters:
+   - bit 0 specifies polarity (0 for normal, 1 for inverted).
+
+Examples:
+	gpio0: gpio at 31000000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31000000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0959ca9..493b7fe 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -181,6 +181,12 @@ config GPIO_F7188X
 	  To compile this driver as a module, choose M here: the module will
 	  be called f7188x-gpio.
 
+config GPIO_MB86S7X
+	bool "GPIO support for Fujitsu MB86S7x Platforms"
+	depends on ARCH_MB86S7X
+	help
+	  Say yes here to support the GPIO controller in LSI ZEVIO SoCs.
+
 config GPIO_MOXART
 	bool "MOXART GPIO support"
 	depends on ARCH_MOXART
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index e5d346c..eec0664 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X)	+= gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= gpio-max7301.o
 obj-$(CONFIG_GPIO_MAX732X)	+= gpio-max732x.o
+obj-$(CONFIG_GPIO_MB86S7X)	+= gpio-mb86s7x.o
 obj-$(CONFIG_GPIO_MC33880)	+= gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)	+= gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)	+= gpio-mcp23s08.o
diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
new file mode 100644
index 0000000..f0b2dc0
--- /dev/null
+++ b/drivers/gpio/gpio-mb86s7x.c
@@ -0,0 +1,211 @@
+/*
+ *  linux/drivers/gpio/gpio-mb86s7x.c
+ *
+ *  Copyright (C) 2014 Fujitsu Semiconductor Limited
+ *  Copyright (C) 2014 Linaro Ltd.
+ *
+ *  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, version 2 of the License.
+ *
+ *  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/io.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#define PDR(x)	(0x0 + x)
+#define DDR(x)	(0x10 + x)
+#define PFR(x)	(0x20 + x)
+
+struct mb86s70_gpio_chip {
+	spinlock_t lock;
+	struct clk *clk;
+	void __iomem *base;
+	struct gpio_chip gc;
+};
+
+static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip = container_of(gc,
+					struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + PFR(offset / 8 * 4));
+	val &= ~(1 << (offset % 8)); /* as gpio-port */
+	writel(val, gchip->base + PFR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static void mb86s70_gpio_free(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip = container_of(gc,
+					struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + PFR(offset / 8 * 4));
+	val |= (1 << (offset % 8)); /* as peri-port */
+	writel(val, gchip->base + PFR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+}
+
+static int mb86s70_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+	val = readl(gchip->base + DDR(offset / 8 * 4));
+	val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + DDR(offset / 8 * 4));
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static int mb86s70_gpio_direction_output(struct gpio_chip *gc,
+					 unsigned offset, int value)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	if (value)
+		val |= (1 << (offset % 8));
+	else
+		val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + PDR(offset / 8 * 4));
+
+	val = readl(gchip->base + DDR(offset / 8 * 4));
+	val |= (1 << (offset % 8));
+	writel(val, gchip->base + DDR(offset / 8 * 4));
+
+	spin_unlock_irqrestore(&gchip->lock, flags);
+
+	return 0;
+}
+
+static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned char val;
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	val &= (1 << (offset % 8));
+	return val ? 1 : 0;
+}
+
+static void mb86s70_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct mb86s70_gpio_chip *gchip =
+			container_of(gc, struct mb86s70_gpio_chip, gc);
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&gchip->lock, flags);
+
+	val = readl(gchip->base + PDR(offset / 8 * 4));
+	if (value)
+		val |= (1 << (offset % 8));
+	else
+		val &= ~(1 << (offset % 8));
+	writel(val, gchip->base + PDR(offset / 8 * 4));
+
+	spin_unlock_irqrestore(&gchip->lock, flags);
+}
+
+static int mb86s70_gpio_probe(struct platform_device *pdev)
+{
+	struct mb86s70_gpio_chip *gchip;
+	struct resource *res;
+	int ret;
+
+	gchip = devm_kzalloc(&pdev->dev, sizeof(*gchip), GFP_KERNEL);
+	if (gchip == NULL)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, gchip);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	gchip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gchip->base))
+		return PTR_ERR(gchip->base);
+
+	gchip->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(gchip->clk))
+		return PTR_ERR(gchip->clk);
+
+	clk_prepare_enable(gchip->clk);
+
+	spin_lock_init(&gchip->lock);
+
+	gchip->gc.direction_output = mb86s70_gpio_direction_output;
+	gchip->gc.direction_input = mb86s70_gpio_direction_input;
+	gchip->gc.request = mb86s70_gpio_request;
+	gchip->gc.free = mb86s70_gpio_free;
+	gchip->gc.get = mb86s70_gpio_get;
+	gchip->gc.set = mb86s70_gpio_set;
+	gchip->gc.label = dev_name(&pdev->dev);
+	gchip->gc.ngpio = 32;
+	gchip->gc.owner = THIS_MODULE;
+	gchip->gc.dev = &pdev->dev;
+	gchip->gc.base = -1;
+
+	ret = gpiochip_add(&gchip->gc);
+	if (ret) {
+		dev_err(&pdev->dev, "couldn't register gpio driver\n");
+		clk_disable_unprepare(gchip->clk);
+	}
+
+	return ret;
+}
+
+static const struct of_device_id mb86s70_gpio_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-gpio" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mb86s70_gpio_dt_ids);
+
+static struct platform_driver mb86s70_gpio_driver = {
+	.probe     = mb86s70_gpio_probe,
+	.driver    = {
+		.name  = "mb86s70-gpio",
+		.of_match_table = mb86s70_gpio_dt_ids,
+	},
+};
+
+static int __init mb86s70_gpio_init(void)
+{
+	return platform_driver_register(&mb86s70_gpio_driver);
+}
+subsys_initcall(mb86s70_gpio_init);
+
+MODULE_DESCRIPTION("MB86S7x GPIO Driver");
+MODULE_ALIAS("platform:mb86s70-gpio");
+MODULE_LICENSE("GPL");
-- 
1.9.0

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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:38   ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:38 UTC (permalink / raw)
  To: devicetree, linux-mmc, linux-arm-kernel
  Cc: arnd, olof, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, chris, ulf.hansson, andy.green, patches,
	jaswinder.singh, Vincent Yang, Tetsuya Takinishi

This patch adds new host controller driver for
Fujitsu SDHCI controller f_sdh30.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
---
 .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
 drivers/mmc/host/Kconfig                           |   9 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
 4 files changed, 364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
 create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
new file mode 100644
index 0000000..a1e0b64
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
@@ -0,0 +1,35 @@
+* Fujitsu SDHCI controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci_f_sdh30 driver.
+
+Required properties:
+- compatible: "fujitsu,mb86s70-sdh30"
+- voltage-ranges : This is a list of pairs. In each pair, two cells
+  are required. First cell specifies minimum slot voltage (mV), second
+  cell specifies maximum slot voltage (mV). In case of supported voltage
+  range is discontinuous, several ranges could be specified as a list.
+
+Optional properties:
+- vqmmc-supply: phandle to the regulator device tree node, mentioned
+  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
+- clocks: Must contain an entry for each entry in clock-names. It is a
+  list of phandles and clock-specifier pairs.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: Should contain the following two entries:
+	"iface" - clock used for sdhci interface
+	"core"  - core clock for sdhci controller
+
+Example:
+
+	sdhci1: sdio@36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		vqmmc-supply = <&vccq_sdhci1>;
+		clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
+		clock-names = "iface", "core";
+	};
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1386065..cbe5e3c 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
 	  This selects the BCM2835 SD/MMC controller. If you have a BCM2835
 	  platform with SD or MMC devices, say Y or M here.
 
+config MMC_SDHCI_F_SDH30
+	tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
+	depends on ARCH_MB86S7X
+	depends on MMC_SDHCI_PLTFM
+	depends on OF
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  Needed by some Fujitsu SoC for MMC / SD / SDIO support.
+	  If you have a controller with this interface, say Y or M here.
 	  If unsure, say N.
 
 config MMC_MOXART
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b09ecfb..63efc38 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3)	+= sdhci-pxav3.o
 obj-$(CONFIG_MMC_SDHCI_PXAV2)	+= sdhci-pxav2.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_SDHCI_SIRF)   	+= sdhci-sirf.o
+obj-$(CONFIG_MMC_SDHCI_F_SDH30)	+= sdhci_f_sdh30.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)	+= sdhci-spear.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
new file mode 100644
index 0000000..f6eba5a
--- /dev/null
+++ b/drivers/mmc/host/sdhci_f_sdh30.c
@@ -0,0 +1,319 @@
+/*
+ * linux/drivers/mmc/host/sdhci_f_sdh30.c
+ *
+ * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
+ *              Vincent Yang <vincent.yang@tw.fujitsu.com>
+ * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
+ */
+
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+/* F_SDH30 extended Controller registers */
+#define F_SDH30_AHB_CONFIG		0x100
+#define  F_SDH30_AHB_BIGED		0x00000040
+#define  F_SDH30_BUSLOCK_DMA		0x00000020
+#define  F_SDH30_BUSLOCK_EN		0x00000010
+#define  F_SDH30_SIN			0x00000008
+#define  F_SDH30_AHB_INCR_16		0x00000004
+#define  F_SDH30_AHB_INCR_8		0x00000002
+#define  F_SDH30_AHB_INCR_4		0x00000001
+
+#define F_SDH30_TUNING_SETTING		0x108
+#define  F_SDH30_CMD_CHK_DIS		0x00010000
+
+#define F_SDH30_IO_CONTROL2		0x114
+#define  F_SDH30_CRES_O_DN		0x00080000
+#define  F_SDH30_MSEL_O_1_8		0x00040000
+
+#define F_SDH30_ESD_CONTROL		0x124
+#define  F_SDH30_EMMC_RST		0x00000002
+#define  F_SDH30_EMMC_HS200		0x01000000
+
+#define F_SDH30_CMD_DAT_DELAY		0x200
+
+#define F_SDH30_MIN_CLOCK		400000
+
+struct f_sdhost_priv {
+	struct clk *clk_iface;
+	struct clk *clk;
+	u32 vendor_hs200;
+	struct device *dev;
+};
+
+void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
+{
+	struct f_sdhost_priv *priv = sdhci_priv(host);
+	u32 ctrl = 0;
+
+	usleep_range(2500, 3000);
+	ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
+	ctrl |= F_SDH30_CRES_O_DN;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+	ctrl |= F_SDH30_MSEL_O_1_8;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+
+	ctrl &= ~F_SDH30_CRES_O_DN;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+	usleep_range(2500, 3000);
+
+	if (priv->vendor_hs200) {
+		dev_info(priv->dev, "%s: setting hs200\n", __func__);
+		ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+		ctrl |= priv->vendor_hs200;
+		sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
+	}
+
+	ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
+	ctrl |= F_SDH30_CMD_CHK_DIS;
+	sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
+}
+
+unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
+{
+	return F_SDH30_MIN_CLOCK;
+}
+
+void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
+{
+	if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
+		sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
+
+	sdhci_reset(host, mask);
+}
+
+static const struct sdhci_ops sdhci_f_sdh30_ops = {
+	.voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
+	.get_min_clock = sdhci_f_sdh30_get_min_clock,
+	.reset = sdhci_f_sdh30_reset,
+	.set_clock = sdhci_set_clock,
+	.set_bus_width = sdhci_set_bus_width,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct device *dev = &pdev->dev;
+	int irq, ctrl = 0, ret = 0;
+	struct f_sdhost_priv *priv;
+	u32 reg = 0;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "%s: no irq specified\n", __func__);
+		ret = irq;
+		goto err;
+	}
+
+	host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
+						sizeof(struct f_sdhost_priv));
+	if (IS_ERR(host)) {
+		dev_err(dev, "%s: host allocate error\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+	priv = sdhci_priv(host);
+	priv->dev = dev;
+
+	host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
+		       SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+	host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
+			SDHCI_QUIRK2_TUNING_WORK_AROUND;
+
+	ret = mmc_of_parse(host->mmc);
+	if (ret)
+		goto err_of_parse;
+
+	ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
+	if (ret)
+		goto err_of_parse;
+
+	platform_set_drvdata(pdev, host);
+
+	sdhci_get_of_property(pdev);
+	host->hw_name = "f_sdh30";
+	host->ops = &sdhci_f_sdh30_ops;
+	host->irq = irq;
+
+	host->ioaddr = of_iomap(pdev->dev.of_node, 0);
+	if (!host->ioaddr) {
+		dev_err(dev, "%s: failed to remap registers\n", __func__);
+		ret = -ENXIO;
+		goto err_remap;
+	}
+
+	priv->clk_iface = clk_get(&pdev->dev, "iface");
+	if (!IS_ERR(priv->clk_iface)) {
+		ret = clk_prepare_enable(priv->clk_iface);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable iface clock: %d\n", ret);
+			goto err_clk1;
+		}
+	}
+	priv->clk = clk_get(&pdev->dev, "core");
+	if (!IS_ERR(priv->clk)) {
+		ret = clk_prepare_enable(priv->clk);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable core clock: %d\n", ret);
+			goto err_clk2;
+		}
+	}
+
+#ifdef CONFIG_PM_RUNTIME
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0)
+		dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(dev, "%s: host add error\n", __func__);
+		goto err_add_host;
+	}
+
+	/* init vendor specific regs */
+	ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
+	ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
+		F_SDH30_AHB_INCR_4;
+	ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
+	sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
+
+	reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+	sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
+	msleep(20);
+	sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
+
+	reg = sdhci_readl(host, SDHCI_CAPABILITIES);
+	if (reg & SDHCI_CAN_DO_8BIT)
+		priv->vendor_hs200 = F_SDH30_EMMC_HS200;
+	else
+		priv->vendor_hs200 = 0;
+
+	return 0;
+
+err_add_host:
+	clk_put(priv->clk);
+err_clk2:
+	clk_put(priv->clk_iface);
+err_clk1:
+	iounmap(host->ioaddr);
+err_remap:
+err_of_parse:
+	sdhci_free_host(host);
+err:
+	return ret;
+}
+
+static int sdhci_f_sdh30_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct f_sdhost_priv *priv = sdhci_priv(host);
+	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
+			  0xffffffff);
+	iounmap(host->ioaddr);
+	release_mem_region(iomem->start, resource_size(iomem));
+
+	clk_disable_unprepare(priv->clk_iface);
+	clk_disable_unprepare(priv->clk);
+
+	clk_put(priv->clk);
+	clk_put(priv->clk_iface);
+
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sdhci_f_sdh30_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_suspend_host(host);
+}
+
+static int sdhci_f_sdh30_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_runtime_suspend_host(host);
+}
+
+static int sdhci_f_sdh30_runtime_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_runtime_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
+	SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
+			   sdhci_f_sdh30_runtime_resume, NULL)
+};
+
+#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
+
+#else
+#define SDHCI_F_SDH30_PMOPS NULL
+#endif
+
+static const struct of_device_id f_sdh30_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-sdh30" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
+
+static struct platform_driver sdhci_f_sdh30_driver = {
+	.driver = {
+		.name = "f_sdh30",
+		.of_match_table = f_sdh30_dt_ids,
+#ifdef CONFIG_PM_SLEEP
+		.pm	= SDHCI_F_SDH30_PMOPS,
+#endif
+	},
+	.probe	= sdhci_f_sdh30_probe,
+	.remove	= sdhci_f_sdh30_remove,
+};
+
+module_platform_driver(sdhci_f_sdh30_driver);
+
+MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
+MODULE_ALIAS("platform:f_sdh30");
-- 
1.9.0


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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
@ 2014-11-20 12:38   ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds new host controller driver for
Fujitsu SDHCI controller f_sdh30.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
---
 .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
 drivers/mmc/host/Kconfig                           |   9 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
 4 files changed, 364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
 create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
new file mode 100644
index 0000000..a1e0b64
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
@@ -0,0 +1,35 @@
+* Fujitsu SDHCI controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci_f_sdh30 driver.
+
+Required properties:
+- compatible: "fujitsu,mb86s70-sdh30"
+- voltage-ranges : This is a list of pairs. In each pair, two cells
+  are required. First cell specifies minimum slot voltage (mV), second
+  cell specifies maximum slot voltage (mV). In case of supported voltage
+  range is discontinuous, several ranges could be specified as a list.
+
+Optional properties:
+- vqmmc-supply: phandle to the regulator device tree node, mentioned
+  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
+- clocks: Must contain an entry for each entry in clock-names. It is a
+  list of phandles and clock-specifier pairs.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: Should contain the following two entries:
+	"iface" - clock used for sdhci interface
+	"core"  - core clock for sdhci controller
+
+Example:
+
+	sdhci1: sdio at 36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		vqmmc-supply = <&vccq_sdhci1>;
+		clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
+		clock-names = "iface", "core";
+	};
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1386065..cbe5e3c 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
 	  This selects the BCM2835 SD/MMC controller. If you have a BCM2835
 	  platform with SD or MMC devices, say Y or M here.
 
+config MMC_SDHCI_F_SDH30
+	tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
+	depends on ARCH_MB86S7X
+	depends on MMC_SDHCI_PLTFM
+	depends on OF
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  Needed by some Fujitsu SoC for MMC / SD / SDIO support.
+	  If you have a controller with this interface, say Y or M here.
 	  If unsure, say N.
 
 config MMC_MOXART
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b09ecfb..63efc38 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3)	+= sdhci-pxav3.o
 obj-$(CONFIG_MMC_SDHCI_PXAV2)	+= sdhci-pxav2.o
 obj-$(CONFIG_MMC_SDHCI_S3C)	+= sdhci-s3c.o
 obj-$(CONFIG_MMC_SDHCI_SIRF)   	+= sdhci-sirf.o
+obj-$(CONFIG_MMC_SDHCI_F_SDH30)	+= sdhci_f_sdh30.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)	+= sdhci-spear.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
new file mode 100644
index 0000000..f6eba5a
--- /dev/null
+++ b/drivers/mmc/host/sdhci_f_sdh30.c
@@ -0,0 +1,319 @@
+/*
+ * linux/drivers/mmc/host/sdhci_f_sdh30.c
+ *
+ * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
+ *              Vincent Yang <vincent.yang@tw.fujitsu.com>
+ * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
+ */
+
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+/* F_SDH30 extended Controller registers */
+#define F_SDH30_AHB_CONFIG		0x100
+#define  F_SDH30_AHB_BIGED		0x00000040
+#define  F_SDH30_BUSLOCK_DMA		0x00000020
+#define  F_SDH30_BUSLOCK_EN		0x00000010
+#define  F_SDH30_SIN			0x00000008
+#define  F_SDH30_AHB_INCR_16		0x00000004
+#define  F_SDH30_AHB_INCR_8		0x00000002
+#define  F_SDH30_AHB_INCR_4		0x00000001
+
+#define F_SDH30_TUNING_SETTING		0x108
+#define  F_SDH30_CMD_CHK_DIS		0x00010000
+
+#define F_SDH30_IO_CONTROL2		0x114
+#define  F_SDH30_CRES_O_DN		0x00080000
+#define  F_SDH30_MSEL_O_1_8		0x00040000
+
+#define F_SDH30_ESD_CONTROL		0x124
+#define  F_SDH30_EMMC_RST		0x00000002
+#define  F_SDH30_EMMC_HS200		0x01000000
+
+#define F_SDH30_CMD_DAT_DELAY		0x200
+
+#define F_SDH30_MIN_CLOCK		400000
+
+struct f_sdhost_priv {
+	struct clk *clk_iface;
+	struct clk *clk;
+	u32 vendor_hs200;
+	struct device *dev;
+};
+
+void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
+{
+	struct f_sdhost_priv *priv = sdhci_priv(host);
+	u32 ctrl = 0;
+
+	usleep_range(2500, 3000);
+	ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
+	ctrl |= F_SDH30_CRES_O_DN;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+	ctrl |= F_SDH30_MSEL_O_1_8;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+
+	ctrl &= ~F_SDH30_CRES_O_DN;
+	sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
+	usleep_range(2500, 3000);
+
+	if (priv->vendor_hs200) {
+		dev_info(priv->dev, "%s: setting hs200\n", __func__);
+		ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+		ctrl |= priv->vendor_hs200;
+		sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
+	}
+
+	ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
+	ctrl |= F_SDH30_CMD_CHK_DIS;
+	sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
+}
+
+unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
+{
+	return F_SDH30_MIN_CLOCK;
+}
+
+void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
+{
+	if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
+		sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
+
+	sdhci_reset(host, mask);
+}
+
+static const struct sdhci_ops sdhci_f_sdh30_ops = {
+	.voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
+	.get_min_clock = sdhci_f_sdh30_get_min_clock,
+	.reset = sdhci_f_sdh30_reset,
+	.set_clock = sdhci_set_clock,
+	.set_bus_width = sdhci_set_bus_width,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+{
+	struct sdhci_host *host;
+	struct device *dev = &pdev->dev;
+	int irq, ctrl = 0, ret = 0;
+	struct f_sdhost_priv *priv;
+	u32 reg = 0;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "%s: no irq specified\n", __func__);
+		ret = irq;
+		goto err;
+	}
+
+	host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
+						sizeof(struct f_sdhost_priv));
+	if (IS_ERR(host)) {
+		dev_err(dev, "%s: host allocate error\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+	priv = sdhci_priv(host);
+	priv->dev = dev;
+
+	host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
+		       SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+	host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
+			SDHCI_QUIRK2_TUNING_WORK_AROUND;
+
+	ret = mmc_of_parse(host->mmc);
+	if (ret)
+		goto err_of_parse;
+
+	ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
+	if (ret)
+		goto err_of_parse;
+
+	platform_set_drvdata(pdev, host);
+
+	sdhci_get_of_property(pdev);
+	host->hw_name = "f_sdh30";
+	host->ops = &sdhci_f_sdh30_ops;
+	host->irq = irq;
+
+	host->ioaddr = of_iomap(pdev->dev.of_node, 0);
+	if (!host->ioaddr) {
+		dev_err(dev, "%s: failed to remap registers\n", __func__);
+		ret = -ENXIO;
+		goto err_remap;
+	}
+
+	priv->clk_iface = clk_get(&pdev->dev, "iface");
+	if (!IS_ERR(priv->clk_iface)) {
+		ret = clk_prepare_enable(priv->clk_iface);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable iface clock: %d\n", ret);
+			goto err_clk1;
+		}
+	}
+	priv->clk = clk_get(&pdev->dev, "core");
+	if (!IS_ERR(priv->clk)) {
+		ret = clk_prepare_enable(priv->clk);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable core clock: %d\n", ret);
+			goto err_clk2;
+		}
+	}
+
+#ifdef CONFIG_PM_RUNTIME
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0)
+		dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
+#endif
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(dev, "%s: host add error\n", __func__);
+		goto err_add_host;
+	}
+
+	/* init vendor specific regs */
+	ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
+	ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
+		F_SDH30_AHB_INCR_4;
+	ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
+	sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
+
+	reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
+	sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
+	msleep(20);
+	sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
+
+	reg = sdhci_readl(host, SDHCI_CAPABILITIES);
+	if (reg & SDHCI_CAN_DO_8BIT)
+		priv->vendor_hs200 = F_SDH30_EMMC_HS200;
+	else
+		priv->vendor_hs200 = 0;
+
+	return 0;
+
+err_add_host:
+	clk_put(priv->clk);
+err_clk2:
+	clk_put(priv->clk_iface);
+err_clk1:
+	iounmap(host->ioaddr);
+err_remap:
+err_of_parse:
+	sdhci_free_host(host);
+err:
+	return ret;
+}
+
+static int sdhci_f_sdh30_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	struct f_sdhost_priv *priv = sdhci_priv(host);
+	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
+			  0xffffffff);
+	iounmap(host->ioaddr);
+	release_mem_region(iomem->start, resource_size(iomem));
+
+	clk_disable_unprepare(priv->clk_iface);
+	clk_disable_unprepare(priv->clk);
+
+	clk_put(priv->clk);
+	clk_put(priv->clk_iface);
+
+	sdhci_free_host(host);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sdhci_f_sdh30_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_suspend_host(host);
+}
+
+static int sdhci_f_sdh30_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_runtime_suspend_host(host);
+}
+
+static int sdhci_f_sdh30_runtime_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	return sdhci_runtime_resume_host(host);
+}
+#endif
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
+	SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
+			   sdhci_f_sdh30_runtime_resume, NULL)
+};
+
+#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
+
+#else
+#define SDHCI_F_SDH30_PMOPS NULL
+#endif
+
+static const struct of_device_id f_sdh30_dt_ids[] = {
+	{ .compatible = "fujitsu,mb86s70-sdh30" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
+
+static struct platform_driver sdhci_f_sdh30_driver = {
+	.driver = {
+		.name = "f_sdh30",
+		.of_match_table = f_sdh30_dt_ids,
+#ifdef CONFIG_PM_SLEEP
+		.pm	= SDHCI_F_SDH30_PMOPS,
+#endif
+	},
+	.probe	= sdhci_f_sdh30_probe,
+	.remove	= sdhci_f_sdh30_remove,
+};
+
+module_platform_driver(sdhci_f_sdh30_driver);
+
+MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
+MODULE_ALIAS("platform:f_sdh30");
-- 
1.9.0

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

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:38     ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:38 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

Add dt files for MB86S7x evb.

Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
 arch/arm/boot/dts/Makefile      |   1 +
 arch/arm/boot/dts/mb86s70.dtsi  |  91 ++++++
 arch/arm/boot/dts/mb86s70eb.dts |  52 ++++
 arch/arm/boot/dts/mb86s73.dtsi  |  49 ++++
 arch/arm/boot/dts/mb86s73eb.dts |  39 +++
 arch/arm/boot/dts/mb86s7x.dtsi  | 595 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 827 insertions(+)
 create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 38c89ca..3a6051b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -163,6 +163,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
 	kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MB86S7X) += mb86s70eb.dtb mb86s73eb.dtb
 dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
diff --git a/arch/arm/boot/dts/mb86s70.dtsi b/arch/arm/boot/dts/mb86s70.dtsi
new file mode 100644
index 0000000..3d5d6bf
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			cci-control-port = <&cci_control4>;
+			clock-frequency = <1200000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			cci-control-port = <&cci_control4>;
+			clock-frequency = <1200000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu2: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu3: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+	};
+
+	cci@2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0x2c090000 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+		cci_control3: slave-if@4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+
+		cci_control4: slave-if@5000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x5000 0x1000>;
+		};
+
+		pmu@9000 {
+			compatible = "arm,cci-400-pmu";
+			reg = <0x9000 0x5000>;
+			interrupts = <0 77 4>,
+					<0 77 4>,
+					<0 77 4>,
+					<0 77 4>,
+					<0 77 4>;
+		};
+	};
+};
+
+&timer1 {
+	status = "disabled";
+};
+
+&pmua7 {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
new file mode 100644
index 0000000..a19c72f
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70eb.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s70.dtsi"
+
+/ {
+	model = "Fujitsu MB86S70 EVB";
+	compatible = "fujitsu,mb86s70-evb";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
+
+	};
+
+	chosen {
+		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+		linux,initrd-start = <0xc0000000>;
+		linux,initrd-end =   <0xc0800000>;
+	};
+
+        vccq_sdhci1: regulator@0 {
+                compatible = "regulator-gpio";
+                regulator-name = "SDHCI1 VccQ";
+                regulator-min-microvolt = <1800000>;
+                regulator-max-microvolt = <3300000>;
+                gpios = <&gpio0 7 0>;
+                gpios-states = <1>;
+                states = <3300000 1
+                          1800000 0>;
+        };
+
+	sdhci1: sdio@36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
+		clock-names = "iface", "core";
+		vqmmc-supply = <&vccq_sdhci1>;
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s73.dtsi b/arch/arm/boot/dts/mb86s73.dtsi
new file mode 100644
index 0000000..45db022
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73.dtsi
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu1: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+	};
+
+	cci@2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0x2c090000 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+		cci_control3: slave-if@4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
new file mode 100644
index 0000000..2bb55a3
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73eb.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s73.dtsi"
+
+/ {
+	model = "Fujitsu MB86S73 EVB";
+	compatible = "fujitsu,mb86s73-evb";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x80000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+		linux,initrd-start = <0xc0000000>;
+		linux,initrd-end =   <0xc0800000>;
+	};
+
+	sdhci1: sdio@36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
+		clock-names = "iface", "core";
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
new file mode 100644
index 0000000..50dcf04
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s7x.dtsi
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/mb86s70-clk.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
+	pmua7: pmu_a7 {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <0 18 4>,
+			     <0 22 4>;
+	};
+
+	/**
+	 * The UngatedCLK is the source of 8 maskable clock ports
+	 * as well as having its own output port which can't be masked.
+	 */
+	clocks {
+		clk_alw_0_0: clk_alw_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_alw_0_1: clk_alw_0_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <1>;
+		};
+
+		clk_alw_0_2: clk_alw_0_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <2>;
+		};
+
+		clk_alw_0_4: clk_alw_0_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <4>;
+		};
+
+		clk_alw_0_5: clk_alw_0_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <5>;
+		};
+
+		clk_alw_0_8: clk_alw_0_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_1_0: clk_alw_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <0>;
+		};
+
+		clk_alw_1_1: clk_alw_1_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <1>;
+		};
+
+		clk_alw_1_2: clk_alw_1_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <2>;
+		};
+
+		clk_alw_1_8: clk_alw_1_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_2_0: clk_alw_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_alw_2_1: clk_alw_2_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <1>;
+		};
+
+		clk_alw_2_2: clk_alw_2_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <2>;
+		};
+
+		clk_alw_2_4: clk_alw_2_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <4>;
+		};
+
+		clk_alw_2_5: clk_alw_2_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <5>;
+		};
+
+		clk_alw_2_8: clk_alw_2_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_6_8: clk_alw_6_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <6>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_7_0: clk_alw_7_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <7>;
+			port = <0>;
+		};
+
+		clk_alw_8_0: clk_alw_8_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <8>;
+			port = <0>;
+		};
+
+		clk_alw_a_0: clk_alw_a_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0a>;
+			port = <0>;
+		};
+
+		clk_alw_a_1: clk_alw_a_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0a>;
+			port = <1>;
+		};
+
+		clk_alw_b_0: clk_alw_b_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0b>;
+			port = <0>;
+		};
+
+		clk_alw_c_0: clk_alw_c_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0c>;
+			port = <0>;
+		};
+
+		clk_ddr3_0_0: clk_ddr3_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DDR3>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_main_0_0: clk_main_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_main_0_8: clk_main_0_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_main_1_3: clk_main_1_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <1>;
+			port = <3>;
+		};
+
+		clk_main_1_4: clk_main_1_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <1>;
+			port = <4>;
+		};
+
+		clk_main_2_0: clk_main_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_main_2_3: clk_main_2_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <3>;
+		};
+
+		clk_main_2_4: clk_main_2_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <4>;
+		};
+
+		clk_main_2_7: clk_main_2_7 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <7>;
+		};
+
+		clk_main_3_0: clk_main_3_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <0>;
+		};
+
+		clk_main_3_3: clk_main_3_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <3>;
+		};
+
+		clk_main_3_4: clk_main_3_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <4>;
+		};
+
+		clk_main_3_5: clk_main_3_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <5>;
+		};
+
+		clk_main_3_6: clk_main_3_6 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <6>;
+		};
+
+		clk_main_4_0: clk_main_4_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <0>;
+		};
+
+		clk_main_4_4: clk_main_4_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <4>;
+		};
+
+		clk_main_4_5: clk_main_4_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <5>;
+		};
+
+		clk_main_5_0: clk_main_5_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <0>;
+		};
+
+		clk_main_5_3: clk_main_5_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <3>;
+		};
+
+		clk_main_5_4: clk_main_5_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <4>;
+		};
+
+		clk_main_5_5: clk_main_5_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <5>;
+		};
+
+		clk_main_7_0: clk_main_7_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <7>;
+			port = <0>;
+		};
+
+		clk_main_8_1: clk_main_8_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <8>;
+			port = <1>;
+		};
+
+		clk_main_9_0: clk_main_9_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <9>;
+			port = <0>;
+		};
+
+		clk_main_a_0: clk_main_a_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xa>;
+			port = <0>;
+		};
+
+		clk_main_b_0: clk_main_b_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xb>;
+			port = <0>;
+		};
+
+		clk_main_c_0: clk_main_c_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xc>;
+			port = <0>;
+		};
+
+		clk_main_d_0: clk_main_d_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xd>;
+			port = <0>;
+		};
+
+		clk_usb_0_0: clk_usb_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_usb_1_0: clk_usb_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <1>;
+			port = <0>;
+		};
+
+		clk_usb_2_0: clk_usb_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_usb_3_0: clk_usb_3_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <3>;
+			port = <0>;
+		};
+
+		clk_fpdlink_0_0: clk_fpdlink_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DPHY>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_fpdlink_1_0: clk_fpdlink_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DPHY>;
+			domain = <1>;
+			port = <0>;
+		};
+	};
+
+	timer0: timer@31080000 {
+		compatible = "arm,sp804", "arm,primecell";
+		reg = <0 0x31080000 0x1000>;
+		interrupts = <0 324 4>,
+			     <0 325 4>;
+		clocks = <&clk_alw_6_8>;
+		clock-names = "apb_pclk";
+	};
+
+	timer1: archtimer {
+		compatible = "arm,armv7-timer";
+		clock-frequency = <125000000>;
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0 0x2c001000 0x1000>,
+		      <0 0x2c002000 0x1000>,
+		      <0 0x2c004000 0x2000>,
+		      <0 0x2c006000 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	mhu: mailbox@2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+	};
+
+	mhu_client: scb@2e000000 {
+		compatible = "fujitsu,mb86s70-scb-1.0";
+		reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+		mboxes = <&mhu 1>;
+	};
+
+	uart0: serial@31040000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31040000 0x100>;
+		interrupts = <0 320 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	uart1: serial@31050000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31050000 0x100>;
+		interrupts = <0 321 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	uart2: serial@31060000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31060000 0x100>;
+		interrupts = <0 322 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	gpio0: gpio@31000000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31000000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
+
+	gpio1: gpio@31010000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31010000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
+
+	sdhci0: emmc@300c0000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x300c0000 0x1000>;
+		interrupts = <0 164 0x4>,
+			     <0 165 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <8>;
+		clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
+		clock-names = "iface", "core";
+	};
+};
-- 
1.9.0

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

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

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-20 12:38     ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

Add dt files for MB86S7x evb.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 arch/arm/boot/dts/Makefile      |   1 +
 arch/arm/boot/dts/mb86s70.dtsi  |  91 ++++++
 arch/arm/boot/dts/mb86s70eb.dts |  52 ++++
 arch/arm/boot/dts/mb86s73.dtsi  |  49 ++++
 arch/arm/boot/dts/mb86s73eb.dts |  39 +++
 arch/arm/boot/dts/mb86s7x.dtsi  | 595 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 827 insertions(+)
 create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
 create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
 create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 38c89ca..3a6051b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -163,6 +163,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
 	kirkwood-ts419-6282.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MB86S7X) += mb86s70eb.dtb mb86s73eb.dtb
 dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
diff --git a/arch/arm/boot/dts/mb86s70.dtsi b/arch/arm/boot/dts/mb86s70.dtsi
new file mode 100644
index 0000000..3d5d6bf
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			cci-control-port = <&cci_control4>;
+			clock-frequency = <1200000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			cci-control-port = <&cci_control4>;
+			clock-frequency = <1200000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu2: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu3: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+	};
+
+	cci at 2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0x2c090000 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+		cci_control3: slave-if at 4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+
+		cci_control4: slave-if at 5000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x5000 0x1000>;
+		};
+
+		pmu at 9000 {
+			compatible = "arm,cci-400-pmu";
+			reg = <0x9000 0x5000>;
+			interrupts = <0 77 4>,
+					<0 77 4>,
+					<0 77 4>,
+					<0 77 4>,
+					<0 77 4>;
+		};
+	};
+};
+
+&timer1 {
+	status = "disabled";
+};
+
+&pmua7 {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
new file mode 100644
index 0000000..a19c72f
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70eb.dts
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s70.dtsi"
+
+/ {
+	model = "Fujitsu MB86S70 EVB";
+	compatible = "fujitsu,mb86s70-evb";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
+
+	};
+
+	chosen {
+		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+		linux,initrd-start = <0xc0000000>;
+		linux,initrd-end =   <0xc0800000>;
+	};
+
+        vccq_sdhci1: regulator at 0 {
+                compatible = "regulator-gpio";
+                regulator-name = "SDHCI1 VccQ";
+                regulator-min-microvolt = <1800000>;
+                regulator-max-microvolt = <3300000>;
+                gpios = <&gpio0 7 0>;
+                gpios-states = <1>;
+                states = <3300000 1
+                          1800000 0>;
+        };
+
+	sdhci1: sdio at 36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
+		clock-names = "iface", "core";
+		vqmmc-supply = <&vccq_sdhci1>;
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s73.dtsi b/arch/arm/boot/dts/mb86s73.dtsi
new file mode 100644
index 0000000..45db022
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73.dtsi
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+
+		cpu1: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			cci-control-port = <&cci_control3>;
+			clock-frequency = <800000000>;
+			clock-latency = <100000>;
+		};
+	};
+
+	cci at 2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0 0x2c090000 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+		cci_control3: slave-if at 4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
new file mode 100644
index 0000000..2bb55a3
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73eb.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s73.dtsi"
+
+/ {
+	model = "Fujitsu MB86S73 EVB";
+	compatible = "fujitsu,mb86s73-evb";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x80000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+		linux,initrd-start = <0xc0000000>;
+		linux,initrd-end =   <0xc0800000>;
+	};
+
+	sdhci1: sdio at 36600000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x36600000 0x1000>;
+		interrupts = <0 172 0x4>,
+			     <0 173 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <4>;
+		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
+		clock-names = "iface", "core";
+	};
+};
diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
new file mode 100644
index 0000000..50dcf04
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s7x.dtsi
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * 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, version 2 of the License.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/mb86s70-clk.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
+	pmua7: pmu_a7 {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <0 18 4>,
+			     <0 22 4>;
+	};
+
+	/**
+	 * The UngatedCLK is the source of 8 maskable clock ports
+	 * as well as having its own output port which can't be masked.
+	 */
+	clocks {
+		clk_alw_0_0: clk_alw_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_alw_0_1: clk_alw_0_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <1>;
+		};
+
+		clk_alw_0_2: clk_alw_0_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <2>;
+		};
+
+		clk_alw_0_4: clk_alw_0_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <4>;
+		};
+
+		clk_alw_0_5: clk_alw_0_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <5>;
+		};
+
+		clk_alw_0_8: clk_alw_0_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_1_0: clk_alw_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <0>;
+		};
+
+		clk_alw_1_1: clk_alw_1_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <1>;
+		};
+
+		clk_alw_1_2: clk_alw_1_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <2>;
+		};
+
+		clk_alw_1_8: clk_alw_1_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <1>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_2_0: clk_alw_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_alw_2_1: clk_alw_2_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <1>;
+		};
+
+		clk_alw_2_2: clk_alw_2_2 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <2>;
+		};
+
+		clk_alw_2_4: clk_alw_2_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <4>;
+		};
+
+		clk_alw_2_5: clk_alw_2_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <5>;
+		};
+
+		clk_alw_2_8: clk_alw_2_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <2>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_6_8: clk_alw_6_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <6>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_alw_7_0: clk_alw_7_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <7>;
+			port = <0>;
+		};
+
+		clk_alw_8_0: clk_alw_8_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <8>;
+			port = <0>;
+		};
+
+		clk_alw_a_0: clk_alw_a_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0a>;
+			port = <0>;
+		};
+
+		clk_alw_a_1: clk_alw_a_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0a>;
+			port = <1>;
+		};
+
+		clk_alw_b_0: clk_alw_b_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0b>;
+			port = <0>;
+		};
+
+		clk_alw_c_0: clk_alw_c_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_ALW>;
+			domain = <0x0c>;
+			port = <0>;
+		};
+
+		clk_ddr3_0_0: clk_ddr3_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DDR3>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_main_0_0: clk_main_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_main_0_8: clk_main_0_8 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0>;
+			port = <MB86S70_CRG11_UNGPRT>;
+		};
+
+		clk_main_1_3: clk_main_1_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <1>;
+			port = <3>;
+		};
+
+		clk_main_1_4: clk_main_1_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <1>;
+			port = <4>;
+		};
+
+		clk_main_2_0: clk_main_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_main_2_3: clk_main_2_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <3>;
+		};
+
+		clk_main_2_4: clk_main_2_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <4>;
+		};
+
+		clk_main_2_7: clk_main_2_7 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <2>;
+			port = <7>;
+		};
+
+		clk_main_3_0: clk_main_3_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <0>;
+		};
+
+		clk_main_3_3: clk_main_3_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <3>;
+		};
+
+		clk_main_3_4: clk_main_3_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <4>;
+		};
+
+		clk_main_3_5: clk_main_3_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <5>;
+		};
+
+		clk_main_3_6: clk_main_3_6 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <3>;
+			port = <6>;
+		};
+
+		clk_main_4_0: clk_main_4_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <0>;
+		};
+
+		clk_main_4_4: clk_main_4_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <4>;
+		};
+
+		clk_main_4_5: clk_main_4_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <4>;
+			port = <5>;
+		};
+
+		clk_main_5_0: clk_main_5_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <0>;
+		};
+
+		clk_main_5_3: clk_main_5_3 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <3>;
+		};
+
+		clk_main_5_4: clk_main_5_4 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <4>;
+		};
+
+		clk_main_5_5: clk_main_5_5 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <5>;
+			port = <5>;
+		};
+
+		clk_main_7_0: clk_main_7_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <7>;
+			port = <0>;
+		};
+
+		clk_main_8_1: clk_main_8_1 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <8>;
+			port = <1>;
+		};
+
+		clk_main_9_0: clk_main_9_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <9>;
+			port = <0>;
+		};
+
+		clk_main_a_0: clk_main_a_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xa>;
+			port = <0>;
+		};
+
+		clk_main_b_0: clk_main_b_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xb>;
+			port = <0>;
+		};
+
+		clk_main_c_0: clk_main_c_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xc>;
+			port = <0>;
+		};
+
+		clk_main_d_0: clk_main_d_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_MAIN>;
+			domain = <0xd>;
+			port = <0>;
+		};
+
+		clk_usb_0_0: clk_usb_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_usb_1_0: clk_usb_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <1>;
+			port = <0>;
+		};
+
+		clk_usb_2_0: clk_usb_2_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <2>;
+			port = <0>;
+		};
+
+		clk_usb_3_0: clk_usb_3_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_HDMI>;
+			domain = <3>;
+			port = <0>;
+		};
+
+		clk_fpdlink_0_0: clk_fpdlink_0_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DPHY>;
+			domain = <0>;
+			port = <0>;
+		};
+
+		clk_fpdlink_1_0: clk_fpdlink_1_0 {
+			compatible = "fujitsu,mb86s70-clk";
+			#clock-cells = <0>;
+			cntrlr = <MB86S70_CRG11_DPHY>;
+			domain = <1>;
+			port = <0>;
+		};
+	};
+
+	timer0: timer at 31080000 {
+		compatible = "arm,sp804", "arm,primecell";
+		reg = <0 0x31080000 0x1000>;
+		interrupts = <0 324 4>,
+			     <0 325 4>;
+		clocks = <&clk_alw_6_8>;
+		clock-names = "apb_pclk";
+	};
+
+	timer1: archtimer {
+		compatible = "arm,armv7-timer";
+		clock-frequency = <125000000>;
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+
+	gic: interrupt-controller at 2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0 0x2c001000 0x1000>,
+		      <0 0x2c002000 0x1000>,
+		      <0 0x2c004000 0x2000>,
+		      <0 0x2c006000 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	mhu: mailbox at 2b1f0000 {
+		#mbox-cells = <1>;
+		compatible = "arm,mbox-mhu";
+		reg = <0 0x2b1f0000 0x1000>;
+		interrupts = <0 36 4>, /* LP Non-Sec */
+			     <0 35 4>, /* HP Non-Sec */
+			     <0 37 4>; /* Secure */
+	};
+
+	mhu_client: scb at 2e000000 {
+		compatible = "fujitsu,mb86s70-scb-1.0";
+		reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+		mboxes = <&mhu 1>;
+	};
+
+	uart0: serial at 31040000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31040000 0x100>;
+		interrupts = <0 320 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	uart1: serial at 31050000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31050000 0x100>;
+		interrupts = <0 321 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	uart2: serial at 31060000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0 0x31060000 0x100>;
+		interrupts = <0 322 0x4>;
+		clock-frequency = <62500000>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		clocks = <&clk_alw_2_1>;
+		clock-names = "sclk";
+	};
+
+	gpio0: gpio at 31000000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31000000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
+
+	gpio1: gpio at 31010000 {
+		compatible = "fujitsu,mb86s70-gpio";
+		reg = <0 0x31010000 0x10000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&clk_alw_2_1>;
+	};
+
+	sdhci0: emmc at 300c0000 {
+		compatible = "fujitsu,mb86s70-sdh30";
+		reg = <0 0x300c0000 0x1000>;
+		interrupts = <0 164 0x4>,
+			     <0 165 0x4>;
+		voltage-ranges = <1800 1800>, <3300 3300>;
+		bus-width = <8>;
+		clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
+		clock-names = "iface", "core";
+	};
+};
-- 
1.9.0

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

* [PATCH 8/9] of: add Fujitsu vendor prefix
  2014-11-20 12:27 ` Vincent Yang
@ 2014-11-20 12:39     ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:39 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.

Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 723999d..dbb7c97 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -56,6 +56,7 @@ everest	Everest Semiconductor Co. Ltd.
 excito	Excito
 fcs	Fairchild Semiconductor
 fsl	Freescale Semiconductor
+fujitsu Fujitsu Semiconductor Ltd.
 GEFanuc	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 geniatech	Geniatech, Inc.
-- 
1.9.0

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

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

* [PATCH 8/9] of: add Fujitsu vendor prefix
@ 2014-11-20 12:39     ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 723999d..dbb7c97 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -56,6 +56,7 @@ everest	Everest Semiconductor Co. Ltd.
 excito	Excito
 fcs	Fairchild Semiconductor
 fsl	Freescale Semiconductor
+fujitsu Fujitsu Semiconductor Ltd.
 GEFanuc	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 geniatech	Geniatech, Inc.
-- 
1.9.0

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

* [PATCH 9/9] ARM: MB86S7x: Add configs
  2014-11-20 12:27 ` Vincent Yang
                   ` (4 preceding siblings ...)
  (?)
@ 2014-11-20 12:40 ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Fujitsu's ARCH_MB86S7X is multi_v7 compatible, so add options to
multi_v7_defconfig. Also add a new defconfig for MB86S7X for those
who want the kernel built specifically for ARCH_MB86S7X.

Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
 arch/arm/configs/fujitsu_defconfig  | 232 ++++++++++++++++++++++++++++++++++++
 arch/arm/configs/multi_v7_defconfig |   5 +
 2 files changed, 237 insertions(+)
 create mode 100644 arch/arm/configs/fujitsu_defconfig

diff --git a/arch/arm/configs/fujitsu_defconfig b/arch/arm/configs/fujitsu_defconfig
new file mode 100644
index 0000000..2d922e4
--- /dev/null
+++ b/arch/arm/configs/fujitsu_defconfig
@@ -0,0 +1,232 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="MB86S7x"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_MB86S7X=y
+CONFIG_ARM_LPAE=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_ERRATA_798181=y
+CONFIG_PCI=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT=y
+CONFIG_THUMB2_KERNEL=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_CMA_AREAS=8
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=2048M console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw"
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=m
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=192
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+# CONFIG_ATA_VERBOSE_ERROR is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_SATA_AHCI_PLATFORM=m
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO_POLLED=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_GPIO=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EGALAX=m
+CONFIG_TOUCHSCREEN_ILI210X=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_SPI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MB86S7X=y
+CONFIG_GPIO_MCP23S08=m
+# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_GPIO=y
+# CONFIG_VGA_ARB is not set
+CONFIG_DRM=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=m
+CONFIG_HID=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=m
+CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_HCD_PCI is not set
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_DWC3=m
+CONFIG_USB_DWC3_HOST=y
+CONFIG_USB_DWC3_DEBUG=y
+CONFIG_USB_GADGET=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_MULTI=m
+CONFIG_MMC=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_F_SDH30=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_DMADEVICES=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOGGER=m
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ION=y
+CONFIG_ARM_MHU=y
+CONFIG_ARM_SMMU=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=m
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BOTH=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_FONTS=y
+CONFIG_FONT_SUN8x16=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 3487046..2b22f44 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -45,6 +45,7 @@ CONFIG_SOC_AM43XX=y
 CONFIG_SOC_DRA7XX=y
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MB86S7X=y
 CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
@@ -247,6 +248,7 @@ CONFIG_GPIO_TWL4030=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_MB86S7X=y
 CONFIG_BATTERY_SBS=y
 CONFIG_CHARGER_TPS65090=y
 CONFIG_POWER_RESET_AS3722=y
@@ -348,6 +350,7 @@ CONFIG_MMC_SDHCI_SPEAR=y
 CONFIG_MMC_SDHCI_S3C=y
 CONFIG_MMC_SDHCI_S3C_DMA=y
 CONFIG_MMC_SDHCI_BCM_KONA=y
+CONFIG_MMC_SDHCI_F_SDH30=y
 CONFIG_MMC_SDHCI_ST=y
 CONFIG_MMC_OMAP=y
 CONFIG_MMC_OMAP_HS=y
@@ -429,6 +432,8 @@ CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
 CONFIG_PHY_MIPHY365X=y
 CONFIG_PHY_SUN4I_USB=y
+CONFIG_MAILBOX=y
+CONFIG_ARM_MHU=y
 CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
-- 
1.9.0

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

* Re: [PATCH 8/9] of: add Fujitsu vendor prefix
  2014-11-20 12:39     ` Vincent Yang
@ 2014-11-20 15:07         ` Rob Herring
  -1 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 15:07 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann,
	Olof Johansson, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Andy Green, Linaro Patches,
	Jaswinder Singh, Vincent Yang, Tetsuya Nuriya

On Thu, Nov 20, 2014 at 6:39 AM, Vincent Yang
<vincent.yang.fujitsu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
>
> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

> ---
>  Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 723999d..dbb7c97 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -56,6 +56,7 @@ everest       Everest Semiconductor Co. Ltd.
>  excito Excito
>  fcs    Fairchild Semiconductor
>  fsl    Freescale Semiconductor
> +fujitsu Fujitsu Semiconductor Ltd.
>  GEFanuc        GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>  gef    GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>  geniatech      Geniatech, Inc.
> --
> 1.9.0
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 8/9] of: add Fujitsu vendor prefix
@ 2014-11-20 15:07         ` Rob Herring
  0 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 20, 2014 at 6:39 AM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>

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

> ---
>  Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 723999d..dbb7c97 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -56,6 +56,7 @@ everest       Everest Semiconductor Co. Ltd.
>  excito Excito
>  fcs    Fairchild Semiconductor
>  fsl    Freescale Semiconductor
> +fujitsu Fujitsu Semiconductor Ltd.
>  GEFanuc        GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>  gef    GE Fanuc Intelligent Platforms Embedded Systems, Inc.
>  geniatech      Geniatech, Inc.
> --
> 1.9.0
>

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

* Re: [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
  2014-11-20 12:38   ` Vincent Yang
@ 2014-11-20 15:22     ` Rob Herring
  -1 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 15:22 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree, linux-mmc, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, chris,
	Ulf Hansson, Andy Green, Linaro Patches, Jaswinder Singh,
	Vincent Yang, Tetsuya Takinishi

On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> This patch adds new host controller driver for
> Fujitsu SDHCI controller f_sdh30.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
> ---
>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>  drivers/mmc/host/Kconfig                           |   9 +
>  drivers/mmc/host/Makefile                          |   1 +
>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>  4 files changed, 364 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
> new file mode 100644
> index 0000000..a1e0b64
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
> @@ -0,0 +1,35 @@
> +* Fujitsu SDHCI controller
> +
> +This file documents differences between the core properties in mmc.txt
> +and the properties used by the sdhci_f_sdh30 driver.
> +
> +Required properties:
> +- compatible: "fujitsu,mb86s70-sdh30"

It would be nice to have sdhci in the name to indicate it is an SDHCI
controller.

> +- voltage-ranges : This is a list of pairs. In each pair, two cells
> +  are required. First cell specifies minimum slot voltage (mV), second
> +  cell specifies maximum slot voltage (mV). In case of supported voltage
> +  range is discontinuous, several ranges could be specified as a list.
> +
> +Optional properties:
> +- vqmmc-supply: phandle to the regulator device tree node, mentioned
> +  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
> +- clocks: Must contain an entry for each entry in clock-names. It is a
> +  list of phandles and clock-specifier pairs.
> +  See ../clocks/clock-bindings.txt for details.
> +- clock-names: Should contain the following two entries:
> +       "iface" - clock used for sdhci interface
> +       "core"  - core clock for sdhci controller
> +
> +Example:
> +
> +       sdhci1: sdio@36600000 {
> +               compatible = "fujitsu,mb86s70-sdh30";
> +               reg = <0 0x36600000 0x1000>;
> +               interrupts = <0 172 0x4>,
> +                            <0 173 0x4>;
> +               voltage-ranges = <1800 1800>, <3300 3300>;
> +               bus-width = <4>;
> +               vqmmc-supply = <&vccq_sdhci1>;
> +               clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
> +               clock-names = "iface", "core";
> +       };
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 1386065..cbe5e3c 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
>           This selects the BCM2835 SD/MMC controller. If you have a BCM2835
>           platform with SD or MMC devices, say Y or M here.
>
> +config MMC_SDHCI_F_SDH30
> +       tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
> +       depends on ARCH_MB86S7X
> +       depends on MMC_SDHCI_PLTFM
> +       depends on OF
> +       help
> +         This selects the Secure Digital Host Controller Interface (SDHCI)
> +         Needed by some Fujitsu SoC for MMC / SD / SDIO support.
> +         If you have a controller with this interface, say Y or M here.
>           If unsure, say N.
>
>  config MMC_MOXART
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index b09ecfb..63efc38 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
>  obj-$(CONFIG_MMC_SDHCI_PXAV2)  += sdhci-pxav2.o
>  obj-$(CONFIG_MMC_SDHCI_S3C)    += sdhci-s3c.o
>  obj-$(CONFIG_MMC_SDHCI_SIRF)           += sdhci-sirf.o
> +obj-$(CONFIG_MMC_SDHCI_F_SDH30)        += sdhci_f_sdh30.o
>  obj-$(CONFIG_MMC_SDHCI_SPEAR)  += sdhci-spear.o
>  obj-$(CONFIG_MMC_WBSD)         += wbsd.o
>  obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
> diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
> new file mode 100644
> index 0000000..f6eba5a
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci_f_sdh30.c
> @@ -0,0 +1,319 @@
> +/*
> + * linux/drivers/mmc/host/sdhci_f_sdh30.c
> + *
> + * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
> + *              Vincent Yang <vincent.yang@tw.fujitsu.com>
> + * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/mmc/sd.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/card.h>
> +#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/suspend.h>
> +
> +#include "sdhci.h"
> +#include "sdhci-pltfm.h"
> +
> +/* F_SDH30 extended Controller registers */
> +#define F_SDH30_AHB_CONFIG             0x100
> +#define  F_SDH30_AHB_BIGED             0x00000040
> +#define  F_SDH30_BUSLOCK_DMA           0x00000020
> +#define  F_SDH30_BUSLOCK_EN            0x00000010
> +#define  F_SDH30_SIN                   0x00000008
> +#define  F_SDH30_AHB_INCR_16           0x00000004
> +#define  F_SDH30_AHB_INCR_8            0x00000002
> +#define  F_SDH30_AHB_INCR_4            0x00000001
> +
> +#define F_SDH30_TUNING_SETTING         0x108
> +#define  F_SDH30_CMD_CHK_DIS           0x00010000
> +
> +#define F_SDH30_IO_CONTROL2            0x114
> +#define  F_SDH30_CRES_O_DN             0x00080000
> +#define  F_SDH30_MSEL_O_1_8            0x00040000
> +
> +#define F_SDH30_ESD_CONTROL            0x124
> +#define  F_SDH30_EMMC_RST              0x00000002
> +#define  F_SDH30_EMMC_HS200            0x01000000
> +
> +#define F_SDH30_CMD_DAT_DELAY          0x200
> +
> +#define F_SDH30_MIN_CLOCK              400000
> +
> +struct f_sdhost_priv {
> +       struct clk *clk_iface;
> +       struct clk *clk;
> +       u32 vendor_hs200;
> +       struct device *dev;
> +};
> +
> +void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
> +{
> +       struct f_sdhost_priv *priv = sdhci_priv(host);
> +       u32 ctrl = 0;
> +
> +       usleep_range(2500, 3000);
> +       ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
> +       ctrl |= F_SDH30_CRES_O_DN;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +       ctrl |= F_SDH30_MSEL_O_1_8;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +
> +       ctrl &= ~F_SDH30_CRES_O_DN;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +       usleep_range(2500, 3000);
> +
> +       if (priv->vendor_hs200) {
> +               dev_info(priv->dev, "%s: setting hs200\n", __func__);
> +               ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
> +               ctrl |= priv->vendor_hs200;
> +               sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
> +       }
> +
> +       ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
> +       ctrl |= F_SDH30_CMD_CHK_DIS;
> +       sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
> +}
> +
> +unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
> +{
> +       return F_SDH30_MIN_CLOCK;
> +}
> +
> +void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
> +{
> +       if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
> +               sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
> +
> +       sdhci_reset(host, mask);
> +}
> +
> +static const struct sdhci_ops sdhci_f_sdh30_ops = {
> +       .voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
> +       .get_min_clock = sdhci_f_sdh30_get_min_clock,
> +       .reset = sdhci_f_sdh30_reset,
> +       .set_clock = sdhci_set_clock,
> +       .set_bus_width = sdhci_set_bus_width,
> +       .set_uhs_signaling = sdhci_set_uhs_signaling,
> +};
> +
> +static int sdhci_f_sdh30_probe(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host;
> +       struct device *dev = &pdev->dev;
> +       int irq, ctrl = 0, ret = 0;
> +       struct f_sdhost_priv *priv;
> +       u32 reg = 0;
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0) {
> +               dev_err(dev, "%s: no irq specified\n", __func__);
> +               ret = irq;
> +               goto err;
> +       }
> +
> +       host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
> +                                               sizeof(struct f_sdhost_priv));
> +       if (IS_ERR(host)) {
> +               dev_err(dev, "%s: host allocate error\n", __func__);
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +       priv = sdhci_priv(host);
> +       priv->dev = dev;
> +
> +       host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
> +                      SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
> +       host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
> +                       SDHCI_QUIRK2_TUNING_WORK_AROUND;
> +
> +       ret = mmc_of_parse(host->mmc);
> +       if (ret)
> +               goto err_of_parse;
> +
> +       ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
> +       if (ret)
> +               goto err_of_parse;
> +
> +       platform_set_drvdata(pdev, host);
> +
> +       sdhci_get_of_property(pdev);
> +       host->hw_name = "f_sdh30";
> +       host->ops = &sdhci_f_sdh30_ops;
> +       host->irq = irq;
> +
> +       host->ioaddr = of_iomap(pdev->dev.of_node, 0);
> +       if (!host->ioaddr) {
> +               dev_err(dev, "%s: failed to remap registers\n", __func__);
> +               ret = -ENXIO;
> +               goto err_remap;
> +       }
> +
> +       priv->clk_iface = clk_get(&pdev->dev, "iface");
> +       if (!IS_ERR(priv->clk_iface)) {
> +               ret = clk_prepare_enable(priv->clk_iface);
> +               if (ret < 0) {
> +                       dev_err(dev, "Failed to enable iface clock: %d\n", ret);
> +                       goto err_clk1;
> +               }
> +       }
> +       priv->clk = clk_get(&pdev->dev, "core");
> +       if (!IS_ERR(priv->clk)) {
> +               ret = clk_prepare_enable(priv->clk);
> +               if (ret < 0) {
> +                       dev_err(dev, "Failed to enable core clock: %d\n", ret);
> +                       goto err_clk2;
> +               }
> +       }
> +
> +#ifdef CONFIG_PM_RUNTIME
> +       pm_runtime_set_active(&pdev->dev);
> +       pm_runtime_enable(&pdev->dev);
> +       ret = pm_runtime_get_sync(&pdev->dev);
> +       if (ret < 0)
> +               dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
> +#endif
> +
> +       ret = sdhci_add_host(host);
> +       if (ret) {
> +               dev_err(dev, "%s: host add error\n", __func__);
> +               goto err_add_host;
> +       }
> +
> +       /* init vendor specific regs */
> +       ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
> +       ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
> +               F_SDH30_AHB_INCR_4;
> +       ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
> +       sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
> +
> +       reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
> +       sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
> +       msleep(20);
> +       sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
> +
> +       reg = sdhci_readl(host, SDHCI_CAPABILITIES);
> +       if (reg & SDHCI_CAN_DO_8BIT)
> +               priv->vendor_hs200 = F_SDH30_EMMC_HS200;
> +       else
> +               priv->vendor_hs200 = 0;
> +
> +       return 0;
> +
> +err_add_host:
> +       clk_put(priv->clk);
> +err_clk2:
> +       clk_put(priv->clk_iface);
> +err_clk1:
> +       iounmap(host->ioaddr);
> +err_remap:
> +err_of_parse:
> +       sdhci_free_host(host);
> +err:
> +       return ret;
> +}
> +
> +static int sdhci_f_sdh30_remove(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host = platform_get_drvdata(pdev);
> +       struct f_sdhost_priv *priv = sdhci_priv(host);
> +       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +       sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
> +                         0xffffffff);
> +       iounmap(host->ioaddr);
> +       release_mem_region(iomem->start, resource_size(iomem));
> +
> +       clk_disable_unprepare(priv->clk_iface);
> +       clk_disable_unprepare(priv->clk);
> +
> +       clk_put(priv->clk);
> +       clk_put(priv->clk_iface);
> +
> +       sdhci_free_host(host);
> +       platform_set_drvdata(pdev, NULL);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int sdhci_f_sdh30_suspend(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_suspend_host(host);
> +}
> +
> +static int sdhci_f_sdh30_resume(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_resume_host(host);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM_RUNTIME
> +static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_runtime_suspend_host(host);
> +}
> +
> +static int sdhci_f_sdh30_runtime_resume(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_runtime_resume_host(host);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM
> +static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
> +       SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
> +                          sdhci_f_sdh30_runtime_resume, NULL)
> +};
> +
> +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
> +
> +#else
> +#define SDHCI_F_SDH30_PMOPS NULL
> +#endif
> +
> +static const struct of_device_id f_sdh30_dt_ids[] = {
> +       { .compatible = "fujitsu,mb86s70-sdh30" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
> +
> +static struct platform_driver sdhci_f_sdh30_driver = {
> +       .driver = {
> +               .name = "f_sdh30",
> +               .of_match_table = f_sdh30_dt_ids,
> +#ifdef CONFIG_PM_SLEEP
> +               .pm     = SDHCI_F_SDH30_PMOPS,
> +#endif
> +       },
> +       .probe  = sdhci_f_sdh30_probe,
> +       .remove = sdhci_f_sdh30_remove,
> +};
> +
> +module_platform_driver(sdhci_f_sdh30_driver);
> +
> +MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
> +MODULE_ALIAS("platform:f_sdh30");
> --
> 1.9.0
>

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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
@ 2014-11-20 15:22     ` Rob Herring
  0 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> This patch adds new host controller driver for
> Fujitsu SDHCI controller f_sdh30.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
> ---
>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>  drivers/mmc/host/Kconfig                           |   9 +
>  drivers/mmc/host/Makefile                          |   1 +
>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>  4 files changed, 364 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
> new file mode 100644
> index 0000000..a1e0b64
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
> @@ -0,0 +1,35 @@
> +* Fujitsu SDHCI controller
> +
> +This file documents differences between the core properties in mmc.txt
> +and the properties used by the sdhci_f_sdh30 driver.
> +
> +Required properties:
> +- compatible: "fujitsu,mb86s70-sdh30"

It would be nice to have sdhci in the name to indicate it is an SDHCI
controller.

> +- voltage-ranges : This is a list of pairs. In each pair, two cells
> +  are required. First cell specifies minimum slot voltage (mV), second
> +  cell specifies maximum slot voltage (mV). In case of supported voltage
> +  range is discontinuous, several ranges could be specified as a list.
> +
> +Optional properties:
> +- vqmmc-supply: phandle to the regulator device tree node, mentioned
> +  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
> +- clocks: Must contain an entry for each entry in clock-names. It is a
> +  list of phandles and clock-specifier pairs.
> +  See ../clocks/clock-bindings.txt for details.
> +- clock-names: Should contain the following two entries:
> +       "iface" - clock used for sdhci interface
> +       "core"  - core clock for sdhci controller
> +
> +Example:
> +
> +       sdhci1: sdio at 36600000 {
> +               compatible = "fujitsu,mb86s70-sdh30";
> +               reg = <0 0x36600000 0x1000>;
> +               interrupts = <0 172 0x4>,
> +                            <0 173 0x4>;
> +               voltage-ranges = <1800 1800>, <3300 3300>;
> +               bus-width = <4>;
> +               vqmmc-supply = <&vccq_sdhci1>;
> +               clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
> +               clock-names = "iface", "core";
> +       };
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 1386065..cbe5e3c 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
>           This selects the BCM2835 SD/MMC controller. If you have a BCM2835
>           platform with SD or MMC devices, say Y or M here.
>
> +config MMC_SDHCI_F_SDH30
> +       tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
> +       depends on ARCH_MB86S7X
> +       depends on MMC_SDHCI_PLTFM
> +       depends on OF
> +       help
> +         This selects the Secure Digital Host Controller Interface (SDHCI)
> +         Needed by some Fujitsu SoC for MMC / SD / SDIO support.
> +         If you have a controller with this interface, say Y or M here.
>           If unsure, say N.
>
>  config MMC_MOXART
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index b09ecfb..63efc38 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
>  obj-$(CONFIG_MMC_SDHCI_PXAV2)  += sdhci-pxav2.o
>  obj-$(CONFIG_MMC_SDHCI_S3C)    += sdhci-s3c.o
>  obj-$(CONFIG_MMC_SDHCI_SIRF)           += sdhci-sirf.o
> +obj-$(CONFIG_MMC_SDHCI_F_SDH30)        += sdhci_f_sdh30.o
>  obj-$(CONFIG_MMC_SDHCI_SPEAR)  += sdhci-spear.o
>  obj-$(CONFIG_MMC_WBSD)         += wbsd.o
>  obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
> diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
> new file mode 100644
> index 0000000..f6eba5a
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci_f_sdh30.c
> @@ -0,0 +1,319 @@
> +/*
> + * linux/drivers/mmc/host/sdhci_f_sdh30.c
> + *
> + * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
> + *              Vincent Yang <vincent.yang@tw.fujitsu.com>
> + * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/mmc/sd.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/card.h>
> +#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/suspend.h>
> +
> +#include "sdhci.h"
> +#include "sdhci-pltfm.h"
> +
> +/* F_SDH30 extended Controller registers */
> +#define F_SDH30_AHB_CONFIG             0x100
> +#define  F_SDH30_AHB_BIGED             0x00000040
> +#define  F_SDH30_BUSLOCK_DMA           0x00000020
> +#define  F_SDH30_BUSLOCK_EN            0x00000010
> +#define  F_SDH30_SIN                   0x00000008
> +#define  F_SDH30_AHB_INCR_16           0x00000004
> +#define  F_SDH30_AHB_INCR_8            0x00000002
> +#define  F_SDH30_AHB_INCR_4            0x00000001
> +
> +#define F_SDH30_TUNING_SETTING         0x108
> +#define  F_SDH30_CMD_CHK_DIS           0x00010000
> +
> +#define F_SDH30_IO_CONTROL2            0x114
> +#define  F_SDH30_CRES_O_DN             0x00080000
> +#define  F_SDH30_MSEL_O_1_8            0x00040000
> +
> +#define F_SDH30_ESD_CONTROL            0x124
> +#define  F_SDH30_EMMC_RST              0x00000002
> +#define  F_SDH30_EMMC_HS200            0x01000000
> +
> +#define F_SDH30_CMD_DAT_DELAY          0x200
> +
> +#define F_SDH30_MIN_CLOCK              400000
> +
> +struct f_sdhost_priv {
> +       struct clk *clk_iface;
> +       struct clk *clk;
> +       u32 vendor_hs200;
> +       struct device *dev;
> +};
> +
> +void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
> +{
> +       struct f_sdhost_priv *priv = sdhci_priv(host);
> +       u32 ctrl = 0;
> +
> +       usleep_range(2500, 3000);
> +       ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
> +       ctrl |= F_SDH30_CRES_O_DN;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +       ctrl |= F_SDH30_MSEL_O_1_8;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +
> +       ctrl &= ~F_SDH30_CRES_O_DN;
> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
> +       usleep_range(2500, 3000);
> +
> +       if (priv->vendor_hs200) {
> +               dev_info(priv->dev, "%s: setting hs200\n", __func__);
> +               ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
> +               ctrl |= priv->vendor_hs200;
> +               sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
> +       }
> +
> +       ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
> +       ctrl |= F_SDH30_CMD_CHK_DIS;
> +       sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
> +}
> +
> +unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
> +{
> +       return F_SDH30_MIN_CLOCK;
> +}
> +
> +void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
> +{
> +       if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
> +               sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
> +
> +       sdhci_reset(host, mask);
> +}
> +
> +static const struct sdhci_ops sdhci_f_sdh30_ops = {
> +       .voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
> +       .get_min_clock = sdhci_f_sdh30_get_min_clock,
> +       .reset = sdhci_f_sdh30_reset,
> +       .set_clock = sdhci_set_clock,
> +       .set_bus_width = sdhci_set_bus_width,
> +       .set_uhs_signaling = sdhci_set_uhs_signaling,
> +};
> +
> +static int sdhci_f_sdh30_probe(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host;
> +       struct device *dev = &pdev->dev;
> +       int irq, ctrl = 0, ret = 0;
> +       struct f_sdhost_priv *priv;
> +       u32 reg = 0;
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0) {
> +               dev_err(dev, "%s: no irq specified\n", __func__);
> +               ret = irq;
> +               goto err;
> +       }
> +
> +       host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
> +                                               sizeof(struct f_sdhost_priv));
> +       if (IS_ERR(host)) {
> +               dev_err(dev, "%s: host allocate error\n", __func__);
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +       priv = sdhci_priv(host);
> +       priv->dev = dev;
> +
> +       host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
> +                      SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
> +       host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
> +                       SDHCI_QUIRK2_TUNING_WORK_AROUND;
> +
> +       ret = mmc_of_parse(host->mmc);
> +       if (ret)
> +               goto err_of_parse;
> +
> +       ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
> +       if (ret)
> +               goto err_of_parse;
> +
> +       platform_set_drvdata(pdev, host);
> +
> +       sdhci_get_of_property(pdev);
> +       host->hw_name = "f_sdh30";
> +       host->ops = &sdhci_f_sdh30_ops;
> +       host->irq = irq;
> +
> +       host->ioaddr = of_iomap(pdev->dev.of_node, 0);
> +       if (!host->ioaddr) {
> +               dev_err(dev, "%s: failed to remap registers\n", __func__);
> +               ret = -ENXIO;
> +               goto err_remap;
> +       }
> +
> +       priv->clk_iface = clk_get(&pdev->dev, "iface");
> +       if (!IS_ERR(priv->clk_iface)) {
> +               ret = clk_prepare_enable(priv->clk_iface);
> +               if (ret < 0) {
> +                       dev_err(dev, "Failed to enable iface clock: %d\n", ret);
> +                       goto err_clk1;
> +               }
> +       }
> +       priv->clk = clk_get(&pdev->dev, "core");
> +       if (!IS_ERR(priv->clk)) {
> +               ret = clk_prepare_enable(priv->clk);
> +               if (ret < 0) {
> +                       dev_err(dev, "Failed to enable core clock: %d\n", ret);
> +                       goto err_clk2;
> +               }
> +       }
> +
> +#ifdef CONFIG_PM_RUNTIME
> +       pm_runtime_set_active(&pdev->dev);
> +       pm_runtime_enable(&pdev->dev);
> +       ret = pm_runtime_get_sync(&pdev->dev);
> +       if (ret < 0)
> +               dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
> +#endif
> +
> +       ret = sdhci_add_host(host);
> +       if (ret) {
> +               dev_err(dev, "%s: host add error\n", __func__);
> +               goto err_add_host;
> +       }
> +
> +       /* init vendor specific regs */
> +       ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
> +       ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
> +               F_SDH30_AHB_INCR_4;
> +       ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
> +       sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
> +
> +       reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
> +       sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
> +       msleep(20);
> +       sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
> +
> +       reg = sdhci_readl(host, SDHCI_CAPABILITIES);
> +       if (reg & SDHCI_CAN_DO_8BIT)
> +               priv->vendor_hs200 = F_SDH30_EMMC_HS200;
> +       else
> +               priv->vendor_hs200 = 0;
> +
> +       return 0;
> +
> +err_add_host:
> +       clk_put(priv->clk);
> +err_clk2:
> +       clk_put(priv->clk_iface);
> +err_clk1:
> +       iounmap(host->ioaddr);
> +err_remap:
> +err_of_parse:
> +       sdhci_free_host(host);
> +err:
> +       return ret;
> +}
> +
> +static int sdhci_f_sdh30_remove(struct platform_device *pdev)
> +{
> +       struct sdhci_host *host = platform_get_drvdata(pdev);
> +       struct f_sdhost_priv *priv = sdhci_priv(host);
> +       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +       sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
> +                         0xffffffff);
> +       iounmap(host->ioaddr);
> +       release_mem_region(iomem->start, resource_size(iomem));
> +
> +       clk_disable_unprepare(priv->clk_iface);
> +       clk_disable_unprepare(priv->clk);
> +
> +       clk_put(priv->clk);
> +       clk_put(priv->clk_iface);
> +
> +       sdhci_free_host(host);
> +       platform_set_drvdata(pdev, NULL);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int sdhci_f_sdh30_suspend(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_suspend_host(host);
> +}
> +
> +static int sdhci_f_sdh30_resume(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_resume_host(host);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM_RUNTIME
> +static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_runtime_suspend_host(host);
> +}
> +
> +static int sdhci_f_sdh30_runtime_resume(struct device *dev)
> +{
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       return sdhci_runtime_resume_host(host);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM
> +static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
> +       SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
> +                          sdhci_f_sdh30_runtime_resume, NULL)
> +};
> +
> +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
> +
> +#else
> +#define SDHCI_F_SDH30_PMOPS NULL
> +#endif
> +
> +static const struct of_device_id f_sdh30_dt_ids[] = {
> +       { .compatible = "fujitsu,mb86s70-sdh30" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
> +
> +static struct platform_driver sdhci_f_sdh30_driver = {
> +       .driver = {
> +               .name = "f_sdh30",
> +               .of_match_table = f_sdh30_dt_ids,
> +#ifdef CONFIG_PM_SLEEP
> +               .pm     = SDHCI_F_SDH30_PMOPS,
> +#endif
> +       },
> +       .probe  = sdhci_f_sdh30_probe,
> +       .remove = sdhci_f_sdh30_remove,
> +};
> +
> +module_platform_driver(sdhci_f_sdh30_driver);
> +
> +MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
> +MODULE_ALIAS("platform:f_sdh30");
> --
> 1.9.0
>

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

* Re: [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
  2014-11-20 15:22     ` Rob Herring
@ 2014-11-20 16:59       ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 16:59 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, linux-mmc, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, chris,
	Ulf Hansson, Andy Green, Linaro Patches, Jaswinder Singh,
	Vincent Yang, Tetsuya Takinishi

2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> This patch adds new host controller driver for
>> Fujitsu SDHCI controller f_sdh30.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>> ---
>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>  drivers/mmc/host/Kconfig                           |   9 +
>>  drivers/mmc/host/Makefile                          |   1 +
>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>  4 files changed, 364 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>> new file mode 100644
>> index 0000000..a1e0b64
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>> @@ -0,0 +1,35 @@
>> +* Fujitsu SDHCI controller
>> +
>> +This file documents differences between the core properties in mmc.txt
>> +and the properties used by the sdhci_f_sdh30 driver.
>> +
>> +Required properties:
>> +- compatible: "fujitsu,mb86s70-sdh30"
>
> It would be nice to have sdhci in the name to indicate it is an SDHCI
> controller.

Yes, we will update it to "fujitsu,sdhci-f-sdh30"
Thanks for your review!

- Vincent Yang

>
>> +- voltage-ranges : This is a list of pairs. In each pair, two cells
>> +  are required. First cell specifies minimum slot voltage (mV), second
>> +  cell specifies maximum slot voltage (mV). In case of supported voltage
>> +  range is discontinuous, several ranges could be specified as a list.
>> +
>> +Optional properties:
>> +- vqmmc-supply: phandle to the regulator device tree node, mentioned
>> +  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
>> +- clocks: Must contain an entry for each entry in clock-names. It is a
>> +  list of phandles and clock-specifier pairs.
>> +  See ../clocks/clock-bindings.txt for details.
>> +- clock-names: Should contain the following two entries:
>> +       "iface" - clock used for sdhci interface
>> +       "core"  - core clock for sdhci controller
>> +
>> +Example:
>> +
>> +       sdhci1: sdio@36600000 {
>> +               compatible = "fujitsu,mb86s70-sdh30";
>> +               reg = <0 0x36600000 0x1000>;
>> +               interrupts = <0 172 0x4>,
>> +                            <0 173 0x4>;
>> +               voltage-ranges = <1800 1800>, <3300 3300>;
>> +               bus-width = <4>;
>> +               vqmmc-supply = <&vccq_sdhci1>;
>> +               clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
>> +               clock-names = "iface", "core";
>> +       };
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 1386065..cbe5e3c 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
>>           This selects the BCM2835 SD/MMC controller. If you have a BCM2835
>>           platform with SD or MMC devices, say Y or M here.
>>
>> +config MMC_SDHCI_F_SDH30
>> +       tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
>> +       depends on ARCH_MB86S7X
>> +       depends on MMC_SDHCI_PLTFM
>> +       depends on OF
>> +       help
>> +         This selects the Secure Digital Host Controller Interface (SDHCI)
>> +         Needed by some Fujitsu SoC for MMC / SD / SDIO support.
>> +         If you have a controller with this interface, say Y or M here.
>>           If unsure, say N.
>>
>>  config MMC_MOXART
>> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
>> index b09ecfb..63efc38 100644
>> --- a/drivers/mmc/host/Makefile
>> +++ b/drivers/mmc/host/Makefile
>> @@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
>>  obj-$(CONFIG_MMC_SDHCI_PXAV2)  += sdhci-pxav2.o
>>  obj-$(CONFIG_MMC_SDHCI_S3C)    += sdhci-s3c.o
>>  obj-$(CONFIG_MMC_SDHCI_SIRF)           += sdhci-sirf.o
>> +obj-$(CONFIG_MMC_SDHCI_F_SDH30)        += sdhci_f_sdh30.o
>>  obj-$(CONFIG_MMC_SDHCI_SPEAR)  += sdhci-spear.o
>>  obj-$(CONFIG_MMC_WBSD)         += wbsd.o
>>  obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
>> diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
>> new file mode 100644
>> index 0000000..f6eba5a
>> --- /dev/null
>> +++ b/drivers/mmc/host/sdhci_f_sdh30.c
>> @@ -0,0 +1,319 @@
>> +/*
>> + * linux/drivers/mmc/host/sdhci_f_sdh30.c
>> + *
>> + * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
>> + *              Vincent Yang <vincent.yang@tw.fujitsu.com>
>> + * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/delay.h>
>> +#include <linux/module.h>
>> +#include <linux/mmc/sd.h>
>> +#include <linux/mmc/host.h>
>> +#include <linux/mmc/card.h>
>> +#include <linux/gpio.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/of_address.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/suspend.h>
>> +
>> +#include "sdhci.h"
>> +#include "sdhci-pltfm.h"
>> +
>> +/* F_SDH30 extended Controller registers */
>> +#define F_SDH30_AHB_CONFIG             0x100
>> +#define  F_SDH30_AHB_BIGED             0x00000040
>> +#define  F_SDH30_BUSLOCK_DMA           0x00000020
>> +#define  F_SDH30_BUSLOCK_EN            0x00000010
>> +#define  F_SDH30_SIN                   0x00000008
>> +#define  F_SDH30_AHB_INCR_16           0x00000004
>> +#define  F_SDH30_AHB_INCR_8            0x00000002
>> +#define  F_SDH30_AHB_INCR_4            0x00000001
>> +
>> +#define F_SDH30_TUNING_SETTING         0x108
>> +#define  F_SDH30_CMD_CHK_DIS           0x00010000
>> +
>> +#define F_SDH30_IO_CONTROL2            0x114
>> +#define  F_SDH30_CRES_O_DN             0x00080000
>> +#define  F_SDH30_MSEL_O_1_8            0x00040000
>> +
>> +#define F_SDH30_ESD_CONTROL            0x124
>> +#define  F_SDH30_EMMC_RST              0x00000002
>> +#define  F_SDH30_EMMC_HS200            0x01000000
>> +
>> +#define F_SDH30_CMD_DAT_DELAY          0x200
>> +
>> +#define F_SDH30_MIN_CLOCK              400000
>> +
>> +struct f_sdhost_priv {
>> +       struct clk *clk_iface;
>> +       struct clk *clk;
>> +       u32 vendor_hs200;
>> +       struct device *dev;
>> +};
>> +
>> +void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
>> +{
>> +       struct f_sdhost_priv *priv = sdhci_priv(host);
>> +       u32 ctrl = 0;
>> +
>> +       usleep_range(2500, 3000);
>> +       ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
>> +       ctrl |= F_SDH30_CRES_O_DN;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +       ctrl |= F_SDH30_MSEL_O_1_8;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +
>> +       ctrl &= ~F_SDH30_CRES_O_DN;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +       usleep_range(2500, 3000);
>> +
>> +       if (priv->vendor_hs200) {
>> +               dev_info(priv->dev, "%s: setting hs200\n", __func__);
>> +               ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
>> +               ctrl |= priv->vendor_hs200;
>> +               sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
>> +       }
>> +
>> +       ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
>> +       ctrl |= F_SDH30_CMD_CHK_DIS;
>> +       sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
>> +}
>> +
>> +unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
>> +{
>> +       return F_SDH30_MIN_CLOCK;
>> +}
>> +
>> +void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
>> +{
>> +       if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
>> +               sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
>> +
>> +       sdhci_reset(host, mask);
>> +}
>> +
>> +static const struct sdhci_ops sdhci_f_sdh30_ops = {
>> +       .voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
>> +       .get_min_clock = sdhci_f_sdh30_get_min_clock,
>> +       .reset = sdhci_f_sdh30_reset,
>> +       .set_clock = sdhci_set_clock,
>> +       .set_bus_width = sdhci_set_bus_width,
>> +       .set_uhs_signaling = sdhci_set_uhs_signaling,
>> +};
>> +
>> +static int sdhci_f_sdh30_probe(struct platform_device *pdev)
>> +{
>> +       struct sdhci_host *host;
>> +       struct device *dev = &pdev->dev;
>> +       int irq, ctrl = 0, ret = 0;
>> +       struct f_sdhost_priv *priv;
>> +       u32 reg = 0;
>> +
>> +       irq = platform_get_irq(pdev, 0);
>> +       if (irq < 0) {
>> +               dev_err(dev, "%s: no irq specified\n", __func__);
>> +               ret = irq;
>> +               goto err;
>> +       }
>> +
>> +       host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
>> +                                               sizeof(struct f_sdhost_priv));
>> +       if (IS_ERR(host)) {
>> +               dev_err(dev, "%s: host allocate error\n", __func__);
>> +               ret = -ENOMEM;
>> +               goto err;
>> +       }
>> +       priv = sdhci_priv(host);
>> +       priv->dev = dev;
>> +
>> +       host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
>> +                      SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
>> +       host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
>> +                       SDHCI_QUIRK2_TUNING_WORK_AROUND;
>> +
>> +       ret = mmc_of_parse(host->mmc);
>> +       if (ret)
>> +               goto err_of_parse;
>> +
>> +       ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
>> +       if (ret)
>> +               goto err_of_parse;
>> +
>> +       platform_set_drvdata(pdev, host);
>> +
>> +       sdhci_get_of_property(pdev);
>> +       host->hw_name = "f_sdh30";
>> +       host->ops = &sdhci_f_sdh30_ops;
>> +       host->irq = irq;
>> +
>> +       host->ioaddr = of_iomap(pdev->dev.of_node, 0);
>> +       if (!host->ioaddr) {
>> +               dev_err(dev, "%s: failed to remap registers\n", __func__);
>> +               ret = -ENXIO;
>> +               goto err_remap;
>> +       }
>> +
>> +       priv->clk_iface = clk_get(&pdev->dev, "iface");
>> +       if (!IS_ERR(priv->clk_iface)) {
>> +               ret = clk_prepare_enable(priv->clk_iface);
>> +               if (ret < 0) {
>> +                       dev_err(dev, "Failed to enable iface clock: %d\n", ret);
>> +                       goto err_clk1;
>> +               }
>> +       }
>> +       priv->clk = clk_get(&pdev->dev, "core");
>> +       if (!IS_ERR(priv->clk)) {
>> +               ret = clk_prepare_enable(priv->clk);
>> +               if (ret < 0) {
>> +                       dev_err(dev, "Failed to enable core clock: %d\n", ret);
>> +                       goto err_clk2;
>> +               }
>> +       }
>> +
>> +#ifdef CONFIG_PM_RUNTIME
>> +       pm_runtime_set_active(&pdev->dev);
>> +       pm_runtime_enable(&pdev->dev);
>> +       ret = pm_runtime_get_sync(&pdev->dev);
>> +       if (ret < 0)
>> +               dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
>> +#endif
>> +
>> +       ret = sdhci_add_host(host);
>> +       if (ret) {
>> +               dev_err(dev, "%s: host add error\n", __func__);
>> +               goto err_add_host;
>> +       }
>> +
>> +       /* init vendor specific regs */
>> +       ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
>> +       ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
>> +               F_SDH30_AHB_INCR_4;
>> +       ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
>> +       sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
>> +
>> +       reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
>> +       sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
>> +       msleep(20);
>> +       sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
>> +
>> +       reg = sdhci_readl(host, SDHCI_CAPABILITIES);
>> +       if (reg & SDHCI_CAN_DO_8BIT)
>> +               priv->vendor_hs200 = F_SDH30_EMMC_HS200;
>> +       else
>> +               priv->vendor_hs200 = 0;
>> +
>> +       return 0;
>> +
>> +err_add_host:
>> +       clk_put(priv->clk);
>> +err_clk2:
>> +       clk_put(priv->clk_iface);
>> +err_clk1:
>> +       iounmap(host->ioaddr);
>> +err_remap:
>> +err_of_parse:
>> +       sdhci_free_host(host);
>> +err:
>> +       return ret;
>> +}
>> +
>> +static int sdhci_f_sdh30_remove(struct platform_device *pdev)
>> +{
>> +       struct sdhci_host *host = platform_get_drvdata(pdev);
>> +       struct f_sdhost_priv *priv = sdhci_priv(host);
>> +       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +
>> +       sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
>> +                         0xffffffff);
>> +       iounmap(host->ioaddr);
>> +       release_mem_region(iomem->start, resource_size(iomem));
>> +
>> +       clk_disable_unprepare(priv->clk_iface);
>> +       clk_disable_unprepare(priv->clk);
>> +
>> +       clk_put(priv->clk);
>> +       clk_put(priv->clk_iface);
>> +
>> +       sdhci_free_host(host);
>> +       platform_set_drvdata(pdev, NULL);
>> +
>> +       return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int sdhci_f_sdh30_suspend(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_suspend_host(host);
>> +}
>> +
>> +static int sdhci_f_sdh30_resume(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_resume_host(host);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM_RUNTIME
>> +static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_runtime_suspend_host(host);
>> +}
>> +
>> +static int sdhci_f_sdh30_runtime_resume(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_runtime_resume_host(host);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM
>> +static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
>> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
>> +       SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
>> +                          sdhci_f_sdh30_runtime_resume, NULL)
>> +};
>> +
>> +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
>> +
>> +#else
>> +#define SDHCI_F_SDH30_PMOPS NULL
>> +#endif
>> +
>> +static const struct of_device_id f_sdh30_dt_ids[] = {
>> +       { .compatible = "fujitsu,mb86s70-sdh30" },
>> +       { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
>> +
>> +static struct platform_driver sdhci_f_sdh30_driver = {
>> +       .driver = {
>> +               .name = "f_sdh30",
>> +               .of_match_table = f_sdh30_dt_ids,
>> +#ifdef CONFIG_PM_SLEEP
>> +               .pm     = SDHCI_F_SDH30_PMOPS,
>> +#endif
>> +       },
>> +       .probe  = sdhci_f_sdh30_probe,
>> +       .remove = sdhci_f_sdh30_remove,
>> +};
>> +
>> +module_platform_driver(sdhci_f_sdh30_driver);
>> +
>> +MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
>> +MODULE_ALIAS("platform:f_sdh30");
>> --
>> 1.9.0
>>

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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
@ 2014-11-20 16:59       ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-20 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> This patch adds new host controller driver for
>> Fujitsu SDHCI controller f_sdh30.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>> ---
>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>  drivers/mmc/host/Kconfig                           |   9 +
>>  drivers/mmc/host/Makefile                          |   1 +
>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>  4 files changed, 364 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>> new file mode 100644
>> index 0000000..a1e0b64
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>> @@ -0,0 +1,35 @@
>> +* Fujitsu SDHCI controller
>> +
>> +This file documents differences between the core properties in mmc.txt
>> +and the properties used by the sdhci_f_sdh30 driver.
>> +
>> +Required properties:
>> +- compatible: "fujitsu,mb86s70-sdh30"
>
> It would be nice to have sdhci in the name to indicate it is an SDHCI
> controller.

Yes, we will update it to "fujitsu,sdhci-f-sdh30"
Thanks for your review!

- Vincent Yang

>
>> +- voltage-ranges : This is a list of pairs. In each pair, two cells
>> +  are required. First cell specifies minimum slot voltage (mV), second
>> +  cell specifies maximum slot voltage (mV). In case of supported voltage
>> +  range is discontinuous, several ranges could be specified as a list.
>> +
>> +Optional properties:
>> +- vqmmc-supply: phandle to the regulator device tree node, mentioned
>> +  as the VCCQ/VDD_IO supply in the eMMC/SD specs.
>> +- clocks: Must contain an entry for each entry in clock-names. It is a
>> +  list of phandles and clock-specifier pairs.
>> +  See ../clocks/clock-bindings.txt for details.
>> +- clock-names: Should contain the following two entries:
>> +       "iface" - clock used for sdhci interface
>> +       "core"  - core clock for sdhci controller
>> +
>> +Example:
>> +
>> +       sdhci1: sdio at 36600000 {
>> +               compatible = "fujitsu,mb86s70-sdh30";
>> +               reg = <0 0x36600000 0x1000>;
>> +               interrupts = <0 172 0x4>,
>> +                            <0 173 0x4>;
>> +               voltage-ranges = <1800 1800>, <3300 3300>;
>> +               bus-width = <4>;
>> +               vqmmc-supply = <&vccq_sdhci1>;
>> +               clocks = <&clk_hdmi_2_0>, <&clk_hdmi_3_0>;
>> +               clock-names = "iface", "core";
>> +       };
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 1386065..cbe5e3c 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -290,6 +290,15 @@ config MMC_SDHCI_BCM2835
>>           This selects the BCM2835 SD/MMC controller. If you have a BCM2835
>>           platform with SD or MMC devices, say Y or M here.
>>
>> +config MMC_SDHCI_F_SDH30
>> +       tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
>> +       depends on ARCH_MB86S7X
>> +       depends on MMC_SDHCI_PLTFM
>> +       depends on OF
>> +       help
>> +         This selects the Secure Digital Host Controller Interface (SDHCI)
>> +         Needed by some Fujitsu SoC for MMC / SD / SDIO support.
>> +         If you have a controller with this interface, say Y or M here.
>>           If unsure, say N.
>>
>>  config MMC_MOXART
>> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
>> index b09ecfb..63efc38 100644
>> --- a/drivers/mmc/host/Makefile
>> +++ b/drivers/mmc/host/Makefile
>> @@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
>>  obj-$(CONFIG_MMC_SDHCI_PXAV2)  += sdhci-pxav2.o
>>  obj-$(CONFIG_MMC_SDHCI_S3C)    += sdhci-s3c.o
>>  obj-$(CONFIG_MMC_SDHCI_SIRF)           += sdhci-sirf.o
>> +obj-$(CONFIG_MMC_SDHCI_F_SDH30)        += sdhci_f_sdh30.o
>>  obj-$(CONFIG_MMC_SDHCI_SPEAR)  += sdhci-spear.o
>>  obj-$(CONFIG_MMC_WBSD)         += wbsd.o
>>  obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
>> diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
>> new file mode 100644
>> index 0000000..f6eba5a
>> --- /dev/null
>> +++ b/drivers/mmc/host/sdhci_f_sdh30.c
>> @@ -0,0 +1,319 @@
>> +/*
>> + * linux/drivers/mmc/host/sdhci_f_sdh30.c
>> + *
>> + * Copyright (C) 2013 - 2014 Fujitsu Semiconductor, Ltd
>> + *              Vincent Yang <vincent.yang@tw.fujitsu.com>
>> + * Copyright (C) 2014 Linaro Ltd  Andy Green <andy.green@linaro.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, version 2 of the License.
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/delay.h>
>> +#include <linux/module.h>
>> +#include <linux/mmc/sd.h>
>> +#include <linux/mmc/host.h>
>> +#include <linux/mmc/card.h>
>> +#include <linux/gpio.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/of_address.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/suspend.h>
>> +
>> +#include "sdhci.h"
>> +#include "sdhci-pltfm.h"
>> +
>> +/* F_SDH30 extended Controller registers */
>> +#define F_SDH30_AHB_CONFIG             0x100
>> +#define  F_SDH30_AHB_BIGED             0x00000040
>> +#define  F_SDH30_BUSLOCK_DMA           0x00000020
>> +#define  F_SDH30_BUSLOCK_EN            0x00000010
>> +#define  F_SDH30_SIN                   0x00000008
>> +#define  F_SDH30_AHB_INCR_16           0x00000004
>> +#define  F_SDH30_AHB_INCR_8            0x00000002
>> +#define  F_SDH30_AHB_INCR_4            0x00000001
>> +
>> +#define F_SDH30_TUNING_SETTING         0x108
>> +#define  F_SDH30_CMD_CHK_DIS           0x00010000
>> +
>> +#define F_SDH30_IO_CONTROL2            0x114
>> +#define  F_SDH30_CRES_O_DN             0x00080000
>> +#define  F_SDH30_MSEL_O_1_8            0x00040000
>> +
>> +#define F_SDH30_ESD_CONTROL            0x124
>> +#define  F_SDH30_EMMC_RST              0x00000002
>> +#define  F_SDH30_EMMC_HS200            0x01000000
>> +
>> +#define F_SDH30_CMD_DAT_DELAY          0x200
>> +
>> +#define F_SDH30_MIN_CLOCK              400000
>> +
>> +struct f_sdhost_priv {
>> +       struct clk *clk_iface;
>> +       struct clk *clk;
>> +       u32 vendor_hs200;
>> +       struct device *dev;
>> +};
>> +
>> +void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
>> +{
>> +       struct f_sdhost_priv *priv = sdhci_priv(host);
>> +       u32 ctrl = 0;
>> +
>> +       usleep_range(2500, 3000);
>> +       ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2);
>> +       ctrl |= F_SDH30_CRES_O_DN;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +       ctrl |= F_SDH30_MSEL_O_1_8;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +
>> +       ctrl &= ~F_SDH30_CRES_O_DN;
>> +       sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2);
>> +       usleep_range(2500, 3000);
>> +
>> +       if (priv->vendor_hs200) {
>> +               dev_info(priv->dev, "%s: setting hs200\n", __func__);
>> +               ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL);
>> +               ctrl |= priv->vendor_hs200;
>> +               sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL);
>> +       }
>> +
>> +       ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING);
>> +       ctrl |= F_SDH30_CMD_CHK_DIS;
>> +       sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING);
>> +}
>> +
>> +unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
>> +{
>> +       return F_SDH30_MIN_CLOCK;
>> +}
>> +
>> +void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
>> +{
>> +       if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
>> +               sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL);
>> +
>> +       sdhci_reset(host, mask);
>> +}
>> +
>> +static const struct sdhci_ops sdhci_f_sdh30_ops = {
>> +       .voltage_switch = sdhci_f_sdh30_soft_voltage_switch,
>> +       .get_min_clock = sdhci_f_sdh30_get_min_clock,
>> +       .reset = sdhci_f_sdh30_reset,
>> +       .set_clock = sdhci_set_clock,
>> +       .set_bus_width = sdhci_set_bus_width,
>> +       .set_uhs_signaling = sdhci_set_uhs_signaling,
>> +};
>> +
>> +static int sdhci_f_sdh30_probe(struct platform_device *pdev)
>> +{
>> +       struct sdhci_host *host;
>> +       struct device *dev = &pdev->dev;
>> +       int irq, ctrl = 0, ret = 0;
>> +       struct f_sdhost_priv *priv;
>> +       u32 reg = 0;
>> +
>> +       irq = platform_get_irq(pdev, 0);
>> +       if (irq < 0) {
>> +               dev_err(dev, "%s: no irq specified\n", __func__);
>> +               ret = irq;
>> +               goto err;
>> +       }
>> +
>> +       host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) +
>> +                                               sizeof(struct f_sdhost_priv));
>> +       if (IS_ERR(host)) {
>> +               dev_err(dev, "%s: host allocate error\n", __func__);
>> +               ret = -ENOMEM;
>> +               goto err;
>> +       }
>> +       priv = sdhci_priv(host);
>> +       priv->dev = dev;
>> +
>> +       host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
>> +                      SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
>> +       host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
>> +                       SDHCI_QUIRK2_TUNING_WORK_AROUND;
>> +
>> +       ret = mmc_of_parse(host->mmc);
>> +       if (ret)
>> +               goto err_of_parse;
>> +
>> +       ret = mmc_of_parse_voltage(pdev->dev.of_node, &host->ocr_mask);
>> +       if (ret)
>> +               goto err_of_parse;
>> +
>> +       platform_set_drvdata(pdev, host);
>> +
>> +       sdhci_get_of_property(pdev);
>> +       host->hw_name = "f_sdh30";
>> +       host->ops = &sdhci_f_sdh30_ops;
>> +       host->irq = irq;
>> +
>> +       host->ioaddr = of_iomap(pdev->dev.of_node, 0);
>> +       if (!host->ioaddr) {
>> +               dev_err(dev, "%s: failed to remap registers\n", __func__);
>> +               ret = -ENXIO;
>> +               goto err_remap;
>> +       }
>> +
>> +       priv->clk_iface = clk_get(&pdev->dev, "iface");
>> +       if (!IS_ERR(priv->clk_iface)) {
>> +               ret = clk_prepare_enable(priv->clk_iface);
>> +               if (ret < 0) {
>> +                       dev_err(dev, "Failed to enable iface clock: %d\n", ret);
>> +                       goto err_clk1;
>> +               }
>> +       }
>> +       priv->clk = clk_get(&pdev->dev, "core");
>> +       if (!IS_ERR(priv->clk)) {
>> +               ret = clk_prepare_enable(priv->clk);
>> +               if (ret < 0) {
>> +                       dev_err(dev, "Failed to enable core clock: %d\n", ret);
>> +                       goto err_clk2;
>> +               }
>> +       }
>> +
>> +#ifdef CONFIG_PM_RUNTIME
>> +       pm_runtime_set_active(&pdev->dev);
>> +       pm_runtime_enable(&pdev->dev);
>> +       ret = pm_runtime_get_sync(&pdev->dev);
>> +       if (ret < 0)
>> +               dev_err(dev, "Failed to pm_runtime_get_sync: %d\n", ret);
>> +#endif
>> +
>> +       ret = sdhci_add_host(host);
>> +       if (ret) {
>> +               dev_err(dev, "%s: host add error\n", __func__);
>> +               goto err_add_host;
>> +       }
>> +
>> +       /* init vendor specific regs */
>> +       ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
>> +       ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
>> +               F_SDH30_AHB_INCR_4;
>> +       ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN);
>> +       sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG);
>> +
>> +       reg = sdhci_readl(host, F_SDH30_ESD_CONTROL);
>> +       sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
>> +       msleep(20);
>> +       sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL);
>> +
>> +       reg = sdhci_readl(host, SDHCI_CAPABILITIES);
>> +       if (reg & SDHCI_CAN_DO_8BIT)
>> +               priv->vendor_hs200 = F_SDH30_EMMC_HS200;
>> +       else
>> +               priv->vendor_hs200 = 0;
>> +
>> +       return 0;
>> +
>> +err_add_host:
>> +       clk_put(priv->clk);
>> +err_clk2:
>> +       clk_put(priv->clk_iface);
>> +err_clk1:
>> +       iounmap(host->ioaddr);
>> +err_remap:
>> +err_of_parse:
>> +       sdhci_free_host(host);
>> +err:
>> +       return ret;
>> +}
>> +
>> +static int sdhci_f_sdh30_remove(struct platform_device *pdev)
>> +{
>> +       struct sdhci_host *host = platform_get_drvdata(pdev);
>> +       struct f_sdhost_priv *priv = sdhci_priv(host);
>> +       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +
>> +       sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
>> +                         0xffffffff);
>> +       iounmap(host->ioaddr);
>> +       release_mem_region(iomem->start, resource_size(iomem));
>> +
>> +       clk_disable_unprepare(priv->clk_iface);
>> +       clk_disable_unprepare(priv->clk);
>> +
>> +       clk_put(priv->clk);
>> +       clk_put(priv->clk_iface);
>> +
>> +       sdhci_free_host(host);
>> +       platform_set_drvdata(pdev, NULL);
>> +
>> +       return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int sdhci_f_sdh30_suspend(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_suspend_host(host);
>> +}
>> +
>> +static int sdhci_f_sdh30_resume(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_resume_host(host);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM_RUNTIME
>> +static int sdhci_f_sdh30_runtime_suspend(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_runtime_suspend_host(host);
>> +}
>> +
>> +static int sdhci_f_sdh30_runtime_resume(struct device *dev)
>> +{
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       return sdhci_runtime_resume_host(host);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM
>> +static const struct dev_pm_ops sdhci_f_sdh30_pmops = {
>> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_f_sdh30_suspend, sdhci_f_sdh30_resume)
>> +       SET_RUNTIME_PM_OPS(sdhci_f_sdh30_runtime_suspend,
>> +                          sdhci_f_sdh30_runtime_resume, NULL)
>> +};
>> +
>> +#define SDHCI_F_SDH30_PMOPS (&sdhci_f_sdh30_pmops)
>> +
>> +#else
>> +#define SDHCI_F_SDH30_PMOPS NULL
>> +#endif
>> +
>> +static const struct of_device_id f_sdh30_dt_ids[] = {
>> +       { .compatible = "fujitsu,mb86s70-sdh30" },
>> +       { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
>> +
>> +static struct platform_driver sdhci_f_sdh30_driver = {
>> +       .driver = {
>> +               .name = "f_sdh30",
>> +               .of_match_table = f_sdh30_dt_ids,
>> +#ifdef CONFIG_PM_SLEEP
>> +               .pm     = SDHCI_F_SDH30_PMOPS,
>> +#endif
>> +       },
>> +       .probe  = sdhci_f_sdh30_probe,
>> +       .remove = sdhci_f_sdh30_remove,
>> +};
>> +
>> +module_platform_driver(sdhci_f_sdh30_driver);
>> +
>> +MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD.");
>> +MODULE_ALIAS("platform:f_sdh30");
>> --
>> 1.9.0
>>

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

* Re: [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
  2014-11-20 16:59       ` Vincent Yang
@ 2014-11-20 18:18         ` Rob Herring
  -1 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 18:18 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree, linux-mmc, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, chris,
	Ulf Hansson, Andy Green, Linaro Patches, Jaswinder Singh,
	Vincent Yang, Tetsuya Takinishi

On Thu, Nov 20, 2014 at 10:59 AM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> 2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
>> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
>> <vincent.yang.fujitsu@gmail.com> wrote:
>>> This patch adds new host controller driver for
>>> Fujitsu SDHCI controller f_sdh30.
>>>
>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>>> ---
>>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>>  drivers/mmc/host/Kconfig                           |   9 +
>>>  drivers/mmc/host/Makefile                          |   1 +
>>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>>  4 files changed, 364 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>> new file mode 100644
>>> index 0000000..a1e0b64
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>> @@ -0,0 +1,35 @@
>>> +* Fujitsu SDHCI controller
>>> +
>>> +This file documents differences between the core properties in mmc.txt
>>> +and the properties used by the sdhci_f_sdh30 driver.
>>> +
>>> +Required properties:
>>> +- compatible: "fujitsu,mb86s70-sdh30"
>>
>> It would be nice to have sdhci in the name to indicate it is an SDHCI
>> controller.
>
> Yes, we will update it to "fujitsu,sdhci-f-sdh30"
> Thanks for your review!

Not really what I had in mind as you are then dropping the chip name.
Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP
version? If the former, I think I'd drop it as IIRC that is available
in a register.

Rob

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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
@ 2014-11-20 18:18         ` Rob Herring
  0 siblings, 0 replies; 97+ messages in thread
From: Rob Herring @ 2014-11-20 18:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 20, 2014 at 10:59 AM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> 2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
>> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
>> <vincent.yang.fujitsu@gmail.com> wrote:
>>> This patch adds new host controller driver for
>>> Fujitsu SDHCI controller f_sdh30.
>>>
>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>>> ---
>>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>>  drivers/mmc/host/Kconfig                           |   9 +
>>>  drivers/mmc/host/Makefile                          |   1 +
>>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>>  4 files changed, 364 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>> new file mode 100644
>>> index 0000000..a1e0b64
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>> @@ -0,0 +1,35 @@
>>> +* Fujitsu SDHCI controller
>>> +
>>> +This file documents differences between the core properties in mmc.txt
>>> +and the properties used by the sdhci_f_sdh30 driver.
>>> +
>>> +Required properties:
>>> +- compatible: "fujitsu,mb86s70-sdh30"
>>
>> It would be nice to have sdhci in the name to indicate it is an SDHCI
>> controller.
>
> Yes, we will update it to "fujitsu,sdhci-f-sdh30"
> Thanks for your review!

Not really what I had in mind as you are then dropping the chip name.
Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP
version? If the former, I think I'd drop it as IIRC that is available
in a register.

Rob

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

* Re: [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
  2014-11-20 18:18         ` Rob Herring
@ 2014-11-21  1:18           ` Vincent Yang
  -1 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-21  1:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, linux-mmc, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, chris,
	Ulf Hansson, Andy Green, Linaro Patches, Jaswinder Singh,
	Vincent Yang, Tetsuya Takinishi

2014-11-21 2:18 GMT+08:00 Rob Herring <robherring2@gmail.com>:
> On Thu, Nov 20, 2014 at 10:59 AM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> 2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
>>> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
>>> <vincent.yang.fujitsu@gmail.com> wrote:
>>>> This patch adds new host controller driver for
>>>> Fujitsu SDHCI controller f_sdh30.
>>>>
>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>>>> ---
>>>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>>>  drivers/mmc/host/Kconfig                           |   9 +
>>>>  drivers/mmc/host/Makefile                          |   1 +
>>>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>>>  4 files changed, 364 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>> new file mode 100644
>>>> index 0000000..a1e0b64
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>> @@ -0,0 +1,35 @@
>>>> +* Fujitsu SDHCI controller
>>>> +
>>>> +This file documents differences between the core properties in mmc.txt
>>>> +and the properties used by the sdhci_f_sdh30 driver.
>>>> +
>>>> +Required properties:
>>>> +- compatible: "fujitsu,mb86s70-sdh30"
>>>
>>> It would be nice to have sdhci in the name to indicate it is an SDHCI
>>> controller.
>>
>> Yes, we will update it to "fujitsu,sdhci-f-sdh30"
>> Thanks for your review!
>
> Not really what I had in mind as you are then dropping the chip name.
> Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP
> version? If the former, I think I'd drop it as IIRC that is available
> in a register.

We will update it to "fujitsu,mb86s70-sdhci-3.0" as you suggest
because 3.0 is IP version
Thanks for your review!

Vincent

>
> Rob

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

* [PATCH 6/9] mmc: sdhci: host: add new f_sdh30
@ 2014-11-21  1:18           ` Vincent Yang
  0 siblings, 0 replies; 97+ messages in thread
From: Vincent Yang @ 2014-11-21  1:18 UTC (permalink / raw)
  To: linux-arm-kernel

2014-11-21 2:18 GMT+08:00 Rob Herring <robherring2@gmail.com>:
> On Thu, Nov 20, 2014 at 10:59 AM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> 2014-11-20 23:22 GMT+08:00 Rob Herring <robherring2@gmail.com>:
>>> On Thu, Nov 20, 2014 at 6:38 AM, Vincent Yang
>>> <vincent.yang.fujitsu@gmail.com> wrote:
>>>> This patch adds new host controller driver for
>>>> Fujitsu SDHCI controller f_sdh30.
>>>>
>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>> Signed-off-by: Tetsuya Takinishi <t.takinishi@jp.fujitsu.com>
>>>> ---
>>>>  .../devicetree/bindings/mmc/sdhci-fujitsu.txt      |  35 +++
>>>>  drivers/mmc/host/Kconfig                           |   9 +
>>>>  drivers/mmc/host/Makefile                          |   1 +
>>>>  drivers/mmc/host/sdhci_f_sdh30.c                   | 319 +++++++++++++++++++++
>>>>  4 files changed, 364 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>>  create mode 100644 drivers/mmc/host/sdhci_f_sdh30.c
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>> new file mode 100644
>>>> index 0000000..a1e0b64
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt
>>>> @@ -0,0 +1,35 @@
>>>> +* Fujitsu SDHCI controller
>>>> +
>>>> +This file documents differences between the core properties in mmc.txt
>>>> +and the properties used by the sdhci_f_sdh30 driver.
>>>> +
>>>> +Required properties:
>>>> +- compatible: "fujitsu,mb86s70-sdh30"
>>>
>>> It would be nice to have sdhci in the name to indicate it is an SDHCI
>>> controller.
>>
>> Yes, we will update it to "fujitsu,sdhci-f-sdh30"
>> Thanks for your review!
>
> Not really what I had in mind as you are then dropping the chip name.
> Perhaps "fujitsu,mb86s70-sdhci-3.0". Is 3.0 the SD spec version or IP
> version? If the former, I think I'd drop it as IIRC that is available
> in a register.

We will update it to "fujitsu,mb86s70-sdhci-3.0" as you suggest
because 3.0 is IP version
Thanks for your review!

Vincent

>
> Rob

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-20 12:35 ` [PATCH 3/9] ARM: MB86S7X: Add MCPM support Vincent Yang
@ 2014-11-21 13:02   ` Arnd Bergmann
  2014-11-21 13:24     ` Jassi Brar
  2014-11-25 11:48   ` Sudeep Holla
  2014-11-25 17:42   ` Nicolas Pitre
  2 siblings, 1 reply; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 20 November 2014 20:35:20 Vincent Yang wrote:
> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> CPU/CLUSTER power up/down done by SCB over mailbox.
> 
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>  arch/arm/mach-mb86s7x/Makefile |   2 +-
>  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>  3 files changed, 388 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>  create mode 100644 arch/arm/mach-mb86s7x/smc.S
> 
> diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
> index 97640b6..b0fa34b 100644
> --- a/arch/arm/mach-mb86s7x/Makefile
> +++ b/arch/arm/mach-mb86s7x/Makefile
> @@ -1 +1 @@
> -obj-$(CONFIG_ARCH_MB86S7X)	+= board.o
> +obj-$(CONFIG_ARCH_MB86S7X)	+= board.o mcpm.o smc.o

The two files are using ARMv7-only instructions in inline assembly,
which means that you will get a compile error for a combined arvm6+armv7
kernel. Please add the appropriate 'CFLAGS_mcpm.o += -march=armv7-a'
statements in the Makefile for each file with this problem.

> +
> +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
> +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
> +extern void __iomem *mb86s7x_shm_base;

Out of principle, you should never put an 'extern' declaration into .c
file. Better put this into a header file that is shared between all files
accessing the variable. In this particular case, I think it would be
better to just move the mb86s7x_set_wficolor() implementation into
drivers/soc/mb86s7x/scb_mhu.c and add an exported symbol for that, so
you can keep the variable local to the mhu implementation.

> +#define mb86s70evb_exit_coherency_flush(level) { \
> +	asm volatile( \
> +	"stmfd	sp!, {fp, ip}\n\t" \
> +	"mrc	p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> +	"bic	r0, r0, #"__stringify(CR_C)"\n\t" \
> +	"mcr	p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> +	"isb\n\t" \
> +	"bl	v7_flush_dcache_"__stringify(level)"\n\t" \
> +	"bl	mb86s70evb_outer_flush_all\n\t" \
> +	"mrc	p15, 0, r0, c1, c0, 1   @ get ACTLR\n\t" \
> +	"bic	r0, r0, #(1 << 6)       @ disable local coherency\n\t" \
> +	"mcr	p15, 0, r0, c1, c0, 1   @ set ACTLR\n\t" \
> +	"isb\n\t" \
> +	"dsb\n\t" \
> +	"ldmfd	sp!, {fp, ip}" \
> +		: : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
> +		"r9", "r10", "lr", "memory"); \
> +	}

Please make this an inline function instead of a macro.

> +
> +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);

Same comment about the extern declaration here. The header won't be
used by the implementation file as that is written in assembly,
but it's better to be consistent.

	Arnd

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-20 12:36     ` Vincent Yang
@ 2014-11-21 13:03         ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 13:03 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	olof-nZhT3qVonbNeoWH0uzbU5w, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-QSEj5FYQhm4dnm+yROfE0A,
	andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya

On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> +#define __DTS_MB86S70_CLK_H
> +
> +#define MB86S70_CRG11_ALW      0
> +#define MB86S70_CRG11_DDR3     1
> +#define MB86S70_CRG11_MAIN     2
> +#define MB86S70_CRG11_CA15     3
> +#define MB86S70_CRG11_HDMI     4
> +#define MB86S70_CRG11_DPHY     5
> +
> +#define MB86S70_CRG11_UNGPRT   8
> 

The clock driver doesn't seem to use those macros at all, how does the
driver know which clock you are referring to?

	Arnd
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 13:03         ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> +#define __DTS_MB86S70_CLK_H
> +
> +#define MB86S70_CRG11_ALW      0
> +#define MB86S70_CRG11_DDR3     1
> +#define MB86S70_CRG11_MAIN     2
> +#define MB86S70_CRG11_CA15     3
> +#define MB86S70_CRG11_HDMI     4
> +#define MB86S70_CRG11_DPHY     5
> +
> +#define MB86S70_CRG11_UNGPRT   8
> 

The clock driver doesn't seem to use those macros at all, how does the
driver know which clock you are referring to?

	Arnd

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 13:03         ` Arnd Bergmann
@ 2014-11-21 13:22           ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 13:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Vincent Yang, Devicetree List,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	Kumar Gala, Mike Turquette, Andy Green, Patch Tracking,
	Vincent Yang, Tetsuya Nuriya

On 21 November 2014 18:33, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
>> +#define __DTS_MB86S70_CLK_H
>> +
>> +#define MB86S70_CRG11_ALW      0
>> +#define MB86S70_CRG11_DDR3     1
>> +#define MB86S70_CRG11_MAIN     2
>> +#define MB86S70_CRG11_CA15     3
>> +#define MB86S70_CRG11_HDMI     4
>> +#define MB86S70_CRG11_DPHY     5
>> +
>> +#define MB86S70_CRG11_UNGPRT   8
>>
>
> The clock driver doesn't seem to use those macros at all, how does the
> driver know which clock you are referring to?
>
That was just an attempt to make a bit verbose the controller
instance. Instead of specifying controller:=4, it reads better
controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
simply fills in controller+domain+port of the given clock into mailbox
payload.

Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
port on the controller, which the clock driver does make use of.

Thanks
Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 13:22           ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 18:33, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
>> +#define __DTS_MB86S70_CLK_H
>> +
>> +#define MB86S70_CRG11_ALW      0
>> +#define MB86S70_CRG11_DDR3     1
>> +#define MB86S70_CRG11_MAIN     2
>> +#define MB86S70_CRG11_CA15     3
>> +#define MB86S70_CRG11_HDMI     4
>> +#define MB86S70_CRG11_DPHY     5
>> +
>> +#define MB86S70_CRG11_UNGPRT   8
>>
>
> The clock driver doesn't seem to use those macros at all, how does the
> driver know which clock you are referring to?
>
That was just an attempt to make a bit verbose the controller
instance. Instead of specifying controller:=4, it reads better
controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
simply fills in controller+domain+port of the given clock into mailbox
payload.

Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
port on the controller, which the clock driver does make use of.

Thanks
Jassi

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-21 13:02   ` Arnd Bergmann
@ 2014-11-21 13:24     ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 18:32, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 20 November 2014 20:35:20 Vincent Yang wrote:
>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> ---
>>  arch/arm/mach-mb86s7x/Makefile |   2 +-
>>  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>>  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>>  3 files changed, 388 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>>  create mode 100644 arch/arm/mach-mb86s7x/smc.S
>>
>> diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
>> index 97640b6..b0fa34b 100644
>> --- a/arch/arm/mach-mb86s7x/Makefile
>> +++ b/arch/arm/mach-mb86s7x/Makefile
>> @@ -1 +1 @@
>> -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
>> +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
>
> The two files are using ARMv7-only instructions in inline assembly,
> which means that you will get a compile error for a combined arvm6+armv7
> kernel. Please add the appropriate 'CFLAGS_mcpm.o += -march=armv7-a'
> statements in the Makefile for each file with this problem.
>
>> +
>> +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
>> +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
>> +extern void __iomem *mb86s7x_shm_base;
>
> Out of principle, you should never put an 'extern' declaration into .c
> file. Better put this into a header file that is shared between all files
> accessing the variable. In this particular case, I think it would be
> better to just move the mb86s7x_set_wficolor() implementation into
> drivers/soc/mb86s7x/scb_mhu.c and add an exported symbol for that, so
> you can keep the variable local to the mhu implementation.
>
>> +#define mb86s70evb_exit_coherency_flush(level) { \
>> +     asm volatile( \
>> +     "stmfd  sp!, {fp, ip}\n\t" \
>> +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
>> +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
>> +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
>> +     "isb\n\t" \
>> +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
>> +     "bl     mb86s70evb_outer_flush_all\n\t" \
>> +     "mrc    p15, 0, r0, c1, c0, 1   @ get ACTLR\n\t" \
>> +     "bic    r0, r0, #(1 << 6)       @ disable local coherency\n\t" \
>> +     "mcr    p15, 0, r0, c1, c0, 1   @ set ACTLR\n\t" \
>> +     "isb\n\t" \
>> +     "dsb\n\t" \
>> +     "ldmfd  sp!, {fp, ip}" \
>> +             : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
>> +             "r9", "r10", "lr", "memory"); \
>> +     }
>
> Please make this an inline function instead of a macro.
>
>> +
>> +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);
>
> Same comment about the extern declaration here. The header won't be
> used by the implementation file as that is written in assembly,
> but it's better to be consistent.
>
Will do all.

Thanks,
Jassi

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

* Re: [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-20 12:38     ` Vincent Yang
@ 2014-11-21 14:26         ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 14:26 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	mark.rutland-5wv7dgnIgG8, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, galak-sgV2jX0FEOL9JmXXK+q4OQ,
	olof-nZhT3qVonbNeoWH0uzbU5w, Tetsuya Nuriya

On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
> diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
> new file mode 100644
> index 0000000..a19c72f
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s70eb.dts
> @@ -0,0 +1,52 @@
> +/*
> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
> + * Copyright (C) 2014 Linaro Ltd.
> + *
> + * 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, version 2 of the License.
> + */
> +
> +/dts-v1/;
> +
> +#include "mb86s70.dtsi"
> +
> +/ {
> +	model = "Fujitsu MB86S70 EVB";
> +	compatible = "fujitsu,mb86s70-evb";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
> +
> +	};
> +
> +	chosen {
> +		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
> +		linux,initrd-start = <0xc0000000>;
> +		linux,initrd-end =   <0xc0800000>;
> +	};

The initrd parameters seem misplaced here, they should be set by the
boot loader. The loglevel=8 seems to be for debugging only, better
remove that.

> +        vccq_sdhci1: regulator@0 {
> +                compatible = "regulator-gpio";
> +                regulator-name = "SDHCI1 VccQ";
> +                regulator-min-microvolt = <1800000>;
> +                regulator-max-microvolt = <3300000>;
> +                gpios = <&gpio0 7 0>;
> +                gpios-states = <1>;
> +                states = <3300000 1
> +                          1800000 0>;
> +        };

This looks whitespace damaged, have you used checkpatch.pl to check your
patch before submitting?

> +	sdhci1: sdio@36600000 {

I think the node name should be 'mmc'

> +		compatible = "fujitsu,mb86s70-sdh30";
> +		reg = <0 0x36600000 0x1000>;
> +		interrupts = <0 172 0x4>,
> +			     <0 173 0x4>;
> +		voltage-ranges = <1800 1800>, <3300 3300>;
> +		bus-width = <4>;
> +		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
> +		clock-names = "iface", "core";
> +		vqmmc-supply = <&vccq_sdhci1>;
> +	};
> +};

Better move the actual node into the main dtsi file for the chip that
contains it, and add a 'status="disabled" property, then just
do this here:

	&sdhci1 {
		status = "ok";
	};

It probably makes sense to also leave the bus-width and voltage-ranges
properties in the per-board file if they are specific to the attached
device rather than the controller.

> diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
> new file mode 100644
> index 0000000..2bb55a3
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s73eb.dts

Some comments for this file.

> diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
> new file mode 100644
> index 0000000..50dcf04
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s7x.dtsi
> @@ -0,0 +1,595 @@
> +/*
> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
> + * Copyright (C) 2014 Linaro Ltd.
> + *
> + * 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, version 2 of the License.
> + */
> +
> +#include "skeleton.dtsi"
> +#include <dt-bindings/clock/mb86s70-clk.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <1>;
> +
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +	};

Please move the aliases into the per-board file as well, some other
boards might not support all the uarts and should only list the
ones that have a connector.
> +	/**
> +	 * The UngatedCLK is the source of 8 maskable clock ports
> +	 * as well as having its own output port which can't be masked.
> +	 */
> +	clocks {
> +		clk_alw_0_0: clk_alw_0_0 {
> +			compatible = "fujitsu,mb86s70-clk";
> +			#clock-cells = <0>;
> +			cntrlr = <MB86S70_CRG11_ALW>;
> +			domain = <0>;
> +			port = <0>;
> +		};
> +
> +		clk_alw_0_1: clk_alw_0_1 {
> +			compatible = "fujitsu,mb86s70-clk";
> +			#clock-cells = <0>;
> +			cntrlr = <MB86S70_CRG11_ALW>;
> +			domain = <0>;
> +			port = <1>;
> +		};

This seems weird: rather than have one clock controller node per
clock source, why not just have one node with #clock-cells = <3>?

Your controller seems perfectly capable of this, and you even
put the numbers in the label. It would be much more straightforward
to do

	clocks = <&clk_alw 0 1>;

than 

	clocks = <&clk_alw_0_1>;

here. Possibly even

	clocks = <&clk MB86S70_CRG11_ALW 0 1>;

with #clock-cells = <3>

> +
> +	timer0: timer@31080000 {
> +		compatible = "arm,sp804", "arm,primecell";
> +		reg = <0 0x31080000 0x1000>;
> +		interrupts = <0 324 4>,
> +			     <0 325 4>;
> +		clocks = <&clk_alw_6_8>;
> +		clock-names = "apb_pclk";
> +	};
> +
> +	timer1: archtimer {
> +		compatible = "arm,armv7-timer";
> +		clock-frequency = <125000000>;
> +		interrupts = <1 13 0xf08>,
> +			     <1 14 0xf08>,
> +			     <1 11 0xf08>,
> +			     <1 10 0xf08>;
> +	};

Inconsistent node names: please call the archtimer node 'timer'
as well, like the other one.

The label is free-form though, so you can just use 'archtimer:'
ther if you need to reference it.

> +	sdhci0: emmc@300c0000 {
> +		compatible = "fujitsu,mb86s70-sdh30";
> +		reg = <0 0x300c0000 0x1000>;
> +		interrupts = <0 164 0x4>,
> +			     <0 165 0x4>;
> +		voltage-ranges = <1800 1800>, <3300 3300>;
> +		bus-width = <8>;
> +		clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
> +		clock-names = "iface", "core";
> +	};
> +};

Maybe also leave this as disabled in the base dtsi file and move the
status="ok" property and the bus width into the per-board file.

Also change the node name to mmc.

	Arnd
--
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	[flat|nested] 97+ messages in thread

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-21 14:26         ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 14:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
> diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
> new file mode 100644
> index 0000000..a19c72f
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s70eb.dts
> @@ -0,0 +1,52 @@
> +/*
> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
> + * Copyright (C) 2014 Linaro Ltd.
> + *
> + * 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, version 2 of the License.
> + */
> +
> +/dts-v1/;
> +
> +#include "mb86s70.dtsi"
> +
> +/ {
> +	model = "Fujitsu MB86S70 EVB";
> +	compatible = "fujitsu,mb86s70-evb";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
> +
> +	};
> +
> +	chosen {
> +		bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
> +		linux,initrd-start = <0xc0000000>;
> +		linux,initrd-end =   <0xc0800000>;
> +	};

The initrd parameters seem misplaced here, they should be set by the
boot loader. The loglevel=8 seems to be for debugging only, better
remove that.

> +        vccq_sdhci1: regulator at 0 {
> +                compatible = "regulator-gpio";
> +                regulator-name = "SDHCI1 VccQ";
> +                regulator-min-microvolt = <1800000>;
> +                regulator-max-microvolt = <3300000>;
> +                gpios = <&gpio0 7 0>;
> +                gpios-states = <1>;
> +                states = <3300000 1
> +                          1800000 0>;
> +        };

This looks whitespace damaged, have you used checkpatch.pl to check your
patch before submitting?

> +	sdhci1: sdio at 36600000 {

I think the node name should be 'mmc'

> +		compatible = "fujitsu,mb86s70-sdh30";
> +		reg = <0 0x36600000 0x1000>;
> +		interrupts = <0 172 0x4>,
> +			     <0 173 0x4>;
> +		voltage-ranges = <1800 1800>, <3300 3300>;
> +		bus-width = <4>;
> +		clocks = <&clk_main_c_0>, <&clk_main_d_0>;
> +		clock-names = "iface", "core";
> +		vqmmc-supply = <&vccq_sdhci1>;
> +	};
> +};

Better move the actual node into the main dtsi file for the chip that
contains it, and add a 'status="disabled" property, then just
do this here:

	&sdhci1 {
		status = "ok";
	};

It probably makes sense to also leave the bus-width and voltage-ranges
properties in the per-board file if they are specific to the attached
device rather than the controller.

> diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
> new file mode 100644
> index 0000000..2bb55a3
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s73eb.dts

Some comments for this file.

> diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
> new file mode 100644
> index 0000000..50dcf04
> --- /dev/null
> +++ b/arch/arm/boot/dts/mb86s7x.dtsi
> @@ -0,0 +1,595 @@
> +/*
> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
> + * Copyright (C) 2014 Linaro Ltd.
> + *
> + * 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, version 2 of the License.
> + */
> +
> +#include "skeleton.dtsi"
> +#include <dt-bindings/clock/mb86s70-clk.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <1>;
> +
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +	};

Please move the aliases into the per-board file as well, some other
boards might not support all the uarts and should only list the
ones that have a connector.
> +	/**
> +	 * The UngatedCLK is the source of 8 maskable clock ports
> +	 * as well as having its own output port which can't be masked.
> +	 */
> +	clocks {
> +		clk_alw_0_0: clk_alw_0_0 {
> +			compatible = "fujitsu,mb86s70-clk";
> +			#clock-cells = <0>;
> +			cntrlr = <MB86S70_CRG11_ALW>;
> +			domain = <0>;
> +			port = <0>;
> +		};
> +
> +		clk_alw_0_1: clk_alw_0_1 {
> +			compatible = "fujitsu,mb86s70-clk";
> +			#clock-cells = <0>;
> +			cntrlr = <MB86S70_CRG11_ALW>;
> +			domain = <0>;
> +			port = <1>;
> +		};

This seems weird: rather than have one clock controller node per
clock source, why not just have one node with #clock-cells = <3>?

Your controller seems perfectly capable of this, and you even
put the numbers in the label. It would be much more straightforward
to do

	clocks = <&clk_alw 0 1>;

than 

	clocks = <&clk_alw_0_1>;

here. Possibly even

	clocks = <&clk MB86S70_CRG11_ALW 0 1>;

with #clock-cells = <3>

> +
> +	timer0: timer at 31080000 {
> +		compatible = "arm,sp804", "arm,primecell";
> +		reg = <0 0x31080000 0x1000>;
> +		interrupts = <0 324 4>,
> +			     <0 325 4>;
> +		clocks = <&clk_alw_6_8>;
> +		clock-names = "apb_pclk";
> +	};
> +
> +	timer1: archtimer {
> +		compatible = "arm,armv7-timer";
> +		clock-frequency = <125000000>;
> +		interrupts = <1 13 0xf08>,
> +			     <1 14 0xf08>,
> +			     <1 11 0xf08>,
> +			     <1 10 0xf08>;
> +	};

Inconsistent node names: please call the archtimer node 'timer'
as well, like the other one.

The label is free-form though, so you can just use 'archtimer:'
ther if you need to reference it.

> +	sdhci0: emmc at 300c0000 {
> +		compatible = "fujitsu,mb86s70-sdh30";
> +		reg = <0 0x300c0000 0x1000>;
> +		interrupts = <0 164 0x4>,
> +			     <0 165 0x4>;
> +		voltage-ranges = <1800 1800>, <3300 3300>;
> +		bus-width = <8>;
> +		clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
> +		clock-names = "iface", "core";
> +	};
> +};

Maybe also leave this as disabled in the base dtsi file and move the
status="ok" property and the bus width into the per-board file.

Also change the node name to mmc.

	Arnd

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 13:22           ` Jassi Brar
@ 2014-11-21 14:34               ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 14:34 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Vincent Yang, Devicetree List,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	Kumar Gala, Mike Turquette, Andy Green, Patch Tracking,
	Vincent Yang, Tetsuya Nuriya

On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
> On 21 November 2014 18:33, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> >> +#define __DTS_MB86S70_CLK_H
> >> +
> >> +#define MB86S70_CRG11_ALW      0
> >> +#define MB86S70_CRG11_DDR3     1
> >> +#define MB86S70_CRG11_MAIN     2
> >> +#define MB86S70_CRG11_CA15     3
> >> +#define MB86S70_CRG11_HDMI     4
> >> +#define MB86S70_CRG11_DPHY     5
> >> +
> >> +#define MB86S70_CRG11_UNGPRT   8
> >>
> >
> > The clock driver doesn't seem to use those macros at all, how does the
> > driver know which clock you are referring to?
> >
> That was just an attempt to make a bit verbose the controller
> instance. Instead of specifying controller:=4, it reads better
> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
> simply fills in controller+domain+port of the given clock into mailbox
> payload.

See my other comments on the clock nodes. If these are hardware properties,
just leave them as numbers in the DT, the header files are only used to
establish an interface between the binding and the driver in case there
is no sensible way to express which one you have.
 
> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> port on the controller, which the clock driver does make use of.

Is this the actual port number that is known to be non-maskable?
How about adding a property to the clock node to mark the logical
controller nonmaskable (in case you go for #clock-cells=2)?

For the #clock-cells=3 case, you should probably just hardcode this
in the driver based on the compatible string.

	Arnd
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 14:34               ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
> On 21 November 2014 18:33, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> >> +#define __DTS_MB86S70_CLK_H
> >> +
> >> +#define MB86S70_CRG11_ALW      0
> >> +#define MB86S70_CRG11_DDR3     1
> >> +#define MB86S70_CRG11_MAIN     2
> >> +#define MB86S70_CRG11_CA15     3
> >> +#define MB86S70_CRG11_HDMI     4
> >> +#define MB86S70_CRG11_DPHY     5
> >> +
> >> +#define MB86S70_CRG11_UNGPRT   8
> >>
> >
> > The clock driver doesn't seem to use those macros at all, how does the
> > driver know which clock you are referring to?
> >
> That was just an attempt to make a bit verbose the controller
> instance. Instead of specifying controller:=4, it reads better
> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
> simply fills in controller+domain+port of the given clock into mailbox
> payload.

See my other comments on the clock nodes. If these are hardware properties,
just leave them as numbers in the DT, the header files are only used to
establish an interface between the binding and the driver in case there
is no sensible way to express which one you have.
 
> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> port on the controller, which the clock driver does make use of.

Is this the actual port number that is known to be non-maskable?
How about adding a property to the clock node to mark the logical
controller nonmaskable (in case you go for #clock-cells=2)?

For the #clock-cells=3 case, you should probably just hardcode this
in the driver based on the compatible string.

	Arnd

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 14:34               ` Arnd Bergmann
@ 2014-11-21 16:36                 ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 16:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Vincent Yang, Devicetree List,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	Kumar Gala, Mike Turquette, Andy Green, Patch Tracking,
	Vincent Yang, Tetsuya Nuriya

On 21 November 2014 20:04, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
>> On 21 November 2014 18:33, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
>> >> +#define __DTS_MB86S70_CLK_H
>> >> +
>> >> +#define MB86S70_CRG11_ALW      0
>> >> +#define MB86S70_CRG11_DDR3     1
>> >> +#define MB86S70_CRG11_MAIN     2
>> >> +#define MB86S70_CRG11_CA15     3
>> >> +#define MB86S70_CRG11_HDMI     4
>> >> +#define MB86S70_CRG11_DPHY     5
>> >> +
>> >> +#define MB86S70_CRG11_UNGPRT   8
>> >>
>> >
>> > The clock driver doesn't seem to use those macros at all, how does the
>> > driver know which clock you are referring to?
>> >
>> That was just an attempt to make a bit verbose the controller
>> instance. Instead of specifying controller:=4, it reads better
>> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
>> simply fills in controller+domain+port of the given clock into mailbox
>> payload.
>
> See my other comments on the clock nodes. If these are hardware properties,
> just leave them as numbers in the DT, the header files are only used to
> establish an interface between the binding and the driver in case there
> is no sensible way to express which one you have.
>
OK, I'll hardcode numbers there.

>> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
>> port on the controller, which the clock driver does make use of.
>
> Is this the actual port number that is known to be non-maskable?
>
Yes the clock comes out of the controller and is also the parent of
other 8 independently maskable clock ports of the domain.
 The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request
only appropriate rates at appropriate times so that other devices are
not messed up.

> How about adding a property to the clock node to mark the logical
> controller nonmaskable (in case you go for #clock-cells=2)?
>
> For the #clock-cells=3 case, you should probably just hardcode this
> in the driver based on the compatible string.
>
The SoC has 6 controllers, each controller has 16domains and each
domain has 8+1 ports. Instead of 864 clocks, we wanted to populate
only clocks that some device actually use (some clocks seem unused in
this patchset but we have users that will be upstreamed later).
The remote f/w can't manage inter-dependencies and expect Linux to
send only appropriate requests on port basis, so we populate ports as
tiny independent clock controllers with single clock output.

Thanks
Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 16:36                 ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 20:04, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
>> On 21 November 2014 18:33, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
>> >> +#define __DTS_MB86S70_CLK_H
>> >> +
>> >> +#define MB86S70_CRG11_ALW      0
>> >> +#define MB86S70_CRG11_DDR3     1
>> >> +#define MB86S70_CRG11_MAIN     2
>> >> +#define MB86S70_CRG11_CA15     3
>> >> +#define MB86S70_CRG11_HDMI     4
>> >> +#define MB86S70_CRG11_DPHY     5
>> >> +
>> >> +#define MB86S70_CRG11_UNGPRT   8
>> >>
>> >
>> > The clock driver doesn't seem to use those macros at all, how does the
>> > driver know which clock you are referring to?
>> >
>> That was just an attempt to make a bit verbose the controller
>> instance. Instead of specifying controller:=4, it reads better
>> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
>> simply fills in controller+domain+port of the given clock into mailbox
>> payload.
>
> See my other comments on the clock nodes. If these are hardware properties,
> just leave them as numbers in the DT, the header files are only used to
> establish an interface between the binding and the driver in case there
> is no sensible way to express which one you have.
>
OK, I'll hardcode numbers there.

>> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
>> port on the controller, which the clock driver does make use of.
>
> Is this the actual port number that is known to be non-maskable?
>
Yes the clock comes out of the controller and is also the parent of
other 8 independently maskable clock ports of the domain.
 The firmware on remote master, lets say, don't wanna be bothered by
the clock topology. Even for set-rate the onus is on Linux to request
only appropriate rates at appropriate times so that other devices are
not messed up.

> How about adding a property to the clock node to mark the logical
> controller nonmaskable (in case you go for #clock-cells=2)?
>
> For the #clock-cells=3 case, you should probably just hardcode this
> in the driver based on the compatible string.
>
The SoC has 6 controllers, each controller has 16domains and each
domain has 8+1 ports. Instead of 864 clocks, we wanted to populate
only clocks that some device actually use (some clocks seem unused in
this patchset but we have users that will be upstreamed later).
The remote f/w can't manage inter-dependencies and expect Linux to
send only appropriate requests on port basis, so we populate ports as
tiny independent clock controllers with single clock output.

Thanks
Jassi

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

* Re: [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-21 14:26         ` Arnd Bergmann
@ 2014-11-21 16:49           ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 16:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Vincent Yang,
	Devicetree List, Mark Rutland, Andy Green, Pawel Moll,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Patch Tracking,
	Vincent Yang, Rob Herring, Kumar Gala, Olof Johansson,
	Tetsuya Nuriya

On 21 November 2014 19:56, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
>> diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
>> new file mode 100644
>> index 0000000..a19c72f
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s70eb.dts
>> @@ -0,0 +1,52 @@
>> +/*
>> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
>> + * Copyright (C) 2014 Linaro Ltd.
>> + *
>> + * 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, version 2 of the License.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "mb86s70.dtsi"
>> +
>> +/ {
>> +     model = "Fujitsu MB86S70 EVB";
>> +     compatible = "fujitsu,mb86s70-evb";
>> +
>> +     memory {
>> +             device_type = "memory";
>> +             reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
>> +
>> +     };
>> +
>> +     chosen {
>> +             bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
>> +             linux,initrd-start = <0xc0000000>;
>> +             linux,initrd-end =   <0xc0800000>;
>> +     };
>
> The initrd parameters seem misplaced here, they should be set by the
> boot loader. The loglevel=8 seems to be for debugging only, better
> remove that.
>
IIRC our custom made bootloader had some issues so we needed the
initrd params here. I'll check internally. And will fix the loglevel.

>> +        vccq_sdhci1: regulator@0 {
>> +                compatible = "regulator-gpio";
>> +                regulator-name = "SDHCI1 VccQ";
>> +                regulator-min-microvolt = <1800000>;
>> +                regulator-max-microvolt = <3300000>;
>> +                gpios = <&gpio0 7 0>;
>> +                gpios-states = <1>;
>> +                states = <3300000 1
>> +                          1800000 0>;
>> +        };
>
> This looks whitespace damaged, have you used checkpatch.pl to check your
> patch before submitting?
>
Sorry the sdhci and its supply node were added just before the
patchset was sent out. We did run checkpatch on patches though.

>> +     sdhci1: sdio@36600000 {
>
> I think the node name should be 'mmc'
>
>> +             compatible = "fujitsu,mb86s70-sdh30";
>> +             reg = <0 0x36600000 0x1000>;
>> +             interrupts = <0 172 0x4>,
>> +                          <0 173 0x4>;
>> +             voltage-ranges = <1800 1800>, <3300 3300>;
>> +             bus-width = <4>;
>> +             clocks = <&clk_main_c_0>, <&clk_main_d_0>;
>> +             clock-names = "iface", "core";
>> +             vqmmc-supply = <&vccq_sdhci1>;
>> +     };
>> +};
>
> Better move the actual node into the main dtsi file for the chip that
> contains it, and add a 'status="disabled" property, then just
> do this here:
>
>         &sdhci1 {
>                 status = "ok";
>         };
>
> It probably makes sense to also leave the bus-width and voltage-ranges
> properties in the per-board file if they are specific to the attached
> device rather than the controller.
>
Yes, I think the vqmmc-supply also needs to be moved in the dts.

>> diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
>> new file mode 100644
>> index 0000000..2bb55a3
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s73eb.dts
>
> Some comments for this file.
>
>> diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
>> new file mode 100644
>> index 0000000..50dcf04
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s7x.dtsi
>> @@ -0,0 +1,595 @@
>> +/*
>> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
>> + * Copyright (C) 2014 Linaro Ltd.
>> + *
>> + * 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, version 2 of the License.
>> + */
>> +
>> +#include "skeleton.dtsi"
>> +#include <dt-bindings/clock/mb86s70-clk.h>
>> +
>> +/ {
>> +     interrupt-parent = <&gic>;
>> +     #address-cells = <2>;
>> +     #size-cells = <1>;
>> +
>> +     aliases {
>> +             serial0 = &uart0;
>> +             serial1 = &uart1;
>> +             serial2 = &uart2;
>> +     };
>
> Please move the aliases into the per-board file as well, some other
> boards might not support all the uarts and should only list the
> ones that have a connector.
>> +     /**
>> +      * The UngatedCLK is the source of 8 maskable clock ports
>> +      * as well as having its own output port which can't be masked.
>> +      */
>> +     clocks {
>> +             clk_alw_0_0: clk_alw_0_0 {
>> +                     compatible = "fujitsu,mb86s70-clk";
>> +                     #clock-cells = <0>;
>> +                     cntrlr = <MB86S70_CRG11_ALW>;
>> +                     domain = <0>;
>> +                     port = <0>;
>> +             };
>> +
>> +             clk_alw_0_1: clk_alw_0_1 {
>> +                     compatible = "fujitsu,mb86s70-clk";
>> +                     #clock-cells = <0>;
>> +                     cntrlr = <MB86S70_CRG11_ALW>;
>> +                     domain = <0>;
>> +                     port = <1>;
>> +             };
>
> This seems weird: rather than have one clock controller node per
> clock source, why not just have one node with #clock-cells = <3>?
>
> Your controller seems perfectly capable of this, and you even
> put the numbers in the label. It would be much more straightforward
> to do
>
>         clocks = <&clk_alw 0 1>;
>
> than
>
>         clocks = <&clk_alw_0_1>;
>
> here. Possibly even
>
>         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
>
> with #clock-cells = <3>
>
Is there a way to compact the dtsi and yet populate only clocks that
are actually ever used (instead of 6x16x9)?

>> +
>> +     timer0: timer@31080000 {
>> +             compatible = "arm,sp804", "arm,primecell";
>> +             reg = <0 0x31080000 0x1000>;
>> +             interrupts = <0 324 4>,
>> +                          <0 325 4>;
>> +             clocks = <&clk_alw_6_8>;
>> +             clock-names = "apb_pclk";
>> +     };
>> +
>> +     timer1: archtimer {
>> +             compatible = "arm,armv7-timer";
>> +             clock-frequency = <125000000>;
>> +             interrupts = <1 13 0xf08>,
>> +                          <1 14 0xf08>,
>> +                          <1 11 0xf08>,
>> +                          <1 10 0xf08>;
>> +     };
>
> Inconsistent node names: please call the archtimer node 'timer'
> as well, like the other one.
>
> The label is free-form though, so you can just use 'archtimer:'
> ther if you need to reference it.
>
>> +     sdhci0: emmc@300c0000 {
>> +             compatible = "fujitsu,mb86s70-sdh30";
>> +             reg = <0 0x300c0000 0x1000>;
>> +             interrupts = <0 164 0x4>,
>> +                          <0 165 0x4>;
>> +             voltage-ranges = <1800 1800>, <3300 3300>;
>> +             bus-width = <8>;
>> +             clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
>> +             clock-names = "iface", "core";
>> +     };
>> +};
>
> Maybe also leave this as disabled in the base dtsi file and move the
> status="ok" property and the bus width into the per-board file.
>
> Also change the node name to mmc.
>
Will address all comments.

Thanks.
Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-21 16:49           ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 19:56, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 20 November 2014 20:38:46 Vincent Yang wrote:
>> diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
>> new file mode 100644
>> index 0000000..a19c72f
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s70eb.dts
>> @@ -0,0 +1,52 @@
>> +/*
>> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
>> + * Copyright (C) 2014 Linaro Ltd.
>> + *
>> + * 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, version 2 of the License.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "mb86s70.dtsi"
>> +
>> +/ {
>> +     model = "Fujitsu MB86S70 EVB";
>> +     compatible = "fujitsu,mb86s70-evb";
>> +
>> +     memory {
>> +             device_type = "memory";
>> +             reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
>> +
>> +     };
>> +
>> +     chosen {
>> +             bootargs = "loglevel=8 console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
>> +             linux,initrd-start = <0xc0000000>;
>> +             linux,initrd-end =   <0xc0800000>;
>> +     };
>
> The initrd parameters seem misplaced here, they should be set by the
> boot loader. The loglevel=8 seems to be for debugging only, better
> remove that.
>
IIRC our custom made bootloader had some issues so we needed the
initrd params here. I'll check internally. And will fix the loglevel.

>> +        vccq_sdhci1: regulator at 0 {
>> +                compatible = "regulator-gpio";
>> +                regulator-name = "SDHCI1 VccQ";
>> +                regulator-min-microvolt = <1800000>;
>> +                regulator-max-microvolt = <3300000>;
>> +                gpios = <&gpio0 7 0>;
>> +                gpios-states = <1>;
>> +                states = <3300000 1
>> +                          1800000 0>;
>> +        };
>
> This looks whitespace damaged, have you used checkpatch.pl to check your
> patch before submitting?
>
Sorry the sdhci and its supply node were added just before the
patchset was sent out. We did run checkpatch on patches though.

>> +     sdhci1: sdio at 36600000 {
>
> I think the node name should be 'mmc'
>
>> +             compatible = "fujitsu,mb86s70-sdh30";
>> +             reg = <0 0x36600000 0x1000>;
>> +             interrupts = <0 172 0x4>,
>> +                          <0 173 0x4>;
>> +             voltage-ranges = <1800 1800>, <3300 3300>;
>> +             bus-width = <4>;
>> +             clocks = <&clk_main_c_0>, <&clk_main_d_0>;
>> +             clock-names = "iface", "core";
>> +             vqmmc-supply = <&vccq_sdhci1>;
>> +     };
>> +};
>
> Better move the actual node into the main dtsi file for the chip that
> contains it, and add a 'status="disabled" property, then just
> do this here:
>
>         &sdhci1 {
>                 status = "ok";
>         };
>
> It probably makes sense to also leave the bus-width and voltage-ranges
> properties in the per-board file if they are specific to the attached
> device rather than the controller.
>
Yes, I think the vqmmc-supply also needs to be moved in the dts.

>> diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
>> new file mode 100644
>> index 0000000..2bb55a3
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s73eb.dts
>
> Some comments for this file.
>
>> diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
>> new file mode 100644
>> index 0000000..50dcf04
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/mb86s7x.dtsi
>> @@ -0,0 +1,595 @@
>> +/*
>> + * Copyright (C) 2013-2014 FUJITSU SEMICONDUCTOR LIMITED
>> + * Copyright (C) 2014 Linaro Ltd.
>> + *
>> + * 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, version 2 of the License.
>> + */
>> +
>> +#include "skeleton.dtsi"
>> +#include <dt-bindings/clock/mb86s70-clk.h>
>> +
>> +/ {
>> +     interrupt-parent = <&gic>;
>> +     #address-cells = <2>;
>> +     #size-cells = <1>;
>> +
>> +     aliases {
>> +             serial0 = &uart0;
>> +             serial1 = &uart1;
>> +             serial2 = &uart2;
>> +     };
>
> Please move the aliases into the per-board file as well, some other
> boards might not support all the uarts and should only list the
> ones that have a connector.
>> +     /**
>> +      * The UngatedCLK is the source of 8 maskable clock ports
>> +      * as well as having its own output port which can't be masked.
>> +      */
>> +     clocks {
>> +             clk_alw_0_0: clk_alw_0_0 {
>> +                     compatible = "fujitsu,mb86s70-clk";
>> +                     #clock-cells = <0>;
>> +                     cntrlr = <MB86S70_CRG11_ALW>;
>> +                     domain = <0>;
>> +                     port = <0>;
>> +             };
>> +
>> +             clk_alw_0_1: clk_alw_0_1 {
>> +                     compatible = "fujitsu,mb86s70-clk";
>> +                     #clock-cells = <0>;
>> +                     cntrlr = <MB86S70_CRG11_ALW>;
>> +                     domain = <0>;
>> +                     port = <1>;
>> +             };
>
> This seems weird: rather than have one clock controller node per
> clock source, why not just have one node with #clock-cells = <3>?
>
> Your controller seems perfectly capable of this, and you even
> put the numbers in the label. It would be much more straightforward
> to do
>
>         clocks = <&clk_alw 0 1>;
>
> than
>
>         clocks = <&clk_alw_0_1>;
>
> here. Possibly even
>
>         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
>
> with #clock-cells = <3>
>
Is there a way to compact the dtsi and yet populate only clocks that
are actually ever used (instead of 6x16x9)?

>> +
>> +     timer0: timer at 31080000 {
>> +             compatible = "arm,sp804", "arm,primecell";
>> +             reg = <0 0x31080000 0x1000>;
>> +             interrupts = <0 324 4>,
>> +                          <0 325 4>;
>> +             clocks = <&clk_alw_6_8>;
>> +             clock-names = "apb_pclk";
>> +     };
>> +
>> +     timer1: archtimer {
>> +             compatible = "arm,armv7-timer";
>> +             clock-frequency = <125000000>;
>> +             interrupts = <1 13 0xf08>,
>> +                          <1 14 0xf08>,
>> +                          <1 11 0xf08>,
>> +                          <1 10 0xf08>;
>> +     };
>
> Inconsistent node names: please call the archtimer node 'timer'
> as well, like the other one.
>
> The label is free-form though, so you can just use 'archtimer:'
> ther if you need to reference it.
>
>> +     sdhci0: emmc at 300c0000 {
>> +             compatible = "fujitsu,mb86s70-sdh30";
>> +             reg = <0 0x300c0000 0x1000>;
>> +             interrupts = <0 164 0x4>,
>> +                          <0 165 0x4>;
>> +             voltage-ranges = <1800 1800>, <3300 3300>;
>> +             bus-width = <8>;
>> +             clocks = <&clk_alw_c_0>, <&clk_alw_b_0>;
>> +             clock-names = "iface", "core";
>> +     };
>> +};
>
> Maybe also leave this as disabled in the base dtsi file and move the
> status="ok" property and the bus width into the per-board file.
>
> Also change the node name to mmc.
>
Will address all comments.

Thanks.
Jassi

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

* Re: [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-21 16:49           ` Jassi Brar
@ 2014-11-21 17:09               ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 17:09 UTC (permalink / raw)
  To: Jassi Brar
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Vincent Yang,
	Devicetree List, Mark Rutland, Andy Green, Pawel Moll,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Patch Tracking,
	Vincent Yang, Rob Herring, Kumar Gala, Olof Johansson,
	Tetsuya Nuriya

On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
> >
> > This seems weird: rather than have one clock controller node per
> > clock source, why not just have one node with #clock-cells = >?
> >
> > Your controller seems perfectly capable of this, and you even
> > put the numbers in the label. It would be much more straightforward
> > to do
> >
> >         clocks = <&clk_alw 0 1>;
> >
> > than
> >
> >         clocks = <&clk_alw_0_1>;
> >
> > here. Possibly even
> >
> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
> >
> > with #clock-cells = >
> >
> Is there a way to compact the dtsi and yet populate only clocks that
> are actually ever used (instead of 6x16x9)?

I believe the clock driver just wouldn't create the clocks until
a device driver requests them.

	Arnd
--
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	[flat|nested] 97+ messages in thread

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-21 17:09               ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
> >
> > This seems weird: rather than have one clock controller node per
> > clock source, why not just have one node with #clock-cells = >?
> >
> > Your controller seems perfectly capable of this, and you even
> > put the numbers in the label. It would be much more straightforward
> > to do
> >
> >         clocks = <&clk_alw 0 1>;
> >
> > than
> >
> >         clocks = <&clk_alw_0_1>;
> >
> > here. Possibly even
> >
> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
> >
> > with #clock-cells = >
> >
> Is there a way to compact the dtsi and yet populate only clocks that
> are actually ever used (instead of 6x16x9)?

I believe the clock driver just wouldn't create the clocks until
a device driver requests them.

	Arnd

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 16:36                 ` Jassi Brar
@ 2014-11-21 17:15                     ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 17:15 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Vincent Yang, Devicetree List,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	Kumar Gala, Mike Turquette, Andy Green, Patch Tracking,
	Vincent Yang, Tetsuya Nuriya

On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
> On 21 November 2014 20:04, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
> >> On 21 November 2014 18:33, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> >> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> >> >> +#define __DTS_MB86S70_CLK_H
> >> >> +
> >> >> +#define MB86S70_CRG11_ALW      0
> >> >> +#define MB86S70_CRG11_DDR3     1
> >> >> +#define MB86S70_CRG11_MAIN     2
> >> >> +#define MB86S70_CRG11_CA15     3
> >> >> +#define MB86S70_CRG11_HDMI     4
> >> >> +#define MB86S70_CRG11_DPHY     5
> >> >> +
> >> >> +#define MB86S70_CRG11_UNGPRT   8
> >> >>
> >> >
> >> > The clock driver doesn't seem to use those macros at all, how does the
> >> > driver know which clock you are referring to?
> >> >
> >> That was just an attempt to make a bit verbose the controller
> >> instance. Instead of specifying controller:=4, it reads better
> >> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
> >> simply fills in controller+domain+port of the given clock into mailbox
> >> payload.
> >
> > See my other comments on the clock nodes. If these are hardware properties,
> > just leave them as numbers in the DT, the header files are only used to
> > establish an interface between the binding and the driver in case there
> > is no sensible way to express which one you have.
> >
> OK, I'll hardcode numbers there.
> 
> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> >> port on the controller, which the clock driver does make use of.
> >
> > Is this the actual port number that is known to be non-maskable?
> >
> Yes the clock comes out of the controller and is also the parent of
> other 8 independently maskable clock ports of the domain.

I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
a port or a controller?

>  The firmware on remote master, lets say, don't wanna be bothered by
> the clock topology. Even for set-rate the onus is on Linux to request
> only appropriate rates at appropriate times so that other devices are
> not messed up.

Is there any code to validate that, or does Linux just treat all
clocks transparently?

> > How about adding a property to the clock node to mark the logical
> > controller nonmaskable (in case you go for #clock-cells=2)?
> >
> > For the #clock-cells=3 case, you should probably just hardcode this
> > in the driver based on the compatible string.
> >
> The SoC has 6 controllers, each controller has 16domains and each
> domain has 8+1 ports. Instead of 864 clocks, we wanted to populate
> only clocks that some device actually use (some clocks seem unused in
> this patchset but we have users that will be upstreamed later).
> The remote f/w can't manage inter-dependencies and expect Linux to
> send only appropriate requests on port basis, so we populate ports as
> tiny independent clock controllers with single clock output.

My impression is that it would be best to model each controller of the
SoC as a clock controller device node with #clock-cells=<2>, and hardcode
the behavior of the special port in the driver.

	Arnd
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 17:15                     ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 17:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
> On 21 November 2014 20:04, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 21 November 2014 18:52:47 Jassi Brar wrote:
> >> On 21 November 2014 18:33, Arnd Bergmann <arnd@arndb.de> wrote:
> >> > On Thursday 20 November 2014 20:36:15 Vincent Yang wrote:
> >> >> +#define __DTS_MB86S70_CLK_H
> >> >> +
> >> >> +#define MB86S70_CRG11_ALW      0
> >> >> +#define MB86S70_CRG11_DDR3     1
> >> >> +#define MB86S70_CRG11_MAIN     2
> >> >> +#define MB86S70_CRG11_CA15     3
> >> >> +#define MB86S70_CRG11_HDMI     4
> >> >> +#define MB86S70_CRG11_DPHY     5
> >> >> +
> >> >> +#define MB86S70_CRG11_UNGPRT   8
> >> >>
> >> >
> >> > The clock driver doesn't seem to use those macros at all, how does the
> >> > driver know which clock you are referring to?
> >> >
> >> That was just an attempt to make a bit verbose the controller
> >> instance. Instead of specifying controller:=4, it reads better
> >> controller:=MB86S70_CRG11_HDMI in the clock DT nodes. The clock driver
> >> simply fills in controller+domain+port of the given clock into mailbox
> >> payload.
> >
> > See my other comments on the clock nodes. If these are hardware properties,
> > just leave them as numbers in the DT, the header files are only used to
> > establish an interface between the binding and the driver in case there
> > is no sensible way to express which one you have.
> >
> OK, I'll hardcode numbers there.
> 
> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> >> port on the controller, which the clock driver does make use of.
> >
> > Is this the actual port number that is known to be non-maskable?
> >
> Yes the clock comes out of the controller and is also the parent of
> other 8 independently maskable clock ports of the domain.

I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
a port or a controller?

>  The firmware on remote master, lets say, don't wanna be bothered by
> the clock topology. Even for set-rate the onus is on Linux to request
> only appropriate rates at appropriate times so that other devices are
> not messed up.

Is there any code to validate that, or does Linux just treat all
clocks transparently?

> > How about adding a property to the clock node to mark the logical
> > controller nonmaskable (in case you go for #clock-cells=2)?
> >
> > For the #clock-cells=3 case, you should probably just hardcode this
> > in the driver based on the compatible string.
> >
> The SoC has 6 controllers, each controller has 16domains and each
> domain has 8+1 ports. Instead of 864 clocks, we wanted to populate
> only clocks that some device actually use (some clocks seem unused in
> this patchset but we have users that will be upstreamed later).
> The remote f/w can't manage inter-dependencies and expect Linux to
> send only appropriate requests on port basis, so we populate ports as
> tiny independent clock controllers with single clock output.

My impression is that it would be best to model each controller of the
SoC as a clock controller device node with #clock-cells=<2>, and hardcode
the behavior of the special port in the driver.

	Arnd

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

* Re: [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-21 17:09               ` Arnd Bergmann
@ 2014-11-21 17:35                 ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 17:35 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Vincent Yang,
	Devicetree List, Mark Rutland, Andy Green, Pawel Moll,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Patch Tracking,
	Vincent Yang, Rob Herring, Kumar Gala, Olof Johansson,
	Tetsuya Nuriya

On 21 November 2014 22:39, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
>> >
>> > This seems weird: rather than have one clock controller node per
>> > clock source, why not just have one node with #clock-cells = >?
>> >
>> > Your controller seems perfectly capable of this, and you even
>> > put the numbers in the label. It would be much more straightforward
>> > to do
>> >
>> >         clocks = <&clk_alw 0 1>;
>> >
>> > than
>> >
>> >         clocks = <&clk_alw_0_1>;
>> >
>> > here. Possibly even
>> >
>> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
>> >
>> > with #clock-cells = >
>> >
>> Is there a way to compact the dtsi and yet populate only clocks that
>> are actually ever used (instead of 6x16x9)?
>
> I believe the clock driver just wouldn't create the clocks until
> a device driver requests them.
>
Seems like the chicken-egg problem. Let me check.

Thanks
Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-21 17:35                 ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 17:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 22:39, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
>> >
>> > This seems weird: rather than have one clock controller node per
>> > clock source, why not just have one node with #clock-cells = >?
>> >
>> > Your controller seems perfectly capable of this, and you even
>> > put the numbers in the label. It would be much more straightforward
>> > to do
>> >
>> >         clocks = <&clk_alw 0 1>;
>> >
>> > than
>> >
>> >         clocks = <&clk_alw_0_1>;
>> >
>> > here. Possibly even
>> >
>> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
>> >
>> > with #clock-cells = >
>> >
>> Is there a way to compact the dtsi and yet populate only clocks that
>> are actually ever used (instead of 6x16x9)?
>
> I believe the clock driver just wouldn't create the clocks until
> a device driver requests them.
>
Seems like the chicken-egg problem. Let me check.

Thanks
Jassi

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 17:15                     ` Arnd Bergmann
@ 2014-11-21 17:58                       ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 17:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Vincent Yang, Devicetree List,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Olof Johansson, Russell King - ARM Linux, Rob Herring,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	Kumar Gala, Mike Turquette, Andy Green, Patch Tracking,
	Vincent Yang, Tetsuya Nuriya

On 21 November 2014 22:45, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Friday 21 November 2014 22:06:51 Jassi Brar wrote:

>> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
>> >> port on the controller, which the clock driver does make use of.
>> >
>> > Is this the actual port number that is known to be non-maskable?
>> >
>> Yes the clock comes out of the controller and is also the parent of
>> other 8 independently maskable clock ports of the domain.
>
> I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
> a port or a controller?
>
Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth
parent clock (port) of a domain that can't be masked.
FYKI, there are 6 instances, of some CRG11 clock controller, under
control of the remote f/w. The Mailbox protocol between remote f/w and
Linux assigned indices [0-5] to these controllers.

>>  The firmware on remote master, lets say, don't wanna be bothered by
>> the clock topology. Even for set-rate the onus is on Linux to request
>> only appropriate rates at appropriate times so that other devices are
>> not messed up.
>
> Is there any code to validate that, or does Linux just treat all
> clocks transparently?
>
The remote does not expose the clock topology and only accepts
requests on port-basis. The remote f/w is supposed to keep track of
which ports are used by Linux and then work out inter-dependencies
upon receiving a request from Linux. So for Linux there are N
independent 'root' clocks, ops on which may or may not succeed at any
given time.

thanks
jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 17:58                       ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-21 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 November 2014 22:45, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 21 November 2014 22:06:51 Jassi Brar wrote:

>> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
>> >> port on the controller, which the clock driver does make use of.
>> >
>> > Is this the actual port number that is known to be non-maskable?
>> >
>> Yes the clock comes out of the controller and is also the parent of
>> other 8 independently maskable clock ports of the domain.
>
> I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
> a port or a controller?
>
Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth
parent clock (port) of a domain that can't be masked.
FYKI, there are 6 instances, of some CRG11 clock controller, under
control of the remote f/w. The Mailbox protocol between remote f/w and
Linux assigned indices [0-5] to these controllers.

>>  The firmware on remote master, lets say, don't wanna be bothered by
>> the clock topology. Even for set-rate the onus is on Linux to request
>> only appropriate rates at appropriate times so that other devices are
>> not messed up.
>
> Is there any code to validate that, or does Linux just treat all
> clocks transparently?
>
The remote does not expose the clock topology and only accepts
requests on port-basis. The remote f/w is supposed to keep track of
which ports are used by Linux and then work out inter-dependencies
upon receiving a request from Linux. So for Linux there are N
independent 'root' clocks, ops on which may or may not succeed at any
given time.

thanks
jassi

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

* Re: [PATCH 4/9] clk: Add clock driver for mb86s7x
  2014-11-21 17:58                       ` Jassi Brar
@ 2014-11-21 20:12                         ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 20:12 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Mark Rutland, Devicetree List, Andy Green,
	Russell King - ARM Linux, Pawel Moll, ijc+devicetree,
	Vincent Yang, Patch Tracking, Vincent Yang, Rob Herring,
	Kumar Gala, Olof Johansson, Mike Turquette, Tetsuya Nuriya,
	linux-arm-kernel

On Friday 21 November 2014 23:28:38 Jassi Brar wrote:
> On 21 November 2014 22:45, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
> 
> >> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> >> >> port on the controller, which the clock driver does make use of.
> >> >
> >> > Is this the actual port number that is known to be non-maskable?
> >> >
> >> Yes the clock comes out of the controller and is also the parent of
> >> other 8 independently maskable clock ports of the domain.
> >
> > I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
> > a port or a controller?
> >
> Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth
> parent clock (port) of a domain that can't be masked.
> FYKI, there are 6 instances, of some CRG11 clock controller, under
> control of the remote f/w. The Mailbox protocol between remote f/w and
> Linux assigned indices [0-5] to these controllers.

Ok, not it makes sense, thanks for clearing that up!

> >>  The firmware on remote master, lets say, don't wanna be bothered by
> >> the clock topology. Even for set-rate the onus is on Linux to request
> >> only appropriate rates at appropriate times so that other devices are
> >> not messed up.
> >
> > Is there any code to validate that, or does Linux just treat all
> > clocks transparently?
> >
> The remote does not expose the clock topology and only accepts
> requests on port-basis. The remote f/w is supposed to keep track of
> which ports are used by Linux and then work out inter-dependencies
> upon receiving a request from Linux. So for Linux there are N
> independent 'root' clocks, ops on which may or may not succeed at any
> given time.

Ok.

	Arnd

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

* [PATCH 4/9] clk: Add clock driver for mb86s7x
@ 2014-11-21 20:12                         ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 20:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 21 November 2014 23:28:38 Jassi Brar wrote:
> On 21 November 2014 22:45, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 21 November 2014 22:06:51 Jassi Brar wrote:
> 
> >> >> Only MB86S70_CRG11_UNGPRT is marked to mean one special (non-maskable)
> >> >> port on the controller, which the clock driver does make use of.
> >> >
> >> > Is this the actual port number that is known to be non-maskable?
> >> >
> >> Yes the clock comes out of the controller and is also the parent of
> >> other 8 independently maskable clock ports of the domain.
> >
> > I'm getting confused by the terminology here. Is MB86S70_CRG11_ALW
> > a port or a controller?
> >
> Sorry, bad symbols. ALW..DPHY are controllers. UNGPRT is the ninth
> parent clock (port) of a domain that can't be masked.
> FYKI, there are 6 instances, of some CRG11 clock controller, under
> control of the remote f/w. The Mailbox protocol between remote f/w and
> Linux assigned indices [0-5] to these controllers.

Ok, not it makes sense, thanks for clearing that up!

> >>  The firmware on remote master, lets say, don't wanna be bothered by
> >> the clock topology. Even for set-rate the onus is on Linux to request
> >> only appropriate rates at appropriate times so that other devices are
> >> not messed up.
> >
> > Is there any code to validate that, or does Linux just treat all
> > clocks transparently?
> >
> The remote does not expose the clock topology and only accepts
> requests on port-basis. The remote f/w is supposed to keep track of
> which ports are used by Linux and then work out inter-dependencies
> upon receiving a request from Linux. So for Linux there are N
> independent 'root' clocks, ops on which may or may not succeed at any
> given time.

Ok.

	Arnd

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

* Re: [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
  2014-11-21 17:35                 ` Jassi Brar
@ 2014-11-21 20:14                   ` Arnd Bergmann
  -1 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 20:14 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Mark Rutland, Devicetree List, Andy Green, Pawel Moll,
	ijc+devicetree, Vincent Yang, Patch Tracking, Vincent Yang,
	Rob Herring, Kumar Gala, Olof Johansson, Tetsuya Nuriya,
	linux-arm-kernel

On Friday 21 November 2014 23:05:28 Jassi Brar wrote:
> On 21 November 2014 22:39, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
> >> >
> >> > This seems weird: rather than have one clock controller node per
> >> > clock source, why not just have one node with #clock-cells = >?
> >> >
> >> > Your controller seems perfectly capable of this, and you even
> >> > put the numbers in the label. It would be much more straightforward
> >> > to do
> >> >
> >> >         clocks = <&clk_alw 0 1>;
> >> >
> >> > than
> >> >
> >> >         clocks = <&clk_alw_0_1>;
> >> >
> >> > here. Possibly even
> >> >
> >> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
> >> >
> >> > with #clock-cells = >
> >> >
> >> Is there a way to compact the dtsi and yet populate only clocks that
> >> are actually ever used (instead of 6x16x9)?
> >
> > I believe the clock driver just wouldn't create the clocks until
> > a device driver requests them.
> >
> Seems like the chicken-egg problem. Let me check.

What I mean is that you should call of_clk_add_provider once for each
of the six clock controllers, but not call clk_register_gate or
clk_register for each possible output until it gets requested.

	Arnd

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

* [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2014-11-21 20:14                   ` Arnd Bergmann
  0 siblings, 0 replies; 97+ messages in thread
From: Arnd Bergmann @ 2014-11-21 20:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 21 November 2014 23:05:28 Jassi Brar wrote:
> On 21 November 2014 22:39, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Friday 21 November 2014 22:19:43 Jassi Brar wrote:
> >> >
> >> > This seems weird: rather than have one clock controller node per
> >> > clock source, why not just have one node with #clock-cells = >?
> >> >
> >> > Your controller seems perfectly capable of this, and you even
> >> > put the numbers in the label. It would be much more straightforward
> >> > to do
> >> >
> >> >         clocks = <&clk_alw 0 1>;
> >> >
> >> > than
> >> >
> >> >         clocks = <&clk_alw_0_1>;
> >> >
> >> > here. Possibly even
> >> >
> >> >         clocks = <&clk MB86S70_CRG11_ALW 0 1>;
> >> >
> >> > with #clock-cells = >
> >> >
> >> Is there a way to compact the dtsi and yet populate only clocks that
> >> are actually ever used (instead of 6x16x9)?
> >
> > I believe the clock driver just wouldn't create the clocks until
> > a device driver requests them.
> >
> Seems like the chicken-egg problem. Let me check.

What I mean is that you should call of_clk_add_provider once for each
of the six clock controllers, but not call clk_register_gate or
clk_register for each possible output until it gets requested.

	Arnd

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-20 12:35 ` [PATCH 3/9] ARM: MB86S7X: Add MCPM support Vincent Yang
  2014-11-21 13:02   ` Arnd Bergmann
@ 2014-11-25 11:48   ` Sudeep Holla
  2014-11-25 13:42     ` Andy Green
  2014-11-25 17:42   ` Nicolas Pitre
  2 siblings, 1 reply; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 11:48 UTC (permalink / raw)
  To: linux-arm-kernel



On 20/11/14 12:35, Vincent Yang wrote:
> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> CPU/CLUSTER power up/down done by SCB over mailbox.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>   arch/arm/mach-mb86s7x/Makefile |   2 +-
>   arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>   arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>   3 files changed, 388 insertions(+), 1 deletion(-)
>   create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>   create mode 100644 arch/arm/mach-mb86s7x/smc.S
>

[...]

> +asmlinkage void mb86s70evb_outer_flush_all(void)
> +{
> +       outer_flush_all();
> +}
> +
> +#define mb86s70evb_exit_coherency_flush(level) { \

You are duplicating the generic macro just to add outer cache, I was
thinking of extending the generic macro to add outer cache support, but
IMO it might be bit tricky for below mentioned reasons.

> +       asm volatile( \
> +       "stmfd  sp!, {fp, ip}\n\t" \
> +       "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> +       "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
> +       "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> +       "isb\n\t" \
> +       "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
> +       "bl     mb86s70evb_outer_flush_all\n\t" \

IIUC, this seem to be broken IMO, you are doing the outer cache flush
unconditionally which means:

1. You do this for every CPU power down(i.e. when level = louis) which
    is incorrect.
2. You do this for every cluster powerdown, again is that required if
    the other cluster is active. You may have to trace last cluster in
    the system.

> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
> new file mode 100644
> index 0000000..a14330b
> --- /dev/null
> +++ b/arch/arm/mach-mb86s7x/smc.S
> @@ -0,0 +1,27 @@
> +/*
> + * SMC command interface to set secondary entry point
> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
> + * Copyright: (C) 2014 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/linkage.h>
> +
> +.arch_extension sec
> +
> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
> +ENTRY(mb86s7x_cpu_entry)
> +       stmfd   sp!, {r1-r11, lr}
> +       mov r1, r0
> +       ldr r0, =1
> +       mrc p15, 0, r3, c1, c0, 0
> +       mov r4, r3
> +       and r3, #0xbfffffff
> +       mcr p15, 0, r3, c1, c0, 0
> +       smc #0

Interesting, it looks like you have some secure entity running on your
platform.
1. While the CPU is powered down who is taking care of saving it's
    state as you are doing it in the Linux itself ?
2. Is Linux running in Secure or Non-secure mode ?
3. Why do you need this smc call for secondary boot only ?

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 11:48   ` Sudeep Holla
@ 2014-11-25 13:42     ` Andy Green
  2014-11-25 14:24       ` Sudeep Holla
  0 siblings, 1 reply; 97+ messages in thread
From: Andy Green @ 2014-11-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 25 November 2014 at 19:48, Sudeep Holla <sudeep.holla@arm.com> wrote:

> On 20/11/14 12:35, Vincent Yang wrote:
>>
>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>
>
>> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
>> new file mode 100644
>> index 0000000..a14330b
>> --- /dev/null
>> +++ b/arch/arm/mach-mb86s7x/smc.S
>> @@ -0,0 +1,27 @@
>> +/*
>> + * SMC command interface to set secondary entry point
>> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
>> + * Copyright: (C) 2014 Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/linkage.h>
>> +
>> +.arch_extension sec
>> +
>> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
>> +ENTRY(mb86s7x_cpu_entry)
>> +       stmfd   sp!, {r1-r11, lr}
>> +       mov r1, r0
>> +       ldr r0, =1
>> +       mrc p15, 0, r3, c1, c0, 0
>> +       mov r4, r3
>> +       and r3, #0xbfffffff
>> +       mcr p15, 0, r3, c1, c0, 0
>> +       smc #0
>
>
> Interesting, it looks like you have some secure entity running on your
> platform.

Yes, we have a stub "secure firmware" that implements a few critical
functions to allow us to operate the kernel as nonsecure.  It's part
of the bootloader for this platform which is also GPL'd.

> 1. While the CPU is powered down who is taking care of saving it's
>    state as you are doing it in the Linux itself ?

Nothing.  The secure firmware is in a bootloader that is copied to and
runs from secure sram.  When the cpu is reset, he comes back up in
secure mode and gets initialized in the secure firmware, before
entering Non-secure mode and the kernel's secondary entry point.

> 2. Is Linux running in Secure or Non-secure mode ?

Another firmware (unfortunately not GPL) running on an on-die M3
informs the secure firmware on the AP whether he should set the AP cpu
to nonsecure or not before jumping to the kernel... basically it's
decided at runtime and the same kernel binary serves in both modes.

> 3. Why do you need this smc call for secondary boot only ?

The call sets the secondary entry point stored in the secure sram.

The bootloader heuristic is if that's unset (0), and it's what the
bootloader decided should be regarded as the primary cpu, then we do
the real onetime cold boot flow, load the kernel etc.  Non-primary
cpus wait at WFI in the bootloader.  When the primary cpu runs the
code above, he sets the secondary entry point, and later starts to
bring up the other cores who jump to the secondary entry that was set.

-Andy

> Regards,
> Sudeep
>

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 13:42     ` Andy Green
@ 2014-11-25 14:24       ` Sudeep Holla
  2014-11-25 16:43         ` Andy Green
  0 siblings, 1 reply; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 14:24 UTC (permalink / raw)
  To: linux-arm-kernel



On 25/11/14 13:42, Andy Green wrote:
> On 25 November 2014 at 19:48, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>> On 20/11/14 12:35, Vincent Yang wrote:
>>>
>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>
>>
>>> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
>>> new file mode 100644
>>> index 0000000..a14330b
>>> --- /dev/null
>>> +++ b/arch/arm/mach-mb86s7x/smc.S
>>> @@ -0,0 +1,27 @@
>>> +/*
>>> + * SMC command interface to set secondary entry point
>>> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
>>> + * Copyright: (C) 2014 Linaro Ltd.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#include <linux/linkage.h>
>>> +
>>> +.arch_extension sec
>>> +
>>> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
>>> +ENTRY(mb86s7x_cpu_entry)
>>> +       stmfd   sp!, {r1-r11, lr}
>>> +       mov r1, r0
>>> +       ldr r0, =1
>>> +       mrc p15, 0, r3, c1, c0, 0
>>> +       mov r4, r3
>>> +       and r3, #0xbfffffff
>>> +       mcr p15, 0, r3, c1, c0, 0
>>> +       smc #0
>>
>>
>> Interesting, it looks like you have some secure entity running on your
>> platform.
>
> Yes, we have a stub "secure firmware" that implements a few critical
> functions to allow us to operate the kernel as nonsecure.  It's part
> of the bootloader for this platform which is also GPL'd.
>

OK, thanks for clarifying.

>> 1. While the CPU is powered down who is taking care of saving it's
>>     state as you are doing it in the Linux itself ?
>
> Nothing.  The secure firmware is in a bootloader that is copied to and
> runs from secure sram.  When the cpu is reset, he comes back up in
> secure mode and gets initialized in the secure firmware, before
> entering Non-secure mode and the kernel's secondary entry point.
>

So you do have live secure firmware stub on secure sram at any time,
right ? When the CPUs are powered down especially for low power states,
how is the secure state of the CPUs preserved ?

>> 2. Is Linux running in Secure or Non-secure mode ?
>
> Another firmware (unfortunately not GPL) running on an on-die M3
> informs the secure firmware on the AP whether he should set the AP cpu
> to nonsecure or not before jumping to the kernel... basically it's
> decided at runtime and the same kernel binary serves in both modes.
>

OK that's fine as along as you assume that kernel *always* runs in
*non-secure* mode and never attempts any *secure access*.

>> 3. Why do you need this smc call for secondary boot only ?
>
> The call sets the secondary entry point stored in the secure sram.
>

So IIUC, you run Linux in non-secure mode, PSCI would be more suitable
than MCPM when you start thinking/implementing CPUIdle otherwise I think
you will end up duplicating some logic(last man and race management)
both in Linux as well as your secure firmware.

> The bootloader heuristic is if that's unset (0), and it's what the

This could be problem as when the CPU is hotplugged out, ideally it
should be set to 0 to avoid spurious wakeup and entry into Linux.
Yes MCPM does manage it, but IMO you are mixing up secure and non-secure
methods which might become issue later when implementing low power
CPU states.

> bootloader decided should be regarded as the primary cpu, then we do
> the real onetime cold boot flow, load the kernel etc.  Non-primary
> cpus wait at WFI in the bootloader.  When the primary cpu runs the
> code above, he sets the secondary entry point, and later starts to

I assume it's not done when primary boots, but by primary cpu when
bringing up the secondaries.

> bring up the other cores who jump to the secondary entry that was set.
>

I assume primary sends IPI to wake up secondaries, but if the SGIs are
configured as secure, then it will _not_ be delivered. If not it *might*
work but I can't understand the need of running Linux non-secure with
all secure access given to it.

Regards,
Sudeep

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-20 12:34     ` Vincent Yang
@ 2014-11-25 14:37         ` Sudeep Holla
  -1 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 14:37 UTC (permalink / raw)
  To: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Sudeep Holla, arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A,
	jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
	Tetsuya Nuriya



On 20/11/14 12:34, Vincent Yang wrote:
> Add driver for the ARM Message-Handling-Unit (MHU).
>
> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> ---
>   .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>   drivers/mailbox/Kconfig                            |   7 +
>   drivers/mailbox/Makefile                           |   2 +
>   drivers/mailbox/arm_mhu.c                          | 196 +++++++++++++++++++++
>   4 files changed, 238 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>   create mode 100644 drivers/mailbox/arm_mhu.c
>
> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> new file mode 100644
> index 0000000..b1b9888
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> @@ -0,0 +1,33 @@
> +ARM MHU Mailbox Driver
> +======================
> +
> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
> +3 independent channels/links to communicate with remote processor(s).

I had reviewed this before and I see not all the comments are addressed.
I had mentioned that you can't add support to _SECURE_ channel in Linux
as you need to assume Linux runs in non-secure privilege(and I gather
that's the case even on this platform from other email in the thread)

> + MHU links are hardwired on a platform. A link raises interrupt for any
> +received data. However, there is no specified way of knowing if the sent
> +data has been read by the remote. This driver assumes the sender polls
> +STAT register and the remote clears it after having read the data.

That could be design, interrupt support could be present on some
systems. The bindings should be flexible to add that support in future
if needed along with necessary code.

Regards,
Sudeep

--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-25 14:37         ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 14:37 UTC (permalink / raw)
  To: linux-arm-kernel



On 20/11/14 12:34, Vincent Yang wrote:
> Add driver for the ARM Message-Handling-Unit (MHU).
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>   .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>   drivers/mailbox/Kconfig                            |   7 +
>   drivers/mailbox/Makefile                           |   2 +
>   drivers/mailbox/arm_mhu.c                          | 196 +++++++++++++++++++++
>   4 files changed, 238 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>   create mode 100644 drivers/mailbox/arm_mhu.c
>
> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> new file mode 100644
> index 0000000..b1b9888
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> @@ -0,0 +1,33 @@
> +ARM MHU Mailbox Driver
> +======================
> +
> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
> +3 independent channels/links to communicate with remote processor(s).

I had reviewed this before and I see not all the comments are addressed.
I had mentioned that you can't add support to _SECURE_ channel in Linux
as you need to assume Linux runs in non-secure privilege(and I gather
that's the case even on this platform from other email in the thread)

> + MHU links are hardwired on a platform. A link raises interrupt for any
> +received data. However, there is no specified way of knowing if the sent
> +data has been read by the remote. This driver assumes the sender polls
> +STAT register and the remote clears it after having read the data.

That could be design, interrupt support could be present on some
systems. The bindings should be flexible to add that support in future
if needed along with necessary code.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 14:24       ` Sudeep Holla
@ 2014-11-25 16:43         ` Andy Green
  2014-11-25 17:00           ` Nicolas Pitre
  2014-11-25 17:39           ` Sudeep Holla
  0 siblings, 2 replies; 97+ messages in thread
From: Andy Green @ 2014-11-25 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 25 November 2014 at 22:24, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 25/11/14 13:42, Andy Green wrote:
>>
>> On 25 November 2014 at 19:48, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>> On 20/11/14 12:35, Vincent Yang wrote:
>>>>
>>>>
>>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>>
>>>
>>>> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
>>>> new file mode 100644
>>>> index 0000000..a14330b
>>>> --- /dev/null
>>>> +++ b/arch/arm/mach-mb86s7x/smc.S
>>>> @@ -0,0 +1,27 @@
>>>> +/*
>>>> + * SMC command interface to set secondary entry point
>>>> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
>>>> + * Copyright: (C) 2014 Linaro Ltd.
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + */
>>>> +
>>>> +#include <linux/linkage.h>
>>>> +
>>>> +.arch_extension sec
>>>> +
>>>> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
>>>> +ENTRY(mb86s7x_cpu_entry)
>>>> +       stmfd   sp!, {r1-r11, lr}
>>>> +       mov r1, r0
>>>> +       ldr r0, =1
>>>> +       mrc p15, 0, r3, c1, c0, 0
>>>> +       mov r4, r3
>>>> +       and r3, #0xbfffffff
>>>> +       mcr p15, 0, r3, c1, c0, 0
>>>> +       smc #0
>>>
>>>
>>>
>>> Interesting, it looks like you have some secure entity running on your
>>> platform.
>>
>>
>> Yes, we have a stub "secure firmware" that implements a few critical
>> functions to allow us to operate the kernel as nonsecure.  It's part
>> of the bootloader for this platform which is also GPL'd.
>>
>
> OK, thanks for clarifying.
>
>>> 1. While the CPU is powered down who is taking care of saving it's
>>>     state as you are doing it in the Linux itself ?
>>
>>
>> Nothing.  The secure firmware is in a bootloader that is copied to and
>> runs from secure sram.  When the cpu is reset, he comes back up in
>> secure mode and gets initialized in the secure firmware, before
>> entering Non-secure mode and the kernel's secondary entry point.
>>
>
> So you do have live secure firmware stub on secure sram at any time,
> right ? When the CPUs are powered down especially for low power states,
> how is the secure state of the CPUs preserved ?

There isn't any 'secure state' like you are thinking.

Our secure firmware is a rudimentary stub that provides a handful of
stateless secure services to the kernel.

There's nothing to save or restore.

>>> 2. Is Linux running in Secure or Non-secure mode ?
>>
>>
>> Another firmware (unfortunately not GPL) running on an on-die M3
>> informs the secure firmware on the AP whether he should set the AP cpu
>> to nonsecure or not before jumping to the kernel... basically it's
>> decided at runtime and the same kernel binary serves in both modes.
>>
>
> OK that's fine as along as you assume that kernel *always* runs in
> *non-secure* mode and never attempts any *secure access*.

Yes that's how it's set up.

When this M3 tells the bootloader to make us nonsecure before going to
the kernel, he marks up all the IPs that have dynamic access control
to allow access in nonsecure.  That's because we have complete BSP
support out of tree and we want to prove that it can all work from
nonsecure directly.

When Fujitsu want to restrict an IP from nonsecure access for a
particular customer they will add support to manage the IP either on
the M3 or the AP secure firmware and disable the IP support in DT.
But that does not exist yet.

>>> 3. Why do you need this smc call for secondary boot only ?
>>
>>
>> The call sets the secondary entry point stored in the secure sram.
>>
>
> So IIUC, you run Linux in non-secure mode, PSCI would be more suitable
> than MCPM when you start thinking/implementing CPUIdle otherwise I think
> you will end up duplicating some logic(last man and race management)
> both in Linux as well as your secure firmware.

As I mentioned our secure firmware is not what you're imagining.

MCPM works very well for us.  Are you saying we can't use MCPM and
must reimplement with PSCI on both sides?

>> The bootloader heuristic is if that's unset (0), and it's what the
>
>
> This could be problem as when the CPU is hotplugged out, ideally it
> should be set to 0 to avoid spurious wakeup and entry into Linux.

... I think you are talking about something else.

This is a PA stored in secure SRAM that holds the kernel's secondary
entry point.  It's 0 when the bootloader is copied to the secure SRAM
by the M3 at cold reset.  If anybody set it, it means Linux booted.

The M3 manages AP core state and either depowers the cluster or holds
them in reset. So there can be no 'spurious wakeup and entry into
Linux'.

> Yes MCPM does manage it, but IMO you are mixing up secure and non-secure
> methods which might become issue later when implementing low power
> CPU states.

Can you explain where you see the problem?  All we are doing is
storing the kernel secondary entry point.  The bootloader / secure
firmware always receives any started core first and decides when and
how to jump to it.

>> bootloader decided should be regarded as the primary cpu, then we do
>> the real onetime cold boot flow, load the kernel etc.  Non-primary
>> cpus wait at WFI in the bootloader.  When the primary cpu runs the
>> code above, he sets the secondary entry point, and later starts to
>
>
> I assume it's not done when primary boots, but by primary cpu when
> bringing up the secondaries.

Yes the point is the primary sets the secondary entry at the secure
firmware using the SMC and then the IPIs can start flying.

>> bring up the other cores who jump to the secondary entry that was set.
>>
>
> I assume primary sends IPI to wake up secondaries, but if the SGIs are
> configured as secure, then it will _not_ be delivered. If not it *might*

Well, it is coordinated between M3 and AP bootloader / secure firmware
if we should run nonsecure or not, and it configures a bunch of stuff
like GIC accordingly so it works.  And it does work.

> work but I can't understand the need of running Linux non-secure with
> all secure access given to it.

Fujitsu's goal with this was confirm the SoC + kernel can work in
nonsecure for the whole BSP stack.  Then as customers want particular
IPs secure-only, implement the behaviour they need in the AP secure
firmware or M3.  But as yet, no support for that is implemented.

-Andy

> Regards,
> Sudeep
>

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-25 14:37         ` Sudeep Holla
@ 2014-11-25 16:51             ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-25 16:51 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya

On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>
>
> On 20/11/14 12:34, Vincent Yang wrote:
>>
>> Add driver for the ARM Message-Handling-Unit (MHU).
>>
>> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
>> ---
>>   .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>   drivers/mailbox/Kconfig                            |   7 +
>>   drivers/mailbox/Makefile                           |   2 +
>>   drivers/mailbox/arm_mhu.c                          | 196
>> +++++++++++++++++++++
>>   4 files changed, 238 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>   create mode 100644 drivers/mailbox/arm_mhu.c
>>
>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> new file mode 100644
>> index 0000000..b1b9888
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> @@ -0,0 +1,33 @@
>> +ARM MHU Mailbox Driver
>> +======================
>> +
>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>> +3 independent channels/links to communicate with remote processor(s).
>
>
> I had reviewed this before and I see not all the comments are addressed.
> I had mentioned that you can't add support to _SECURE_ channel in Linux
> as you need to assume Linux runs in non-secure privilege(and I gather
> that's the case even on this platform from other email in the thread)
>
Please revisit the old thread. After some discussion you had
graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you
have valid reasons. In case you decide to support it ....
]
 It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform,
the DT will specify only some NS channel to be used. The controller
driver shouldn't be crippled just because you think Linux will never
be run in Secure mode.

Though I did forget to add .remove() function in case the driver is
used as a module. Will add that.

>> + MHU links are hardwired on a platform. A link raises interrupt for any
>> +received data. However, there is no specified way of knowing if the sent
>> +data has been read by the remote. This driver assumes the sender polls
>> +STAT register and the remote clears it after having read the data.
>
>
> That could be design, interrupt support could be present on some
> systems. The bindings should be flexible to add that support in future
> if needed along with necessary code.
>
We are the only 2 users of MHU atm and neither have that feature. I
even doubt if that is a configurable option. I stand corrected if you
share some spec telling otherwise because all I have is a few
snapshot'ed pages of MHU spec in a Japanese manual.  So please lets
keep things simple until we see real need for it.

Thanks
Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-25 16:51             ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-25 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 20/11/14 12:34, Vincent Yang wrote:
>>
>> Add driver for the ARM Message-Handling-Unit (MHU).
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> ---
>>   .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>   drivers/mailbox/Kconfig                            |   7 +
>>   drivers/mailbox/Makefile                           |   2 +
>>   drivers/mailbox/arm_mhu.c                          | 196
>> +++++++++++++++++++++
>>   4 files changed, 238 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>   create mode 100644 drivers/mailbox/arm_mhu.c
>>
>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> new file mode 100644
>> index 0000000..b1b9888
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>> @@ -0,0 +1,33 @@
>> +ARM MHU Mailbox Driver
>> +======================
>> +
>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>> +3 independent channels/links to communicate with remote processor(s).
>
>
> I had reviewed this before and I see not all the comments are addressed.
> I had mentioned that you can't add support to _SECURE_ channel in Linux
> as you need to assume Linux runs in non-secure privilege(and I gather
> that's the case even on this platform from other email in the thread)
>
Please revisit the old thread. After some discussion you had
graciously allowed me to keep the secure channel ;)
[
... Even though I don't like you have secure channel access in Linux, you
have valid reasons. In case you decide to support it ....
]
 It seems you still don't get my point that the driver should manage
all channels - S & NS. If Linux is running in NS mode on a platform,
the DT will specify only some NS channel to be used. The controller
driver shouldn't be crippled just because you think Linux will never
be run in Secure mode.

Though I did forget to add .remove() function in case the driver is
used as a module. Will add that.

>> + MHU links are hardwired on a platform. A link raises interrupt for any
>> +received data. However, there is no specified way of knowing if the sent
>> +data has been read by the remote. This driver assumes the sender polls
>> +STAT register and the remote clears it after having read the data.
>
>
> That could be design, interrupt support could be present on some
> systems. The bindings should be flexible to add that support in future
> if needed along with necessary code.
>
We are the only 2 users of MHU atm and neither have that feature. I
even doubt if that is a configurable option. I stand corrected if you
share some spec telling otherwise because all I have is a few
snapshot'ed pages of MHU spec in a Japanese manual.  So please lets
keep things simple until we see real need for it.

Thanks
Jassi

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 16:43         ` Andy Green
@ 2014-11-25 17:00           ` Nicolas Pitre
  2014-11-25 17:39           ` Sudeep Holla
  1 sibling, 0 replies; 97+ messages in thread
From: Nicolas Pitre @ 2014-11-25 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 26 Nov 2014, Andy Green wrote:

> On 25 November 2014 at 22:24, Sudeep Holla <sudeep.holla@arm.com> wrote:
> 
> > So IIUC, you run Linux in non-secure mode, PSCI would be more suitable
> > than MCPM when you start thinking/implementing CPUIdle otherwise I think
> > you will end up duplicating some logic(last man and race management)
> > both in Linux as well as your secure firmware.
> 
> As I mentioned our secure firmware is not what you're imagining.
> 
> MCPM works very well for us.  Are you saying we can't use MCPM and
> must reimplement with PSCI on both sides?

I said it many times before: not everyone is willing to invest in the 
complexity trap implied by the firmware model as proposed by ARM.  This 
is a concrete example of that.  MCPM-like functionality is an order of 
magnitude simpler to debug and maintain when implemented on the 
easily-replaceable kernel side.


Nicolas

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 16:43         ` Andy Green
  2014-11-25 17:00           ` Nicolas Pitre
@ 2014-11-25 17:39           ` Sudeep Holla
  2014-11-25 20:31             ` Andy Green
  1 sibling, 1 reply; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 17:39 UTC (permalink / raw)
  To: linux-arm-kernel



On 25/11/14 16:43, Andy Green wrote:
> On 25 November 2014 at 22:24, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>
>> On 25/11/14 13:42, Andy Green wrote:
>>>
>>> On 25 November 2014 at 19:48, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>
>>>> On 20/11/14 12:35, Vincent Yang wrote:
>>>>>
>>>>>
>>>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>>>
>>>>
>>>>> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
>>>>> new file mode 100644
>>>>> index 0000000..a14330b
>>>>> --- /dev/null
>>>>> +++ b/arch/arm/mach-mb86s7x/smc.S
>>>>> @@ -0,0 +1,27 @@
>>>>> +/*
>>>>> + * SMC command interface to set secondary entry point
>>>>> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
>>>>> + * Copyright: (C) 2014 Linaro Ltd.
>>>>> + *
>>>>> + * This program is free software; you can redistribute it and/or modify
>>>>> + * it under the terms of the GNU General Public License version 2 as
>>>>> + * published by the Free Software Foundation.
>>>>> + */
>>>>> +
>>>>> +#include <linux/linkage.h>
>>>>> +
>>>>> +.arch_extension sec
>>>>> +
>>>>> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
>>>>> +ENTRY(mb86s7x_cpu_entry)
>>>>> +       stmfd   sp!, {r1-r11, lr}
>>>>> +       mov r1, r0
>>>>> +       ldr r0, =1
>>>>> +       mrc p15, 0, r3, c1, c0, 0
>>>>> +       mov r4, r3
>>>>> +       and r3, #0xbfffffff
>>>>> +       mcr p15, 0, r3, c1, c0, 0
>>>>> +       smc #0
>>>>
>>>>
>>>>
>>>> Interesting, it looks like you have some secure entity running on your
>>>> platform.
>>>
>>>
>>> Yes, we have a stub "secure firmware" that implements a few critical
>>> functions to allow us to operate the kernel as nonsecure.  It's part
>>> of the bootloader for this platform which is also GPL'd.
>>>
>>
>> OK, thanks for clarifying.
>>
>>>> 1. While the CPU is powered down who is taking care of saving it's
>>>>      state as you are doing it in the Linux itself ?
>>>
>>>
>>> Nothing.  The secure firmware is in a bootloader that is copied to and
>>> runs from secure sram.  When the cpu is reset, he comes back up in
>>> secure mode and gets initialized in the secure firmware, before
>>> entering Non-secure mode and the kernel's secondary entry point.
>>>
>>
>> So you do have live secure firmware stub on secure sram at any time,
>> right ? When the CPUs are powered down especially for low power states,
>> how is the secure state of the CPUs preserved ?
>
> There isn't any 'secure state' like you are thinking.
>
> Our secure firmware is a rudimentary stub that provides a handful of
> stateless secure services to the kernel.
>
> There's nothing to save or restore.
>

Ok that clarifies, but I assume some customers would like to extend that
beyond the stub.

>>>> 2. Is Linux running in Secure or Non-secure mode ?
>>>
>>>
>>> Another firmware (unfortunately not GPL) running on an on-die M3
>>> informs the secure firmware on the AP whether he should set the AP cpu
>>> to nonsecure or not before jumping to the kernel... basically it's
>>> decided at runtime and the same kernel binary serves in both modes.
>>>
>>
>> OK that's fine as along as you assume that kernel *always* runs in
>> *non-secure* mode and never attempts any *secure access*.
>
> Yes that's how it's set up.
>
> When this M3 tells the bootloader to make us nonsecure before going to
> the kernel, he marks up all the IPs that have dynamic access control
> to allow access in nonsecure.  That's because we have complete BSP
> support out of tree and we want to prove that it can all work from
> nonsecure directly.
>
> When Fujitsu want to restrict an IP from nonsecure access for a
> particular customer they will add support to manage the IP either on
> the M3 or the AP secure firmware and disable the IP support in DT.
> But that does not exist yet.
>

Yes this was what I was trying to tell. From what I understand now, if
the customer implements secure firmware which might need to save and
restore the state, then he needs to manage.(He might end up with
duplication of this last man algorithm in the secure firmware too,
I was just trying to mention this)

>>>> 3. Why do you need this smc call for secondary boot only ?
>>>
>>>
>>> The call sets the secondary entry point stored in the secure sram.
>>>
>>
>> So IIUC, you run Linux in non-secure mode, PSCI would be more suitable
>> than MCPM when you start thinking/implementing CPUIdle otherwise I think
>> you will end up duplicating some logic(last man and race management)
>> both in Linux as well as your secure firmware.
>
> As I mentioned our secure firmware is not what you're imagining.
>

Understood, that?s about the current stub secure firmware and I was
talking about non-existent full blown secure firmware. If that's not the
case, then it's fine.

> MCPM works very well for us.  Are you saying we can't use MCPM and
> must reimplement with PSCI on both sides?
>

No I never said that, I wanted to understand what's the scope of your
or any secure firmware of your customer.

>>> The bootloader heuristic is if that's unset (0), and it's what the
>>
>>
>> This could be problem as when the CPU is hotplugged out, ideally it
>> should be set to 0 to avoid spurious wakeup and entry into Linux.
>
> ... I think you are talking about something else.
>
> This is a PA stored in secure SRAM that holds the kernel's secondary
> entry point.  It's 0 when the bootloader is copied to the secure SRAM
> by the M3 at cold reset.  If anybody set it, it means Linux booted.
>
> The M3 manages AP core state and either depowers the cluster or holds
> them in reset. So there can be no 'spurious wakeup and entry into
> Linux'.
>

Ok, good that you can guarantee that.

>> Yes MCPM does manage it, but IMO you are mixing up secure and non-secure
>> methods which might become issue later when implementing low power
>> CPU states.
>
> Can you explain where you see the problem?  All we are doing is
> storing the kernel secondary entry point.  The bootloader / secure
> firmware always receives any started core first and decides when and
> how to jump to it.
>
>>> bootloader decided should be regarded as the primary cpu, then we do
>>> the real onetime cold boot flow, load the kernel etc.  Non-primary
>>> cpus wait at WFI in the bootloader.  When the primary cpu runs the
>>> code above, he sets the secondary entry point, and later starts to
>>
>>
>> I assume it's not done when primary boots, but by primary cpu when
>> bringing up the secondaries.
>
> Yes the point is the primary sets the secondary entry at the secure
> firmware using the SMC and then the IPIs can start flying.
>

Only if GIC is properly configured for that though I don't see the point
in giving non-secure entity secure access. If any secure firmware wants
to change that in future that could be issue.

>>> bring up the other cores who jump to the secondary entry that was set.
>>>
>>
>> I assume primary sends IPI to wake up secondaries, but if the SGIs are
>> configured as secure, then it will _not_ be delivered. If not it *might*
>
> Well, it is coordinated between M3 and AP bootloader / secure firmware
> if we should run nonsecure or not, and it configures a bunch of stuff
> like GIC accordingly so it works.  And it does work.
>
>> work but I can't understand the need of running Linux non-secure with
>> all secure access given to it.
>
> Fujitsu's goal with this was confirm the SoC + kernel can work in
> nonsecure for the whole BSP stack.  Then as customers want particular
> IPs secure-only, implement the behaviour they need in the AP secure
> firmware or M3.  But as yet, no support for that is implemented.
>

I never said you *must implement* PSCI and *not use* MCPM. Since you 
mentioned that you will be providing option to run Linux in non-secure 
mode, which means there can be _secure_entity_ which does more than your
current stub, I just wanted to mention the possible issues you may need 
to resolve then.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-20 12:35 ` [PATCH 3/9] ARM: MB86S7X: Add MCPM support Vincent Yang
  2014-11-21 13:02   ` Arnd Bergmann
  2014-11-25 11:48   ` Sudeep Holla
@ 2014-11-25 17:42   ` Nicolas Pitre
  2014-11-25 18:06     ` Sudeep Holla
                       ` (2 more replies)
  2 siblings, 3 replies; 97+ messages in thread
From: Nicolas Pitre @ 2014-11-25 17:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 20 Nov 2014, Vincent Yang wrote:

> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> CPU/CLUSTER power up/down done by SCB over mailbox.
> 
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>  arch/arm/mach-mb86s7x/Makefile |   2 +-
>  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>  3 files changed, 388 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>  create mode 100644 arch/arm/mach-mb86s7x/smc.S
> 
> diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
> index 97640b6..b0fa34b 100644
> --- a/arch/arm/mach-mb86s7x/Makefile
> +++ b/arch/arm/mach-mb86s7x/Makefile
> @@ -1 +1 @@
> -obj-$(CONFIG_ARCH_MB86S7X)	+= board.o
> +obj-$(CONFIG_ARCH_MB86S7X)	+= board.o mcpm.o smc.o
> diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
> new file mode 100644
> index 0000000..bf1b50a
> --- /dev/null
> +++ b/arch/arm/mach-mb86s7x/mcpm.c
> @@ -0,0 +1,360 @@
> +/*
> + * arch/arm/mach-mb86s7x/mcpm.c
> + * Copyright:	(C) 2013-2014 Fujitsu Semiconductor Limited
> + * Copyright:	(C) 2014 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/pm.h>
> +#include <linux/delay.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/arm-cci.h>
> +#include <linux/spinlock.h>
> +#include <linux/suspend.h>
> +#include <linux/of_device.h>
> +#include <linux/irqchip/arm-gic.h>
> +#include <linux/platform_device.h>
> +
> +#include <soc/mb86s7x/scb_mhu.h>
> +
> +#include <asm/mcpm.h>
> +#include <asm/cp15.h>
> +#include <asm/cputype.h>
> +#include <asm/suspend.h>
> +#include <asm/idmap.h>
> +
> +#define S7X_MAX_CLUSTER	2
> +#define S7X_MAX_CPU	2
> +
> +#define MHU_SHM_OFFSET		0x3800
> +#define WFI_COLOR_OFFSET	0x3f00
> +#define TRAMPOLINE_OFFSET	0x3c00
> +#define RESET_OFFSET		(TRAMPOLINE_OFFSET + 0x3fc)
> +
> +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
> +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
> +extern void __iomem *mb86s7x_shm_base;
> +
> +#define AT_WFI_DO_NOTHING	0x0
> +#define AT_WFI_DO_SUSPEND	0x1
> +#define AT_WFI_DO_POWEROFF	0x2
> +#define AT_WFI_COLOR_MASK	0x3
> +
> +struct mb86s7x_cpu_gate {
> +	u32 payload_size;
> +	u32 cluster_class;
> +	u32 cluster_id;
> +	u32 cpu_id;
> +#define SCB_CPU_STATE_OFF	0x0
> +#define SCB_CPU_STATE_ON	0x1
> +#define SCB_CPU_STATE_SUSP	0x2
> +	u32 cpu_state;
> +};
> +
> +asmlinkage void mb86s70evb_outer_flush_all(void)
> +{
> +	outer_flush_all();
> +}
> +
> +#define mb86s70evb_exit_coherency_flush(level) { \
> +	asm volatile( \
> +	"stmfd	sp!, {fp, ip}\n\t" \
> +	"mrc	p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> +	"bic	r0, r0, #"__stringify(CR_C)"\n\t" \
> +	"mcr	p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> +	"isb\n\t" \
> +	"bl	v7_flush_dcache_"__stringify(level)"\n\t" \
> +	"bl	mb86s70evb_outer_flush_all\n\t" \

This is wrong.  As mentioned already, this unconditionally flushes L2 in 
all cases which shouldn't be necessary in the "louis" case.

Furthermore, the safety of this macro is ensured by not having any 
memory writes in the middle of the whole sequence.  By calling 
mb86s70evb_outer_flush_all() there could be the return address pushed 
onto the stack before calling outer_flush_all() if some tail call 
optimization is not applied.  And this is without saying what 
outer_flush_all() actually does.

Why can't you simply do this instead:

	v7_exit_coherency_flush(all);
	outer_flush_all();

Of course you'll have to audit everything in the outer_flush_all() path 
to make sure no atomic instructions such as LDREX/STREX are invoked.  
Those have undefined behavior after CR_C is cleared.

> +	"mrc	p15, 0, r0, c1, c0, 1   @ get ACTLR\n\t" \
> +	"bic	r0, r0, #(1 << 6)       @ disable local coherency\n\t" \
> +	"mcr	p15, 0, r0, c1, c0, 1   @ set ACTLR\n\t" \
> +	"isb\n\t" \
> +	"dsb\n\t" \
> +	"ldmfd	sp!, {fp, ip}" \
> +		: : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
> +		"r9", "r10", "lr", "memory"); \
> +	}
> +
> +static void
> +mb86s7x_set_wficolor(unsigned clstr, unsigned cpu, unsigned clr)
> +{
> +	u8 val;
> +
> +	if (clr & ~AT_WFI_COLOR_MASK)
> +		return;

Shouldn't this be a BUG() rather than a return?

> +
> +	val = readb_relaxed(mb86s7x_shm_base
> +			    + WFI_COLOR_OFFSET + clstr * 2 + cpu);
> +	val &= ~AT_WFI_COLOR_MASK;
> +	val |= clr;
> +	writeb_relaxed(val, mb86s7x_shm_base
> +		       + WFI_COLOR_OFFSET + clstr * 2 + cpu);
> +}
> +
> +static int mb86s7x_pm_power_up(unsigned int cpu, unsigned int cluster)
> +{
> +	int ret = 0;
> +
> +	if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
> +		return -EINVAL;
> +
> +	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
> +
> +	local_irq_disable();
> +	arch_spin_lock(&mb86s7x_pm_lock);
> +
> +	mb86s7x_pm_use_count[cluster][cpu]++;
> +
> +	if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
> +		struct mb86s7x_cpu_gate cmd;
> +
> +		arch_spin_unlock(&mb86s7x_pm_lock);
> +		local_irq_enable();

>From that point onward, nothing prevents concurrent execution in 
mb86s7x_pm_suspend() racing to call mb86s7x_set_wficolor() resulting in 
an incoherent state depending on who wins the race.

> +		cmd.payload_size = sizeof(cmd);
> +		cmd.cluster_class = 0;
> +		cmd.cluster_id = cluster;
> +		cmd.cpu_id = cpu;
> +		cmd.cpu_state = SCB_CPU_STATE_ON;
> +
> +		pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
> +			 __func__, __LINE__, cmd.cluster_class,
> +			 cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
> +
> +		mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
> +		ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_SET_REQ,
> +					  &cmd, sizeof(cmd));
> +		if (ret < 0) {
> +			pr_err("%s:%d failed!\n", __func__, __LINE__);
> +			return ret;
> +		}
> +
> +		pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
> +			 __func__, __LINE__, cmd.cluster_class,
> +			 cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
> +
> +		if (cmd.cpu_state != SCB_CPU_STATE_ON)
> +			return -ENODEV;
> +	} else if (mb86s7x_pm_use_count[cluster][cpu] != 2) {
> +		/*
> +		 * The only possible values are:
> +		 * 0 = CPU down
> +		 * 1 = CPU (still) up
> +		 * 2 = CPU requested to be up before it had a chance
> +		 *     to actually make itself down.
> +		 * Any other value is a bug.
> +		 */
> +		BUG();
> +	}
> +
> +	return 0;
> +}
> +
> +static void mb86s7x_pm_suspend(u64 ignored)
> +{
> +	unsigned int mpidr, cpu, cluster;
> +	bool last_man = false, skip_wfi = false;
> +
> +	mpidr = read_cpuid_mpidr();
> +	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> +	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> +
> +	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
> +	__mcpm_cpu_going_down(cpu, cluster);
> +
> +	arch_spin_lock(&mb86s7x_pm_lock);
> +	BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
> +
> +	mb86s7x_pm_use_count[cluster][cpu]--;
> +
> +	if (mb86s7x_pm_use_count[cluster][cpu] == 0) {
> +		if (!mb86s7x_pm_use_count[cluster][0] &&
> +		    !mb86s7x_pm_use_count[cluster][1])
> +			last_man = true;
> +		mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_POWEROFF);
> +	} else if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
> +		skip_wfi = true; /* Overtaken by a power up */
> +	} else {
> +		BUG();
> +	}
> +
> +	if (!skip_wfi)
> +		gic_cpu_if_down();
> +
> +	if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
> +		arch_spin_unlock(&mb86s7x_pm_lock);
> +
> +		if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
> +			/*
> +			 * On the Cortex-A15 we need to disable
> +			 * L2 prefetching before flushing the cache.
> +			 */
> +			asm volatile(
> +			"mcr p15, 1, %0, c15, c0, 3\n\t"
> +			"isb\n\t"
> +			"dsb"
> +			: : "r" (0x400));
> +		}
> +
> +		mb86s70evb_exit_coherency_flush(all);
> +
> +		cci_disable_port_by_cpu(mpidr);
> +
> +		__mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
> +	} else {
> +		arch_spin_unlock(&mb86s7x_pm_lock);
> +		mb86s70evb_exit_coherency_flush(louis);
> +	}
> +
> +	__mcpm_cpu_down(cpu, cluster);
> +
> +	/* Now we are prepared for power-down, do it: */
> +	if (!skip_wfi)
> +		wfi();
> +}
> +
> +static void mb86s7x_pm_power_down(void)
> +{
> +	mb86s7x_pm_suspend(0);
> +}
> +
> +static int mb86s7x_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
> +{
> +	struct mb86s7x_cpu_gate cmd;
> +	int i, ret;
> +
> +	if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
> +		return 0;

This should return an error or BUG().

> +	cmd.payload_size = sizeof(cmd);
> +	cmd.cluster_class = 0;
> +	cmd.cluster_id = cluster;
> +	cmd.cpu_id = cpu;
> +	cmd.cpu_state = SCB_CPU_STATE_ON;
> +
> +	for (i = 0; i < 50; i++) {
> +		ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_GET_REQ,
> +					  &cmd, sizeof(cmd));
> +		if (ret < 0) {
> +			pr_err("%s:%d failed to get CPU status\n",
> +			       __func__, __LINE__);
> +			return ret;
> +		}
> +
> +		pr_debug("%s:%d Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u\n",
> +			 __func__, __LINE__,
> +			 cmd.cluster_class, cmd.cluster_id,
> +			 cmd.cpu_id, cmd.cpu_state);
> +
> +		if (cmd.cpu_state == SCB_CPU_STATE_OFF)
> +			return 0;
> +
> +		msleep(20);
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static void mb86s7x_pm_powered_up(void)
> +{
> +	unsigned int mpidr, cpu, cluster;
> +
> +	mpidr = read_cpuid_mpidr();
> +	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> +	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> +
> +	arch_spin_lock(&mb86s7x_pm_lock);
> +	if (!mb86s7x_pm_use_count[cluster][cpu])
> +		mb86s7x_pm_use_count[cluster][cpu] = 1;
> +	arch_spin_unlock(&mb86s7x_pm_lock);
> +}
> +
> +static const struct mcpm_platform_ops mb86s7x_pm_power_ops = {
> +	.power_up		= mb86s7x_pm_power_up,
> +	.power_down		= mb86s7x_pm_power_down,
> +	.wait_for_powerdown	= mb86s7x_wait_for_powerdown,
> +	.suspend		= mb86s7x_pm_suspend,
> +	.powered_up		= mb86s7x_pm_powered_up,
> +};
> +
> +/*
> + * Enable cluster-level coherency, in preparation for turning on the MMU.
> + */
> +static void __naked mb86s7x_pm_power_up_setup(unsigned int affinity_level)
> +{
> +	asm volatile ("\n"
> +"	cmp	r0, #1\n"
> +"	bxne	lr\n"
> +"	b	cci_enable_port_for_self");
> +}
> +
> +static void __init mb86s7x_cache_off(void)
> +{
> +	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
> +		/* disable L2 prefetching on the Cortex-A15 */
> +		asm volatile(
> +		"mcr	p15, 1, %0, c15, c0, 3\n\t"
> +		"isb\n\t"
> +		"dsb"
> +		: : "r" (0x400));
> +	}
> +	mb86s70evb_exit_coherency_flush(all);
> +}
> +
> +struct mb86s7x_scb_version {
> +	u32 payload_size;
> +	u32 version;
> +	u32 config_version;
> +};
> +
> +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);
> +
> +static int __init mb86s7x_mcpm_init(void)
> +{
> +	unsigned int mpidr, cpu, cluster;
> +	struct mb86s7x_scb_version cmd;
> +	int ret;
> +
> +	if (!cci_probed())
> +		return -ENODEV;
> +
> +	mpidr = read_cpuid_mpidr();
> +	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> +	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> +
> +	pr_info("Booting on cpu_%u cluster_%u\n", cpu, cluster);
> +	mb86s7x_pm_use_count[cluster][cpu] = 1;
> +
> +	/* reset the wfi 'color' for primary cpu */
> +	mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
> +
> +	/* Do SMC to set entry address for CPUs coming online */
> +	mb86s7x_cpu_entry(virt_to_phys(mcpm_entry_point));
> +
> +	cmd.payload_size = sizeof(cmd);
> +	cmd.version = 0;
> +	cmd.config_version = 0;
> +	ret = mb86s7x_send_packet(CMD_SCB_CAPABILITY_GET_REQ,
> +				  &cmd, sizeof(cmd));
> +	if (ret < 0)
> +		pr_err("%s:%d failed to get SCB version\n",
> +		       __func__, __LINE__);
> +
> +	pr_info("MB86S7x MCPM initialized: SCB version 0x%x:0x%x\n",
> +		cmd.version, cmd.config_version);
> +
> +	ret = mcpm_platform_register(&mb86s7x_pm_power_ops);
> +	if (!ret)
> +		ret = mcpm_sync_init(mb86s7x_pm_power_up_setup);
> +	if (!ret)
> +		ret = mcpm_loopback(mb86s7x_cache_off); /* turn on the CCI */
> +	mcpm_smp_set_ops();
> +
> +	return ret;
> +}
> +early_initcall(mb86s7x_mcpm_init);
> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
> new file mode 100644
> index 0000000..a14330b
> --- /dev/null
> +++ b/arch/arm/mach-mb86s7x/smc.S
> @@ -0,0 +1,27 @@
> +/*
> + * SMC command interface to set secondary entry point
> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
> + * Copyright: (C) 2014 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/linkage.h>
> +
> +.arch_extension sec
> +
> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
> +ENTRY(mb86s7x_cpu_entry)
> +	stmfd   sp!, {r1-r11, lr}
> +	mov r1, r0
> +	ldr r0, =1
> +	mrc p15, 0, r3, c1, c0, 0
> +	mov r4, r3
> +	and r3, #0xbfffffff
> +	mcr p15, 0, r3, c1, c0, 0
> +	smc #0
> +	mcr p15, 0, r4, c1, c0, 0
> +	ldmfd   sp!, {r1-r11, pc}
> +ENDPROC(mb86s7x_cpu_entry)
> -- 
> 1.9.0
> 
> 

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-25 16:51             ` Jassi Brar
@ 2014-11-25 18:01                 ` Sudeep Holla
  -1 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 18:01 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Sudeep Holla, Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya



On 25/11/14 16:51, Jassi Brar wrote:
> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>
>>
>> On 20/11/14 12:34, Vincent Yang wrote:
>>>
>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>
>>> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
>>> ---
>>>    .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>    drivers/mailbox/Kconfig                            |   7 +
>>>    drivers/mailbox/Makefile                           |   2 +
>>>    drivers/mailbox/arm_mhu.c                          | 196
>>> +++++++++++++++++++++
>>>    4 files changed, 238 insertions(+)
>>>    create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>    create mode 100644 drivers/mailbox/arm_mhu.c
>>>
>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> new file mode 100644
>>> index 0000000..b1b9888
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> @@ -0,0 +1,33 @@
>>> +ARM MHU Mailbox Driver
>>> +======================
>>> +
>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>> +3 independent channels/links to communicate with remote processor(s).
>>
>>
>> I had reviewed this before and I see not all the comments are addressed.
>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>> as you need to assume Linux runs in non-secure privilege(and I gather
>> that's the case even on this platform from other email in the thread)
>>
> Please revisit the old thread. After some discussion you had
> graciously allowed me to keep the secure channel ;)
> [
> ... Even though I don't like you have secure channel access in Linux, you
> have valid reasons. In case you decide to support it ....
> ]

Agreed but based on the other email in the same thread it looks like you
want to run the same kernel both in secure and no-secure mode on this
platform, in which case you _have_to_assume_ it's *non-secure only* 
always unless you come up with some DT magic.

>   It seems you still don't get my point that the driver should manage
> all channels - S & NS. If Linux is running in NS mode on a platform,
> the DT will specify only some NS channel to be used. The controller
> driver shouldn't be crippled just because you think Linux will never
> be run in Secure mode.
>

Ok how do you handle that, I don't see that in the DT binding. As it
stands, you can unconditionally try to access the secure channel and
cause aborts if the platform is running in non-secure mode.

Regards,
Sudeep

--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-25 18:01                 ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 18:01 UTC (permalink / raw)
  To: linux-arm-kernel



On 25/11/14 16:51, Jassi Brar wrote:
> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>
>> On 20/11/14 12:34, Vincent Yang wrote:
>>>
>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>
>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>>> ---
>>>    .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>    drivers/mailbox/Kconfig                            |   7 +
>>>    drivers/mailbox/Makefile                           |   2 +
>>>    drivers/mailbox/arm_mhu.c                          | 196
>>> +++++++++++++++++++++
>>>    4 files changed, 238 insertions(+)
>>>    create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>    create mode 100644 drivers/mailbox/arm_mhu.c
>>>
>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> new file mode 100644
>>> index 0000000..b1b9888
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>> @@ -0,0 +1,33 @@
>>> +ARM MHU Mailbox Driver
>>> +======================
>>> +
>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>> +3 independent channels/links to communicate with remote processor(s).
>>
>>
>> I had reviewed this before and I see not all the comments are addressed.
>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>> as you need to assume Linux runs in non-secure privilege(and I gather
>> that's the case even on this platform from other email in the thread)
>>
> Please revisit the old thread. After some discussion you had
> graciously allowed me to keep the secure channel ;)
> [
> ... Even though I don't like you have secure channel access in Linux, you
> have valid reasons. In case you decide to support it ....
> ]

Agreed but based on the other email in the same thread it looks like you
want to run the same kernel both in secure and no-secure mode on this
platform, in which case you _have_to_assume_ it's *non-secure only* 
always unless you come up with some DT magic.

>   It seems you still don't get my point that the driver should manage
> all channels - S & NS. If Linux is running in NS mode on a platform,
> the DT will specify only some NS channel to be used. The controller
> driver shouldn't be crippled just because you think Linux will never
> be run in Secure mode.
>

Ok how do you handle that, I don't see that in the DT binding. As it
stands, you can unconditionally try to access the secure channel and
cause aborts if the platform is running in non-secure mode.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 17:42   ` Nicolas Pitre
@ 2014-11-25 18:06     ` Sudeep Holla
  2014-11-25 18:55       ` Nicolas Pitre
  2014-11-25 18:46     ` Lorenzo Pieralisi
  2014-11-27  4:59     ` Jassi Brar
  2 siblings, 1 reply; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 18:06 UTC (permalink / raw)
  To: linux-arm-kernel



On 25/11/14 17:42, Nicolas Pitre wrote:
> On Thu, 20 Nov 2014, Vincent Yang wrote:
>
>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> ---
>>   arch/arm/mach-mb86s7x/Makefile |   2 +-
>>   arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>>   arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>>   3 files changed, 388 insertions(+), 1 deletion(-)
>>   create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>>   create mode 100644 arch/arm/mach-mb86s7x/smc.S
>>
>> diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
>> index 97640b6..b0fa34b 100644
>> --- a/arch/arm/mach-mb86s7x/Makefile
>> +++ b/arch/arm/mach-mb86s7x/Makefile
>> @@ -1 +1 @@
>> -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
>> +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
>> diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
>> new file mode 100644
>> index 0000000..bf1b50a
>> --- /dev/null
>> +++ b/arch/arm/mach-mb86s7x/mcpm.c
>> @@ -0,0 +1,360 @@
>> +/*
>> + * arch/arm/mach-mb86s7x/mcpm.c
>> + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
>> + * Copyright:        (C) 2014 Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/pm.h>
>> +#include <linux/delay.h>
>> +#include <linux/cpu_pm.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/arm-cci.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/suspend.h>
>> +#include <linux/of_device.h>
>> +#include <linux/irqchip/arm-gic.h>
>> +#include <linux/platform_device.h>
>> +
>> +#include <soc/mb86s7x/scb_mhu.h>
>> +
>> +#include <asm/mcpm.h>
>> +#include <asm/cp15.h>
>> +#include <asm/cputype.h>
>> +#include <asm/suspend.h>
>> +#include <asm/idmap.h>
>> +
>> +#define S7X_MAX_CLUSTER      2
>> +#define S7X_MAX_CPU  2
>> +
>> +#define MHU_SHM_OFFSET               0x3800
>> +#define WFI_COLOR_OFFSET     0x3f00
>> +#define TRAMPOLINE_OFFSET    0x3c00
>> +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
>> +
>> +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
>> +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
>> +extern void __iomem *mb86s7x_shm_base;
>> +
>> +#define AT_WFI_DO_NOTHING    0x0
>> +#define AT_WFI_DO_SUSPEND    0x1
>> +#define AT_WFI_DO_POWEROFF   0x2
>> +#define AT_WFI_COLOR_MASK    0x3
>> +
>> +struct mb86s7x_cpu_gate {
>> +     u32 payload_size;
>> +     u32 cluster_class;
>> +     u32 cluster_id;
>> +     u32 cpu_id;
>> +#define SCB_CPU_STATE_OFF    0x0
>> +#define SCB_CPU_STATE_ON     0x1
>> +#define SCB_CPU_STATE_SUSP   0x2
>> +     u32 cpu_state;
>> +};
>> +
>> +asmlinkage void mb86s70evb_outer_flush_all(void)
>> +{
>> +     outer_flush_all();
>> +}
>> +
>> +#define mb86s70evb_exit_coherency_flush(level) { \
>> +     asm volatile( \
>> +     "stmfd  sp!, {fp, ip}\n\t" \
>> +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
>> +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
>> +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
>> +     "isb\n\t" \
>> +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
>> +     "bl     mb86s70evb_outer_flush_all\n\t" \
>
> This is wrong.  As mentioned already, this unconditionally flushes L2 in
> all cases which shouldn't be necessary in the "louis" case.
>

IIUC the external/outer cache needs to be flushed only if it's last
cluster going down. It would be suboptimal to flush it when one cluster
is going down while other is still active. So it's not always correct
for even "all" case too.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 17:42   ` Nicolas Pitre
  2014-11-25 18:06     ` Sudeep Holla
@ 2014-11-25 18:46     ` Lorenzo Pieralisi
  2014-11-25 18:59       ` Nicolas Pitre
  2014-11-26 16:29       ` Jassi Brar
  2014-11-27  4:59     ` Jassi Brar
  2 siblings, 2 replies; 97+ messages in thread
From: Lorenzo Pieralisi @ 2014-11-25 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 25, 2014 at 05:42:32PM +0000, Nicolas Pitre wrote:
> On Thu, 20 Nov 2014, Vincent Yang wrote:
> 
> > The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> > CPU/CLUSTER power up/down done by SCB over mailbox.
> >
> > Signed-off-by: Andy Green <andy.green@linaro.org>
> > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> > Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> > ---
> >  arch/arm/mach-mb86s7x/Makefile |   2 +-
> >  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
> >  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
> >  3 files changed, 388 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
> >  create mode 100644 arch/arm/mach-mb86s7x/smc.S
> >
> > diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
> > index 97640b6..b0fa34b 100644
> > --- a/arch/arm/mach-mb86s7x/Makefile
> > +++ b/arch/arm/mach-mb86s7x/Makefile
> > @@ -1 +1 @@
> > -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
> > +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
> > diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
> > new file mode 100644
> > index 0000000..bf1b50a
> > --- /dev/null
> > +++ b/arch/arm/mach-mb86s7x/mcpm.c
> > @@ -0,0 +1,360 @@
> > +/*
> > + * arch/arm/mach-mb86s7x/mcpm.c
> > + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
> > + * Copyright:        (C) 2014 Linaro Ltd.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/io.h>
> > +#include <linux/pm.h>
> > +#include <linux/delay.h>
> > +#include <linux/cpu_pm.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/arm-cci.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/suspend.h>
> > +#include <linux/of_device.h>
> > +#include <linux/irqchip/arm-gic.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include <soc/mb86s7x/scb_mhu.h>
> > +
> > +#include <asm/mcpm.h>
> > +#include <asm/cp15.h>
> > +#include <asm/cputype.h>
> > +#include <asm/suspend.h>
> > +#include <asm/idmap.h>
> > +
> > +#define S7X_MAX_CLUSTER      2
> > +#define S7X_MAX_CPU  2
> > +
> > +#define MHU_SHM_OFFSET               0x3800
> > +#define WFI_COLOR_OFFSET     0x3f00
> > +#define TRAMPOLINE_OFFSET    0x3c00
> > +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
> > +
> > +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
> > +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
> > +extern void __iomem *mb86s7x_shm_base;
> > +
> > +#define AT_WFI_DO_NOTHING    0x0
> > +#define AT_WFI_DO_SUSPEND    0x1
> > +#define AT_WFI_DO_POWEROFF   0x2
> > +#define AT_WFI_COLOR_MASK    0x3
> > +
> > +struct mb86s7x_cpu_gate {
> > +     u32 payload_size;
> > +     u32 cluster_class;
> > +     u32 cluster_id;
> > +     u32 cpu_id;
> > +#define SCB_CPU_STATE_OFF    0x0
> > +#define SCB_CPU_STATE_ON     0x1
> > +#define SCB_CPU_STATE_SUSP   0x2
> > +     u32 cpu_state;
> > +};
> > +
> > +asmlinkage void mb86s70evb_outer_flush_all(void)
> > +{
> > +     outer_flush_all();
> > +}
> > +
> > +#define mb86s70evb_exit_coherency_flush(level) { \
> > +     asm volatile( \
> > +     "stmfd  sp!, {fp, ip}\n\t" \
> > +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> > +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
> > +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> > +     "isb\n\t" \
> > +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
> > +     "bl     mb86s70evb_outer_flush_all\n\t" \
> 
> This is wrong.  As mentioned already, this unconditionally flushes L2 in
> all cases which shouldn't be necessary in the "louis" case.

Is this a bL system with unified and architected L2s ? I think so, so
what's the outercache for ?

> Furthermore, the safety of this macro is ensured by not having any
> memory writes in the middle of the whole sequence.  By calling
> mb86s70evb_outer_flush_all() there could be the return address pushed
> onto the stack before calling outer_flush_all() if some tail call
> optimization is not applied.  And this is without saying what
> outer_flush_all() actually does.
> 
> Why can't you simply do this instead:
> 
>         v7_exit_coherency_flush(all);
>         outer_flush_all();
> 
> Of course you'll have to audit everything in the outer_flush_all() path
> to make sure no atomic instructions such as LDREX/STREX are invoked.
> Those have undefined behavior after CR_C is cleared.

What you are saying is correct but first of all I would like to
understand what outercache we are talking about here.

Code snippet above is fragile, as you said, and I'd rather disable
the outercache before executing the power down sequence (which implies
cache is cleaned/invalidated and quiescent before we clear the C bit)
if there is an outercache to be managed.

Waiting in trepidation :)

Lorenzo

> 
> > +     "mrc    p15, 0, r0, c1, c0, 1   @ get ACTLR\n\t" \
> > +     "bic    r0, r0, #(1 << 6)       @ disable local coherency\n\t" \
> > +     "mcr    p15, 0, r0, c1, c0, 1   @ set ACTLR\n\t" \
> > +     "isb\n\t" \
> > +     "dsb\n\t" \
> > +     "ldmfd  sp!, {fp, ip}" \
> > +             : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
> > +             "r9", "r10", "lr", "memory"); \
> > +     }
> > +
> > +static void
> > +mb86s7x_set_wficolor(unsigned clstr, unsigned cpu, unsigned clr)
> > +{
> > +     u8 val;
> > +
> > +     if (clr & ~AT_WFI_COLOR_MASK)
> > +             return;
> 
> Shouldn't this be a BUG() rather than a return?
> 
> > +
> > +     val = readb_relaxed(mb86s7x_shm_base
> > +                         + WFI_COLOR_OFFSET + clstr * 2 + cpu);
> > +     val &= ~AT_WFI_COLOR_MASK;
> > +     val |= clr;
> > +     writeb_relaxed(val, mb86s7x_shm_base
> > +                    + WFI_COLOR_OFFSET + clstr * 2 + cpu);
> > +}
> > +
> > +static int mb86s7x_pm_power_up(unsigned int cpu, unsigned int cluster)
> > +{
> > +     int ret = 0;
> > +
> > +     if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
> > +             return -EINVAL;
> > +
> > +     pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
> > +
> > +     local_irq_disable();
> > +     arch_spin_lock(&mb86s7x_pm_lock);
> > +
> > +     mb86s7x_pm_use_count[cluster][cpu]++;
> > +
> > +     if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
> > +             struct mb86s7x_cpu_gate cmd;
> > +
> > +             arch_spin_unlock(&mb86s7x_pm_lock);
> > +             local_irq_enable();
> 
> From that point onward, nothing prevents concurrent execution in
> mb86s7x_pm_suspend() racing to call mb86s7x_set_wficolor() resulting in
> an incoherent state depending on who wins the race.
> 
> > +             cmd.payload_size = sizeof(cmd);
> > +             cmd.cluster_class = 0;
> > +             cmd.cluster_id = cluster;
> > +             cmd.cpu_id = cpu;
> > +             cmd.cpu_state = SCB_CPU_STATE_ON;
> > +
> > +             pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
> > +                      __func__, __LINE__, cmd.cluster_class,
> > +                      cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
> > +
> > +             mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
> > +             ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_SET_REQ,
> > +                                       &cmd, sizeof(cmd));
> > +             if (ret < 0) {
> > +                     pr_err("%s:%d failed!\n", __func__, __LINE__);
> > +                     return ret;
> > +             }
> > +
> > +             pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u}\n",
> > +                      __func__, __LINE__, cmd.cluster_class,
> > +                      cmd.cluster_id, cmd.cpu_id, cmd.cpu_state);
> > +
> > +             if (cmd.cpu_state != SCB_CPU_STATE_ON)
> > +                     return -ENODEV;
> > +     } else if (mb86s7x_pm_use_count[cluster][cpu] != 2) {
> > +             /*
> > +              * The only possible values are:
> > +              * 0 = CPU down
> > +              * 1 = CPU (still) up
> > +              * 2 = CPU requested to be up before it had a chance
> > +              *     to actually make itself down.
> > +              * Any other value is a bug.
> > +              */
> > +             BUG();
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void mb86s7x_pm_suspend(u64 ignored)
> > +{
> > +     unsigned int mpidr, cpu, cluster;
> > +     bool last_man = false, skip_wfi = false;
> > +
> > +     mpidr = read_cpuid_mpidr();
> > +     cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> > +     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> > +
> > +     pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
> > +     __mcpm_cpu_going_down(cpu, cluster);
> > +
> > +     arch_spin_lock(&mb86s7x_pm_lock);
> > +     BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
> > +
> > +     mb86s7x_pm_use_count[cluster][cpu]--;
> > +
> > +     if (mb86s7x_pm_use_count[cluster][cpu] == 0) {
> > +             if (!mb86s7x_pm_use_count[cluster][0] &&
> > +                 !mb86s7x_pm_use_count[cluster][1])
> > +                     last_man = true;
> > +             mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_POWEROFF);
> > +     } else if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
> > +             skip_wfi = true; /* Overtaken by a power up */
> > +     } else {
> > +             BUG();
> > +     }
> > +
> > +     if (!skip_wfi)
> > +             gic_cpu_if_down();
> > +
> > +     if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
> > +             arch_spin_unlock(&mb86s7x_pm_lock);
> > +
> > +             if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
> > +                     /*
> > +                      * On the Cortex-A15 we need to disable
> > +                      * L2 prefetching before flushing the cache.
> > +                      */
> > +                     asm volatile(
> > +                     "mcr p15, 1, %0, c15, c0, 3\n\t"
> > +                     "isb\n\t"
> > +                     "dsb"
> > +                     : : "r" (0x400));
> > +             }
> > +
> > +             mb86s70evb_exit_coherency_flush(all);
> > +
> > +             cci_disable_port_by_cpu(mpidr);
> > +
> > +             __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
> > +     } else {
> > +             arch_spin_unlock(&mb86s7x_pm_lock);
> > +             mb86s70evb_exit_coherency_flush(louis);
> > +     }
> > +
> > +     __mcpm_cpu_down(cpu, cluster);
> > +
> > +     /* Now we are prepared for power-down, do it: */
> > +     if (!skip_wfi)
> > +             wfi();
> > +}
> > +
> > +static void mb86s7x_pm_power_down(void)
> > +{
> > +     mb86s7x_pm_suspend(0);
> > +}
> > +
> > +static int mb86s7x_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
> > +{
> > +     struct mb86s7x_cpu_gate cmd;
> > +     int i, ret;
> > +
> > +     if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
> > +             return 0;
> 
> This should return an error or BUG().
> 
> > +     cmd.payload_size = sizeof(cmd);
> > +     cmd.cluster_class = 0;
> > +     cmd.cluster_id = cluster;
> > +     cmd.cpu_id = cpu;
> > +     cmd.cpu_state = SCB_CPU_STATE_ON;
> > +
> > +     for (i = 0; i < 50; i++) {
> > +             ret = mb86s7x_send_packet(CMD_CPU_CLOCK_GATE_GET_REQ,
> > +                                       &cmd, sizeof(cmd));
> > +             if (ret < 0) {
> > +                     pr_err("%s:%d failed to get CPU status\n",
> > +                            __func__, __LINE__);
> > +                     return ret;
> > +             }
> > +
> > +             pr_debug("%s:%d Cl_Class-%u CL_ID-%u CPU_ID-%u STATE-%u\n",
> > +                      __func__, __LINE__,
> > +                      cmd.cluster_class, cmd.cluster_id,
> > +                      cmd.cpu_id, cmd.cpu_state);
> > +
> > +             if (cmd.cpu_state == SCB_CPU_STATE_OFF)
> > +                     return 0;
> > +
> > +             msleep(20);
> > +     }
> > +
> > +     return -ETIMEDOUT;
> > +}
> > +
> > +static void mb86s7x_pm_powered_up(void)
> > +{
> > +     unsigned int mpidr, cpu, cluster;
> > +
> > +     mpidr = read_cpuid_mpidr();
> > +     cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> > +     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> > +
> > +     arch_spin_lock(&mb86s7x_pm_lock);
> > +     if (!mb86s7x_pm_use_count[cluster][cpu])
> > +             mb86s7x_pm_use_count[cluster][cpu] = 1;
> > +     arch_spin_unlock(&mb86s7x_pm_lock);
> > +}
> > +
> > +static const struct mcpm_platform_ops mb86s7x_pm_power_ops = {
> > +     .power_up               = mb86s7x_pm_power_up,
> > +     .power_down             = mb86s7x_pm_power_down,
> > +     .wait_for_powerdown     = mb86s7x_wait_for_powerdown,
> > +     .suspend                = mb86s7x_pm_suspend,
> > +     .powered_up             = mb86s7x_pm_powered_up,
> > +};
> > +
> > +/*
> > + * Enable cluster-level coherency, in preparation for turning on the MMU.
> > + */
> > +static void __naked mb86s7x_pm_power_up_setup(unsigned int affinity_level)
> > +{
> > +     asm volatile ("\n"
> > +"    cmp     r0, #1\n"
> > +"    bxne    lr\n"
> > +"    b       cci_enable_port_for_self");
> > +}
> > +
> > +static void __init mb86s7x_cache_off(void)
> > +{
> > +     if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) {
> > +             /* disable L2 prefetching on the Cortex-A15 */
> > +             asm volatile(
> > +             "mcr    p15, 1, %0, c15, c0, 3\n\t"
> > +             "isb\n\t"
> > +             "dsb"
> > +             : : "r" (0x400));
> > +     }
> > +     mb86s70evb_exit_coherency_flush(all);
> > +}
> > +
> > +struct mb86s7x_scb_version {
> > +     u32 payload_size;
> > +     u32 version;
> > +     u32 config_version;
> > +};
> > +
> > +extern void mb86s7x_cpu_entry(unsigned long secondary_entry);
> > +
> > +static int __init mb86s7x_mcpm_init(void)
> > +{
> > +     unsigned int mpidr, cpu, cluster;
> > +     struct mb86s7x_scb_version cmd;
> > +     int ret;
> > +
> > +     if (!cci_probed())
> > +             return -ENODEV;
> > +
> > +     mpidr = read_cpuid_mpidr();
> > +     cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
> > +     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
> > +
> > +     pr_info("Booting on cpu_%u cluster_%u\n", cpu, cluster);
> > +     mb86s7x_pm_use_count[cluster][cpu] = 1;
> > +
> > +     /* reset the wfi 'color' for primary cpu */
> > +     mb86s7x_set_wficolor(cluster, cpu, AT_WFI_DO_NOTHING);
> > +
> > +     /* Do SMC to set entry address for CPUs coming online */
> > +     mb86s7x_cpu_entry(virt_to_phys(mcpm_entry_point));
> > +
> > +     cmd.payload_size = sizeof(cmd);
> > +     cmd.version = 0;
> > +     cmd.config_version = 0;
> > +     ret = mb86s7x_send_packet(CMD_SCB_CAPABILITY_GET_REQ,
> > +                               &cmd, sizeof(cmd));
> > +     if (ret < 0)
> > +             pr_err("%s:%d failed to get SCB version\n",
> > +                    __func__, __LINE__);
> > +
> > +     pr_info("MB86S7x MCPM initialized: SCB version 0x%x:0x%x\n",
> > +             cmd.version, cmd.config_version);
> > +
> > +     ret = mcpm_platform_register(&mb86s7x_pm_power_ops);
> > +     if (!ret)
> > +             ret = mcpm_sync_init(mb86s7x_pm_power_up_setup);
> > +     if (!ret)
> > +             ret = mcpm_loopback(mb86s7x_cache_off); /* turn on the CCI */
> > +     mcpm_smp_set_ops();
> > +
> > +     return ret;
> > +}
> > +early_initcall(mb86s7x_mcpm_init);
> > diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
> > new file mode 100644
> > index 0000000..a14330b
> > --- /dev/null
> > +++ b/arch/arm/mach-mb86s7x/smc.S
> > @@ -0,0 +1,27 @@
> > +/*
> > + * SMC command interface to set secondary entry point
> > + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
> > + * Copyright: (C) 2014 Linaro Ltd.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/linkage.h>
> > +
> > +.arch_extension sec
> > +
> > +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
> > +ENTRY(mb86s7x_cpu_entry)
> > +     stmfd   sp!, {r1-r11, lr}
> > +     mov r1, r0
> > +     ldr r0, =1
> > +     mrc p15, 0, r3, c1, c0, 0
> > +     mov r4, r3
> > +     and r3, #0xbfffffff
> > +     mcr p15, 0, r3, c1, c0, 0
> > +     smc #0
> > +     mcr p15, 0, r4, c1, c0, 0
> > +     ldmfd   sp!, {r1-r11, pc}
> > +ENDPROC(mb86s7x_cpu_entry)
> > --
> > 1.9.0
> >
> >
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 18:06     ` Sudeep Holla
@ 2014-11-25 18:55       ` Nicolas Pitre
  0 siblings, 0 replies; 97+ messages in thread
From: Nicolas Pitre @ 2014-11-25 18:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Nov 2014, Sudeep Holla wrote:

> 
> 
> On 25/11/14 17:42, Nicolas Pitre wrote:
> > On Thu, 20 Nov 2014, Vincent Yang wrote:
> >
> > > The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> > > CPU/CLUSTER power up/down done by SCB over mailbox.
> > >
> > > Signed-off-by: Andy Green <andy.green@linaro.org>
> > > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > > Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> > > Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> > > ---
> > >   arch/arm/mach-mb86s7x/Makefile |   2 +-
> > >   arch/arm/mach-mb86s7x/mcpm.c   | 360
> > >   +++++++++++++++++++++++++++++++++++++++++
> > >   arch/arm/mach-mb86s7x/smc.S    |  27 ++++
> > >   3 files changed, 388 insertions(+), 1 deletion(-)
> > >   create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
> > >   create mode 100644 arch/arm/mach-mb86s7x/smc.S
> > >
> > > diff --git a/arch/arm/mach-mb86s7x/Makefile
> > > b/arch/arm/mach-mb86s7x/Makefile
> > > index 97640b6..b0fa34b 100644
> > > --- a/arch/arm/mach-mb86s7x/Makefile
> > > +++ b/arch/arm/mach-mb86s7x/Makefile
> > > @@ -1 +1 @@
> > > -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
> > > +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
> > > diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
> > > new file mode 100644
> > > index 0000000..bf1b50a
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mb86s7x/mcpm.c
> > > @@ -0,0 +1,360 @@
> > > +/*
> > > + * arch/arm/mach-mb86s7x/mcpm.c
> > > + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
> > > + * Copyright:        (C) 2014 Linaro Ltd.
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 as
> > > + * published by the Free Software Foundation.
> > > + */
> > > +
> > > +#include <linux/io.h>
> > > +#include <linux/pm.h>
> > > +#include <linux/delay.h>
> > > +#include <linux/cpu_pm.h>
> > > +#include <linux/kernel.h>
> > > +#include <linux/module.h>
> > > +#include <linux/arm-cci.h>
> > > +#include <linux/spinlock.h>
> > > +#include <linux/suspend.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/irqchip/arm-gic.h>
> > > +#include <linux/platform_device.h>
> > > +
> > > +#include <soc/mb86s7x/scb_mhu.h>
> > > +
> > > +#include <asm/mcpm.h>
> > > +#include <asm/cp15.h>
> > > +#include <asm/cputype.h>
> > > +#include <asm/suspend.h>
> > > +#include <asm/idmap.h>
> > > +
> > > +#define S7X_MAX_CLUSTER      2
> > > +#define S7X_MAX_CPU  2
> > > +
> > > +#define MHU_SHM_OFFSET               0x3800
> > > +#define WFI_COLOR_OFFSET     0x3f00
> > > +#define TRAMPOLINE_OFFSET    0x3c00
> > > +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
> > > +
> > > +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
> > > +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
> > > +extern void __iomem *mb86s7x_shm_base;
> > > +
> > > +#define AT_WFI_DO_NOTHING    0x0
> > > +#define AT_WFI_DO_SUSPEND    0x1
> > > +#define AT_WFI_DO_POWEROFF   0x2
> > > +#define AT_WFI_COLOR_MASK    0x3
> > > +
> > > +struct mb86s7x_cpu_gate {
> > > +     u32 payload_size;
> > > +     u32 cluster_class;
> > > +     u32 cluster_id;
> > > +     u32 cpu_id;
> > > +#define SCB_CPU_STATE_OFF    0x0
> > > +#define SCB_CPU_STATE_ON     0x1
> > > +#define SCB_CPU_STATE_SUSP   0x2
> > > +     u32 cpu_state;
> > > +};
> > > +
> > > +asmlinkage void mb86s70evb_outer_flush_all(void)
> > > +{
> > > +     outer_flush_all();
> > > +}
> > > +
> > > +#define mb86s70evb_exit_coherency_flush(level) { \
> > > +     asm volatile( \
> > > +     "stmfd  sp!, {fp, ip}\n\t" \
> > > +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> > > +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
> > > +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> > > +     "isb\n\t" \
> > > +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
> > > +     "bl     mb86s70evb_outer_flush_all\n\t" \
> >
> > This is wrong.  As mentioned already, this unconditionally flushes L2 in
> > all cases which shouldn't be necessary in the "louis" case.
> >
> 
> IIUC the external/outer cache needs to be flushed only if it's last
> cluster going down. It would be suboptimal to flush it when one cluster
> is going down while other is still active. So it's not always correct
> for even "all" case too.

Indeed.

It is trivial to look at the cluster usage count and flush L2 whenever 
the other cluster's count is also 0.  This would happen when the count 
lock is released which opens the possibility for races with the other 
cluster coming up or in the process of going down at the same time, 
causing spurious flushes... which we certainly can live with.


Nicolas

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 18:46     ` Lorenzo Pieralisi
@ 2014-11-25 18:59       ` Nicolas Pitre
  2014-11-25 19:21         ` Sudeep Holla
  2014-11-26 16:29       ` Jassi Brar
  1 sibling, 1 reply; 97+ messages in thread
From: Nicolas Pitre @ 2014-11-25 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Nov 2014, Lorenzo Pieralisi wrote:

> On Tue, Nov 25, 2014 at 05:42:32PM +0000, Nicolas Pitre wrote:
> > On Thu, 20 Nov 2014, Vincent Yang wrote:
> > 
> > > The remote firmware(SCB) owns the SMP control. This MCPM driver gets
> > > CPU/CLUSTER power up/down done by SCB over mailbox.
> > >
> > > Signed-off-by: Andy Green <andy.green@linaro.org>
> > > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > > Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> > > Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> > > ---
> > >  arch/arm/mach-mb86s7x/Makefile |   2 +-
> > >  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
> > >  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
> > >  3 files changed, 388 insertions(+), 1 deletion(-)
> > >  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
> > >  create mode 100644 arch/arm/mach-mb86s7x/smc.S
> > >
> > > diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
> > > index 97640b6..b0fa34b 100644
> > > --- a/arch/arm/mach-mb86s7x/Makefile
> > > +++ b/arch/arm/mach-mb86s7x/Makefile
> > > @@ -1 +1 @@
> > > -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
> > > +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
> > > diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
> > > new file mode 100644
> > > index 0000000..bf1b50a
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mb86s7x/mcpm.c
> > > @@ -0,0 +1,360 @@
> > > +/*
> > > + * arch/arm/mach-mb86s7x/mcpm.c
> > > + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
> > > + * Copyright:        (C) 2014 Linaro Ltd.
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 as
> > > + * published by the Free Software Foundation.
> > > + */
> > > +
> > > +#include <linux/io.h>
> > > +#include <linux/pm.h>
> > > +#include <linux/delay.h>
> > > +#include <linux/cpu_pm.h>
> > > +#include <linux/kernel.h>
> > > +#include <linux/module.h>
> > > +#include <linux/arm-cci.h>
> > > +#include <linux/spinlock.h>
> > > +#include <linux/suspend.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/irqchip/arm-gic.h>
> > > +#include <linux/platform_device.h>
> > > +
> > > +#include <soc/mb86s7x/scb_mhu.h>
> > > +
> > > +#include <asm/mcpm.h>
> > > +#include <asm/cp15.h>
> > > +#include <asm/cputype.h>
> > > +#include <asm/suspend.h>
> > > +#include <asm/idmap.h>
> > > +
> > > +#define S7X_MAX_CLUSTER      2
> > > +#define S7X_MAX_CPU  2
> > > +
> > > +#define MHU_SHM_OFFSET               0x3800
> > > +#define WFI_COLOR_OFFSET     0x3f00
> > > +#define TRAMPOLINE_OFFSET    0x3c00
> > > +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
> > > +
> > > +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
> > > +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
> > > +extern void __iomem *mb86s7x_shm_base;
> > > +
> > > +#define AT_WFI_DO_NOTHING    0x0
> > > +#define AT_WFI_DO_SUSPEND    0x1
> > > +#define AT_WFI_DO_POWEROFF   0x2
> > > +#define AT_WFI_COLOR_MASK    0x3
> > > +
> > > +struct mb86s7x_cpu_gate {
> > > +     u32 payload_size;
> > > +     u32 cluster_class;
> > > +     u32 cluster_id;
> > > +     u32 cpu_id;
> > > +#define SCB_CPU_STATE_OFF    0x0
> > > +#define SCB_CPU_STATE_ON     0x1
> > > +#define SCB_CPU_STATE_SUSP   0x2
> > > +     u32 cpu_state;
> > > +};
> > > +
> > > +asmlinkage void mb86s70evb_outer_flush_all(void)
> > > +{
> > > +     outer_flush_all();
> > > +}
> > > +
> > > +#define mb86s70evb_exit_coherency_flush(level) { \
> > > +     asm volatile( \
> > > +     "stmfd  sp!, {fp, ip}\n\t" \
> > > +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
> > > +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
> > > +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
> > > +     "isb\n\t" \
> > > +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
> > > +     "bl     mb86s70evb_outer_flush_all\n\t" \
> > 
> > This is wrong.  As mentioned already, this unconditionally flushes L2 in
> > all cases which shouldn't be necessary in the "louis" case.
> 
> Is this a bL system with unified and architected L2s ? I think so, so
> what's the outercache for ?
> 
> > Furthermore, the safety of this macro is ensured by not having any
> > memory writes in the middle of the whole sequence.  By calling
> > mb86s70evb_outer_flush_all() there could be the return address pushed
> > onto the stack before calling outer_flush_all() if some tail call
> > optimization is not applied.  And this is without saying what
> > outer_flush_all() actually does.
> > 
> > Why can't you simply do this instead:
> > 
> >         v7_exit_coherency_flush(all);
> >         outer_flush_all();
> > 
> > Of course you'll have to audit everything in the outer_flush_all() path
> > to make sure no atomic instructions such as LDREX/STREX are invoked.
> > Those have undefined behavior after CR_C is cleared.
> 
> What you are saying is correct but first of all I would like to
> understand what outercache we are talking about here.
> 
> Code snippet above is fragile, as you said, and I'd rather disable
> the outercache before executing the power down sequence (which implies
> cache is cleaned/invalidated and quiescent before we clear the C bit)
> if there is an outercache to be managed.

Good question.  That opens the potential for an even simpler fix!  ;-)


Nicolas

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 18:59       ` Nicolas Pitre
@ 2014-11-25 19:21         ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-25 19:21 UTC (permalink / raw)
  To: linux-arm-kernel



On 25/11/14 18:59, Nicolas Pitre wrote:
> On Tue, 25 Nov 2014, Lorenzo Pieralisi wrote:
>
>> On Tue, Nov 25, 2014 at 05:42:32PM +0000, Nicolas Pitre wrote:
>>> On Thu, 20 Nov 2014, Vincent Yang wrote:
>>>
>>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>>
>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>>>> ---
>>>>   arch/arm/mach-mb86s7x/Makefile |   2 +-
>>>>   arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>>>>   arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>>>>   3 files changed, 388 insertions(+), 1 deletion(-)
>>>>   create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>>>>   create mode 100644 arch/arm/mach-mb86s7x/smc.S
>>>>
>>>> diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
>>>> index 97640b6..b0fa34b 100644
>>>> --- a/arch/arm/mach-mb86s7x/Makefile
>>>> +++ b/arch/arm/mach-mb86s7x/Makefile
>>>> @@ -1 +1 @@
>>>> -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
>>>> +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
>>>> diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
>>>> new file mode 100644
>>>> index 0000000..bf1b50a
>>>> --- /dev/null
>>>> +++ b/arch/arm/mach-mb86s7x/mcpm.c
>>>> @@ -0,0 +1,360 @@
>>>> +/*
>>>> + * arch/arm/mach-mb86s7x/mcpm.c
>>>> + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
>>>> + * Copyright:        (C) 2014 Linaro Ltd.
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + */
>>>> +
>>>> +#include <linux/io.h>
>>>> +#include <linux/pm.h>
>>>> +#include <linux/delay.h>
>>>> +#include <linux/cpu_pm.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/arm-cci.h>
>>>> +#include <linux/spinlock.h>
>>>> +#include <linux/suspend.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/irqchip/arm-gic.h>
>>>> +#include <linux/platform_device.h>
>>>> +
>>>> +#include <soc/mb86s7x/scb_mhu.h>
>>>> +
>>>> +#include <asm/mcpm.h>
>>>> +#include <asm/cp15.h>
>>>> +#include <asm/cputype.h>
>>>> +#include <asm/suspend.h>
>>>> +#include <asm/idmap.h>
>>>> +
>>>> +#define S7X_MAX_CLUSTER      2
>>>> +#define S7X_MAX_CPU  2
>>>> +
>>>> +#define MHU_SHM_OFFSET               0x3800
>>>> +#define WFI_COLOR_OFFSET     0x3f00
>>>> +#define TRAMPOLINE_OFFSET    0x3c00
>>>> +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
>>>> +
>>>> +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
>>>> +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
>>>> +extern void __iomem *mb86s7x_shm_base;
>>>> +
>>>> +#define AT_WFI_DO_NOTHING    0x0
>>>> +#define AT_WFI_DO_SUSPEND    0x1
>>>> +#define AT_WFI_DO_POWEROFF   0x2
>>>> +#define AT_WFI_COLOR_MASK    0x3
>>>> +
>>>> +struct mb86s7x_cpu_gate {
>>>> +     u32 payload_size;
>>>> +     u32 cluster_class;
>>>> +     u32 cluster_id;
>>>> +     u32 cpu_id;
>>>> +#define SCB_CPU_STATE_OFF    0x0
>>>> +#define SCB_CPU_STATE_ON     0x1
>>>> +#define SCB_CPU_STATE_SUSP   0x2
>>>> +     u32 cpu_state;
>>>> +};
>>>> +
>>>> +asmlinkage void mb86s70evb_outer_flush_all(void)
>>>> +{
>>>> +     outer_flush_all();
>>>> +}
>>>> +
>>>> +#define mb86s70evb_exit_coherency_flush(level) { \
>>>> +     asm volatile( \
>>>> +     "stmfd  sp!, {fp, ip}\n\t" \
>>>> +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
>>>> +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
>>>> +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
>>>> +     "isb\n\t" \
>>>> +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
>>>> +     "bl     mb86s70evb_outer_flush_all\n\t" \
>>>
>>> This is wrong.  As mentioned already, this unconditionally flushes L2 in
>>> all cases which shouldn't be necessary in the "louis" case.
>>
>> Is this a bL system with unified and architected L2s ? I think so, so
>> what's the outercache for ?
>>
>>> Furthermore, the safety of this macro is ensured by not having any
>>> memory writes in the middle of the whole sequence.  By calling
>>> mb86s70evb_outer_flush_all() there could be the return address pushed
>>> onto the stack before calling outer_flush_all() if some tail call
>>> optimization is not applied.  And this is without saying what
>>> outer_flush_all() actually does.
>>>
>>> Why can't you simply do this instead:
>>>
>>>          v7_exit_coherency_flush(all);
>>>          outer_flush_all();
>>>
>>> Of course you'll have to audit everything in the outer_flush_all() path
>>> to make sure no atomic instructions such as LDREX/STREX are invoked.
>>> Those have undefined behavior after CR_C is cleared.
>>
>> What you are saying is correct but first of all I would like to
>> understand what outercache we are talking about here.
>>
>> Code snippet above is fragile, as you said, and I'd rather disable
>> the outercache before executing the power down sequence (which implies
>> cache is cleaned/invalidated and quiescent before we clear the C bit)
>> if there is an outercache to be managed.
>
> Good question.  That opens the potential for an even simpler fix!  ;-)
>
Ah right, sorry my bad somehow I assumed this is system cache at higher
level apart from the intra-cluster unified and architected L2 cache.
Now checking the DT again I don't see any outer cache controller, so
it's better to get that info.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 17:39           ` Sudeep Holla
@ 2014-11-25 20:31             ` Andy Green
  0 siblings, 0 replies; 97+ messages in thread
From: Andy Green @ 2014-11-25 20:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 26 November 2014 at 01:39, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 25/11/14 16:43, Andy Green wrote:
>>
>> On 25 November 2014 at 22:24, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>
>>>
>>>
>>> On 25/11/14 13:42, Andy Green wrote:
>>>>
>>>>
>>>> On 25 November 2014 at 19:48, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>>
>>>>> On 20/11/14 12:35, Vincent Yang wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>>>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>>>>
>>>>>
>>>>>> diff --git a/arch/arm/mach-mb86s7x/smc.S b/arch/arm/mach-mb86s7x/smc.S
>>>>>> new file mode 100644
>>>>>> index 0000000..a14330b
>>>>>> --- /dev/null
>>>>>> +++ b/arch/arm/mach-mb86s7x/smc.S
>>>>>> @@ -0,0 +1,27 @@
>>>>>> +/*
>>>>>> + * SMC command interface to set secondary entry point
>>>>>> + * Copyright: (C) 2013-2014 Fujitsu Semiconductor Limited
>>>>>> + * Copyright: (C) 2014 Linaro Ltd.
>>>>>> + *
>>>>>> + * This program is free software; you can redistribute it and/or
>>>>>> modify
>>>>>> + * it under the terms of the GNU General Public License version 2 as
>>>>>> + * published by the Free Software Foundation.
>>>>>> + */
>>>>>> +
>>>>>> +#include <linux/linkage.h>
>>>>>> +
>>>>>> +.arch_extension sec
>>>>>> +
>>>>>> +/* void mb86s7x_cpu_entry(unsigned long secondary_entry); */
>>>>>> +ENTRY(mb86s7x_cpu_entry)
>>>>>> +       stmfd   sp!, {r1-r11, lr}
>>>>>> +       mov r1, r0
>>>>>> +       ldr r0, =1
>>>>>> +       mrc p15, 0, r3, c1, c0, 0
>>>>>> +       mov r4, r3
>>>>>> +       and r3, #0xbfffffff
>>>>>> +       mcr p15, 0, r3, c1, c0, 0
>>>>>> +       smc #0
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Interesting, it looks like you have some secure entity running on your
>>>>> platform.
>>>>
>>>>
>>>>
>>>> Yes, we have a stub "secure firmware" that implements a few critical
>>>> functions to allow us to operate the kernel as nonsecure.  It's part
>>>> of the bootloader for this platform which is also GPL'd.
>>>>
>>>
>>> OK, thanks for clarifying.
>>>
>>>>> 1. While the CPU is powered down who is taking care of saving it's
>>>>>      state as you are doing it in the Linux itself ?
>>>>
>>>>
>>>>
>>>> Nothing.  The secure firmware is in a bootloader that is copied to and
>>>> runs from secure sram.  When the cpu is reset, he comes back up in
>>>> secure mode and gets initialized in the secure firmware, before
>>>> entering Non-secure mode and the kernel's secondary entry point.
>>>>
>>>
>>> So you do have live secure firmware stub on secure sram at any time,
>>> right ? When the CPUs are powered down especially for low power states,
>>> how is the secure state of the CPUs preserved ?
>>
>>
>> There isn't any 'secure state' like you are thinking.
>>
>> Our secure firmware is a rudimentary stub that provides a handful of
>> stateless secure services to the kernel.
>>
>> There's nothing to save or restore.
>>
>
> Ok that clarifies, but I assume some customers would like to extend that
> beyond the stub.

Yes.  But currently the only implementation is the stub one.

>>>>> 2. Is Linux running in Secure or Non-secure mode ?
>>>>
>>>>
>>>>
>>>> Another firmware (unfortunately not GPL) running on an on-die M3
>>>> informs the secure firmware on the AP whether he should set the AP cpu
>>>> to nonsecure or not before jumping to the kernel... basically it's
>>>> decided at runtime and the same kernel binary serves in both modes.
>>>>
>>>
>>> OK that's fine as along as you assume that kernel *always* runs in
>>> *non-secure* mode and never attempts any *secure access*.
>>
>>
>> Yes that's how it's set up.
>>
>> When this M3 tells the bootloader to make us nonsecure before going to
>> the kernel, he marks up all the IPs that have dynamic access control
>> to allow access in nonsecure.  That's because we have complete BSP
>> support out of tree and we want to prove that it can all work from
>> nonsecure directly.
>>
>> When Fujitsu want to restrict an IP from nonsecure access for a
>> particular customer they will add support to manage the IP either on
>> the M3 or the AP secure firmware and disable the IP support in DT.
>> But that does not exist yet.
>>
>
> Yes this was what I was trying to tell. From what I understand now, if
> the customer implements secure firmware which might need to save and
> restore the state, then he needs to manage.(He might end up with

Yes.  But I think we'll have to implement and test management for that
when it exists.

> duplication of this last man algorithm in the secure firmware too,
> I was just trying to mention this)

Maybe... other patterns are also possible like whole core reservation
at the bootloader / secure firmware to run a different secure OS and
leave smp like it is.

Fujitsu's market is ASIC so they will implement whatever customization
their customer likes in hardware, firmware and software.

>>>>> 3. Why do you need this smc call for secondary boot only ?
>>>>
>>>>
>>>>
>>>> The call sets the secondary entry point stored in the secure sram.
>>>>
>>>
>>> So IIUC, you run Linux in non-secure mode, PSCI would be more suitable
>>> than MCPM when you start thinking/implementing CPUIdle otherwise I think
>>> you will end up duplicating some logic(last man and race management)
>>> both in Linux as well as your secure firmware.
>>
>>
>> As I mentioned our secure firmware is not what you're imagining.
>>
>
> Understood, that?s about the current stub secure firmware and I was
> talking about non-existent full blown secure firmware. If that's not the
> case, then it's fine.

OK

>> MCPM works very well for us.  Are you saying we can't use MCPM and
>> must reimplement with PSCI on both sides?
>>
>
> No I never said that, I wanted to understand what's the scope of your
> or any secure firmware of your customer.

Good thanks.

>>>> The bootloader heuristic is if that's unset (0), and it's what the
>>>
>>>
>>>
>>> This could be problem as when the CPU is hotplugged out, ideally it
>>> should be set to 0 to avoid spurious wakeup and entry into Linux.
>>
>>
>> ... I think you are talking about something else.
>>
>> This is a PA stored in secure SRAM that holds the kernel's secondary
>> entry point.  It's 0 when the bootloader is copied to the secure SRAM
>> by the M3 at cold reset.  If anybody set it, it means Linux booted.
>>
>> The M3 manages AP core state and either depowers the cluster or holds
>> them in reset. So there can be no 'spurious wakeup and entry into
>> Linux'.
>>
>
> Ok, good that you can guarantee that.
>
>>> Yes MCPM does manage it, but IMO you are mixing up secure and non-secure
>>> methods which might become issue later when implementing low power
>>> CPU states.
>>
>>
>> Can you explain where you see the problem?  All we are doing is
>> storing the kernel secondary entry point.  The bootloader / secure
>> firmware always receives any started core first and decides when and
>> how to jump to it.
>>
>>>> bootloader decided should be regarded as the primary cpu, then we do
>>>> the real onetime cold boot flow, load the kernel etc.  Non-primary
>>>> cpus wait at WFI in the bootloader.  When the primary cpu runs the
>>>> code above, he sets the secondary entry point, and later starts to
>>>
>>>
>>>
>>> I assume it's not done when primary boots, but by primary cpu when
>>> bringing up the secondaries.
>>
>>
>> Yes the point is the primary sets the secondary entry at the secure
>> firmware using the SMC and then the IPIs can start flying.
>>
>
> Only if GIC is properly configured for that though I don't see the point
> in giving non-secure entity secure access. If any secure firmware wants
> to change that in future that could be issue.

Well the point is there is no irq handling or smp management in the
secure firmware stub.

If it grows traditional secure world features like dealing with irqs
in secure world we'll have to cross / test that bridge when and if we
come to it.

>>>> bring up the other cores who jump to the secondary entry that was set.
>>>>
>>>
>>> I assume primary sends IPI to wake up secondaries, but if the SGIs are
>>> configured as secure, then it will _not_ be delivered. If not it *might*
>>
>>
>> Well, it is coordinated between M3 and AP bootloader / secure firmware
>> if we should run nonsecure or not, and it configures a bunch of stuff
>> like GIC accordingly so it works.  And it does work.
>>
>>> work but I can't understand the need of running Linux non-secure with
>>> all secure access given to it.
>>
>>
>> Fujitsu's goal with this was confirm the SoC + kernel can work in
>> nonsecure for the whole BSP stack.  Then as customers want particular
>> IPs secure-only, implement the behaviour they need in the AP secure
>> firmware or M3.  But as yet, no support for that is implemented.
>>
>
> I never said you *must implement* PSCI and *not use* MCPM. Since you

OK, good.

> mentioned that you will be providing option to run Linux in non-secure mode,
> which means there can be _secure_entity_ which does more than your
> current stub, I just wanted to mention the possible issues you may need to
> resolve then.

OK, thanks for your feedback.

-Andy

> Regards,
> Sudeep
>

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-25 18:01                 ` Sudeep Holla
@ 2014-11-26  5:37                     ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-26  5:37 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya

On 25 November 2014 at 23:31, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>
>
> On 25/11/14 16:51, Jassi Brar wrote:
>>
>> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>>
>>>
>>>
>>> On 20/11/14 12:34, Vincent Yang wrote:
>>>>
>>>>
>>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>>
>>>> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
>>>> ---
>>>>    .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>>    drivers/mailbox/Kconfig                            |   7 +
>>>>    drivers/mailbox/Makefile                           |   2 +
>>>>    drivers/mailbox/arm_mhu.c                          | 196
>>>> +++++++++++++++++++++
>>>>    4 files changed, 238 insertions(+)
>>>>    create mode 100644
>>>> Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>    create mode 100644 drivers/mailbox/arm_mhu.c
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> new file mode 100644
>>>> index 0000000..b1b9888
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> @@ -0,0 +1,33 @@
>>>> +ARM MHU Mailbox Driver
>>>> +======================
>>>> +
>>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>>> +3 independent channels/links to communicate with remote processor(s).
>>>
>>>
>>>
>>> I had reviewed this before and I see not all the comments are addressed.
>>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>>> as you need to assume Linux runs in non-secure privilege(and I gather
>>> that's the case even on this platform from other email in the thread)
>>>
>> Please revisit the old thread. After some discussion you had
>> graciously allowed me to keep the secure channel ;)
>> [
>> ... Even though I don't like you have secure channel access in Linux, you
>> have valid reasons. In case you decide to support it ....
>> ]
>
>
> Agreed but based on the other email in the same thread it looks like you
> want to run the same kernel both in secure and no-secure mode on this
> platform, in which case you _have_to_assume_ it's *non-secure only* always
> unless you come up with some DT magic.
>
Yes, the S vs NS mode should ideally be defined in DT. The kernel
image should remain the same.

>>   It seems you still don't get my point that the driver should manage
>> all channels - S & NS. If Linux is running in NS mode on a platform,
>> the DT will specify only some NS channel to be used. The controller
>> driver shouldn't be crippled just because you think Linux will never
>> be run in Secure mode.
>>
>
> Ok how do you handle that, I don't see that in the DT binding. As it
> stands, you can unconditionally try to access the secure channel and
> cause aborts if the platform is running in non-secure mode.
>
No. Please look at the dtsi again ....

        mhu: mailbox@2b1f0000 {
                #mbox-cells = <1>;
                compatible = "arm,mbox-mhu";
                reg = <0 0x2b1f0000 0x1000>;
                interrupts = <0 36 4>, /* LP Non-Sec */
                             <0 35 4>, /* HP Non-Sec */
                             <0 37 4>; /* Secure */
        };

        mhu_client: scb@2e000000 {
                compatible = "fujitsu,mb86s70-scb-1.0";
                reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
                mboxes = <&mhu 1>;
        };

See the DT for mbox client specifies that it uses channel-1 which is
High-Priority_Non-Secure channel.

-jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-26  5:37                     ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-26  5:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 25 November 2014 at 23:31, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 25/11/14 16:51, Jassi Brar wrote:
>>
>> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>
>>>
>>>
>>> On 20/11/14 12:34, Vincent Yang wrote:
>>>>
>>>>
>>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>>
>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>>>> ---
>>>>    .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>>    drivers/mailbox/Kconfig                            |   7 +
>>>>    drivers/mailbox/Makefile                           |   2 +
>>>>    drivers/mailbox/arm_mhu.c                          | 196
>>>> +++++++++++++++++++++
>>>>    4 files changed, 238 insertions(+)
>>>>    create mode 100644
>>>> Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>    create mode 100644 drivers/mailbox/arm_mhu.c
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> new file mode 100644
>>>> index 0000000..b1b9888
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>> @@ -0,0 +1,33 @@
>>>> +ARM MHU Mailbox Driver
>>>> +======================
>>>> +
>>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>>> +3 independent channels/links to communicate with remote processor(s).
>>>
>>>
>>>
>>> I had reviewed this before and I see not all the comments are addressed.
>>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>>> as you need to assume Linux runs in non-secure privilege(and I gather
>>> that's the case even on this platform from other email in the thread)
>>>
>> Please revisit the old thread. After some discussion you had
>> graciously allowed me to keep the secure channel ;)
>> [
>> ... Even though I don't like you have secure channel access in Linux, you
>> have valid reasons. In case you decide to support it ....
>> ]
>
>
> Agreed but based on the other email in the same thread it looks like you
> want to run the same kernel both in secure and no-secure mode on this
> platform, in which case you _have_to_assume_ it's *non-secure only* always
> unless you come up with some DT magic.
>
Yes, the S vs NS mode should ideally be defined in DT. The kernel
image should remain the same.

>>   It seems you still don't get my point that the driver should manage
>> all channels - S & NS. If Linux is running in NS mode on a platform,
>> the DT will specify only some NS channel to be used. The controller
>> driver shouldn't be crippled just because you think Linux will never
>> be run in Secure mode.
>>
>
> Ok how do you handle that, I don't see that in the DT binding. As it
> stands, you can unconditionally try to access the secure channel and
> cause aborts if the platform is running in non-secure mode.
>
No. Please look at the dtsi again ....

        mhu: mailbox at 2b1f0000 {
                #mbox-cells = <1>;
                compatible = "arm,mbox-mhu";
                reg = <0 0x2b1f0000 0x1000>;
                interrupts = <0 36 4>, /* LP Non-Sec */
                             <0 35 4>, /* HP Non-Sec */
                             <0 37 4>; /* Secure */
        };

        mhu_client: scb at 2e000000 {
                compatible = "fujitsu,mb86s70-scb-1.0";
                reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
                mboxes = <&mhu 1>;
        };

See the DT for mbox client specifies that it uses channel-1 which is
High-Priority_Non-Secure channel.

-jassi

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-26  5:37                     ` Jassi Brar
  (?)
@ 2014-11-26  5:44                     ` Andy Green
  -1 siblings, 0 replies; 97+ messages in thread
From: Andy Green @ 2014-11-26  5:44 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Vincent Yang, Vincent Yang, devicetree, linux, Sudeep Holla,
	linux-arm-kernel, galak, ijc+devicetree, robh+dt, arnd,
	Mark Rutland, Tetsuya Nuriya, patches, olof, Pawel Moll

[-- Attachment #1: Type: text/plain, Size: 4154 bytes --]

On 26 Nov 2014 13:37, "Jassi Brar" <jaswinder.singh@linaro.org> wrote:
>
> On 25 November 2014 at 23:31, Sudeep Holla <sudeep.holla@arm.com> wrote:
> >
> >
> > On 25/11/14 16:51, Jassi Brar wrote:
> >>
> >> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla@arm.com>
wrote:
> >>>
> >>>
> >>>
> >>> On 20/11/14 12:34, Vincent Yang wrote:
> >>>>
> >>>>
> >>>> Add driver for the ARM Message-Handling-Unit (MHU).
> >>>>
> >>>> Signed-off-by: Andy Green <andy.green@linaro.org>
> >>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> >>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> >>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> >>>> ---
> >>>>    .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
> >>>>    drivers/mailbox/Kconfig                            |   7 +
> >>>>    drivers/mailbox/Makefile                           |   2 +
> >>>>    drivers/mailbox/arm_mhu.c                          | 196
> >>>> +++++++++++++++++++++
> >>>>    4 files changed, 238 insertions(+)
> >>>>    create mode 100644
> >>>> Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> >>>>    create mode 100644 drivers/mailbox/arm_mhu.c
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> >>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> >>>> new file mode 100644
> >>>> index 0000000..b1b9888
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
> >>>> @@ -0,0 +1,33 @@
> >>>> +ARM MHU Mailbox Driver
> >>>> +======================
> >>>> +
> >>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that
has
> >>>> +3 independent channels/links to communicate with remote
processor(s).
> >>>
> >>>
> >>>
> >>> I had reviewed this before and I see not all the comments are
addressed.
> >>> I had mentioned that you can't add support to _SECURE_ channel in
Linux
> >>> as you need to assume Linux runs in non-secure privilege(and I gather
> >>> that's the case even on this platform from other email in the thread)
> >>>
> >> Please revisit the old thread. After some discussion you had
> >> graciously allowed me to keep the secure channel ;)
> >> [
> >> ... Even though I don't like you have secure channel access in Linux,
you
> >> have valid reasons. In case you decide to support it ....
> >> ]
> >
> >
> > Agreed but based on the other email in the same thread it looks like you
> > want to run the same kernel both in secure and no-secure mode on this
> > platform, in which case you _have_to_assume_ it's *non-secure only*
always
> > unless you come up with some DT magic.
> >
> Yes, the S vs NS mode should ideally be defined in DT. The kernel
> image should remain the same.

If this is desirable, we can edit the related dtb path in memory
accordingly at the bootloader, since that knows at runtime if he's secure
or nonsecure.

-Andy

> >>   It seems you still don't get my point that the driver should manage
> >> all channels - S & NS. If Linux is running in NS mode on a platform,
> >> the DT will specify only some NS channel to be used. The controller
> >> driver shouldn't be crippled just because you think Linux will never
> >> be run in Secure mode.
> >>
> >
> > Ok how do you handle that, I don't see that in the DT binding. As it
> > stands, you can unconditionally try to access the secure channel and
> > cause aborts if the platform is running in non-secure mode.
> >
> No. Please look at the dtsi again ....
>
>         mhu: mailbox@2b1f0000 {
>                 #mbox-cells = <1>;
>                 compatible = "arm,mbox-mhu";
>                 reg = <0 0x2b1f0000 0x1000>;
>                 interrupts = <0 36 4>, /* LP Non-Sec */
>                              <0 35 4>, /* HP Non-Sec */
>                              <0 37 4>; /* Secure */
>         };
>
>         mhu_client: scb@2e000000 {
>                 compatible = "fujitsu,mb86s70-scb-1.0";
>                 reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
>                 mboxes = <&mhu 1>;
>         };
>
> See the DT for mbox client specifies that it uses channel-1 which is
> High-Priority_Non-Secure channel.
>
> -jassi

[-- Attachment #2: Type: text/html, Size: 6264 bytes --]

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-26  5:37                     ` Jassi Brar
@ 2014-11-26 14:00                         ` Sudeep Holla
  -1 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-26 14:00 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Sudeep Holla, Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya



On 26/11/14 05:37, Jassi Brar wrote:
> On 25 November 2014 at 23:31, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>
>>
>> On 25/11/14 16:51, Jassi Brar wrote:
>>>
>>> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>>>
>>>>
>>>>
>>>> On 20/11/14 12:34, Vincent Yang wrote:
>>>>>
>>>>>
>>>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>>>
>>>>> Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>>> Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>>> Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
>>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
>>>>> ---
>>>>>     .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>>>     drivers/mailbox/Kconfig                            |   7 +
>>>>>     drivers/mailbox/Makefile                           |   2 +
>>>>>     drivers/mailbox/arm_mhu.c                          | 196
>>>>> +++++++++++++++++++++
>>>>>     4 files changed, 238 insertions(+)
>>>>>     create mode 100644
>>>>> Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>>     create mode 100644 drivers/mailbox/arm_mhu.c
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> new file mode 100644
>>>>> index 0000000..b1b9888
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> @@ -0,0 +1,33 @@
>>>>> +ARM MHU Mailbox Driver
>>>>> +======================
>>>>> +
>>>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>>>> +3 independent channels/links to communicate with remote processor(s).
>>>>
>>>>
>>>>
>>>> I had reviewed this before and I see not all the comments are addressed.
>>>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>>>> as you need to assume Linux runs in non-secure privilege(and I gather
>>>> that's the case even on this platform from other email in the thread)
>>>>
>>> Please revisit the old thread. After some discussion you had
>>> graciously allowed me to keep the secure channel ;)
>>> [
>>> ... Even though I don't like you have secure channel access in Linux, you
>>> have valid reasons. In case you decide to support it ....
>>> ]
>>
>>
>> Agreed but based on the other email in the same thread it looks like you
>> want to run the same kernel both in secure and no-secure mode on this
>> platform, in which case you _have_to_assume_ it's *non-secure only* always
>> unless you come up with some DT magic.
>>
> Yes, the S vs NS mode should ideally be defined in DT. The kernel
> image should remain the same.
>

That's good :)

>>>    It seems you still don't get my point that the driver should manage
>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>> the DT will specify only some NS channel to be used. The controller
>>> driver shouldn't be crippled just because you think Linux will never
>>> be run in Secure mode.
>>>
>>
>> Ok how do you handle that, I don't see that in the DT binding. As it
>> stands, you can unconditionally try to access the secure channel and
>> cause aborts if the platform is running in non-secure mode.
>>
> No. Please look at the dtsi again ....
>
>          mhu: mailbox@2b1f0000 {
>                  #mbox-cells = <1>;
>                  compatible = "arm,mbox-mhu";
>                  reg = <0 0x2b1f0000 0x1000>;
>                  interrupts = <0 36 4>, /* LP Non-Sec */
>                               <0 35 4>, /* HP Non-Sec */
>                               <0 37 4>; /* Secure */

One possible issue I can think of(though current driver design requests
irq only on channel startup, it could be moved to probe for optimization
in which case you need a way to make sure secure channel or irq is not
accessed)

>          };
>
>          mhu_client: scb@2e000000 {
>                  compatible = "fujitsu,mb86s70-scb-1.0";
>                  reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
>                  mboxes = <&mhu 1>;
>          };
>
> See the DT for mbox client specifies that it uses channel-1 which is
> High-Priority_Non-Secure channel.
>

Yes I noticed that, but still a wrong entry of another mhu_client with
secure channel might end up crashing MHU driver or even whole system.
Not sure but still probably one could try to play around with DT
overlays in future, just a thought. So you need to ensure that's handled
properly in the MHU driver.

Regards,
Sudeep

--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-26 14:00                         ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-26 14:00 UTC (permalink / raw)
  To: linux-arm-kernel



On 26/11/14 05:37, Jassi Brar wrote:
> On 25 November 2014 at 23:31, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>
>> On 25/11/14 16:51, Jassi Brar wrote:
>>>
>>> On 25 November 2014 at 20:07, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>>
>>>>
>>>>
>>>> On 20/11/14 12:34, Vincent Yang wrote:
>>>>>
>>>>>
>>>>> Add driver for the ARM Message-Handling-Unit (MHU).
>>>>>
>>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>>>>> ---
>>>>>     .../devicetree/bindings/mailbox/arm-mhu.txt        |  33 ++++
>>>>>     drivers/mailbox/Kconfig                            |   7 +
>>>>>     drivers/mailbox/Makefile                           |   2 +
>>>>>     drivers/mailbox/arm_mhu.c                          | 196
>>>>> +++++++++++++++++++++
>>>>>     4 files changed, 238 insertions(+)
>>>>>     create mode 100644
>>>>> Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>>     create mode 100644 drivers/mailbox/arm_mhu.c
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> new file mode 100644
>>>>> index 0000000..b1b9888
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
>>>>> @@ -0,0 +1,33 @@
>>>>> +ARM MHU Mailbox Driver
>>>>> +======================
>>>>> +
>>>>> +The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
>>>>> +3 independent channels/links to communicate with remote processor(s).
>>>>
>>>>
>>>>
>>>> I had reviewed this before and I see not all the comments are addressed.
>>>> I had mentioned that you can't add support to _SECURE_ channel in Linux
>>>> as you need to assume Linux runs in non-secure privilege(and I gather
>>>> that's the case even on this platform from other email in the thread)
>>>>
>>> Please revisit the old thread. After some discussion you had
>>> graciously allowed me to keep the secure channel ;)
>>> [
>>> ... Even though I don't like you have secure channel access in Linux, you
>>> have valid reasons. In case you decide to support it ....
>>> ]
>>
>>
>> Agreed but based on the other email in the same thread it looks like you
>> want to run the same kernel both in secure and no-secure mode on this
>> platform, in which case you _have_to_assume_ it's *non-secure only* always
>> unless you come up with some DT magic.
>>
> Yes, the S vs NS mode should ideally be defined in DT. The kernel
> image should remain the same.
>

That's good :)

>>>    It seems you still don't get my point that the driver should manage
>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>> the DT will specify only some NS channel to be used. The controller
>>> driver shouldn't be crippled just because you think Linux will never
>>> be run in Secure mode.
>>>
>>
>> Ok how do you handle that, I don't see that in the DT binding. As it
>> stands, you can unconditionally try to access the secure channel and
>> cause aborts if the platform is running in non-secure mode.
>>
> No. Please look at the dtsi again ....
>
>          mhu: mailbox at 2b1f0000 {
>                  #mbox-cells = <1>;
>                  compatible = "arm,mbox-mhu";
>                  reg = <0 0x2b1f0000 0x1000>;
>                  interrupts = <0 36 4>, /* LP Non-Sec */
>                               <0 35 4>, /* HP Non-Sec */
>                               <0 37 4>; /* Secure */

One possible issue I can think of(though current driver design requests
irq only on channel startup, it could be moved to probe for optimization
in which case you need a way to make sure secure channel or irq is not
accessed)

>          };
>
>          mhu_client: scb at 2e000000 {
>                  compatible = "fujitsu,mb86s70-scb-1.0";
>                  reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
>                  mboxes = <&mhu 1>;
>          };
>
> See the DT for mbox client specifies that it uses channel-1 which is
> High-Priority_Non-Secure channel.
>

Yes I noticed that, but still a wrong entry of another mhu_client with
secure channel might end up crashing MHU driver or even whole system.
Not sure but still probably one could try to play around with DT
overlays in future, just a thought. So you need to ensure that's handled
properly in the MHU driver.

Regards,
Sudeep

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-26 14:00                         ` Sudeep Holla
@ 2014-11-26 16:20                             ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-26 16:20 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya

On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
> On 26/11/14 05:37, Jassi Brar wrote:
>>

>>>>    It seems you still don't get my point that the driver should manage
>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>> the DT will specify only some NS channel to be used. The controller
>>>> driver shouldn't be crippled just because you think Linux will never
>>>> be run in Secure mode.
>>>>
>>>
>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>> stands, you can unconditionally try to access the secure channel and
>>> cause aborts if the platform is running in non-secure mode.
>>>
>> No. Please look at the dtsi again ....
>>
>>          mhu: mailbox@2b1f0000 {
>>                  #mbox-cells = <1>;
>>                  compatible = "arm,mbox-mhu";
>>                  reg = <0 0x2b1f0000 0x1000>;
>>                  interrupts = <0 36 4>, /* LP Non-Sec */
>>                               <0 35 4>, /* HP Non-Sec */
>>                               <0 37 4>; /* Secure */
>
>
> One possible issue I can think of(though current driver design requests
> irq only on channel startup, it could be moved to probe for optimization
> in which case you need a way to make sure secure channel or irq is not
> accessed)
>
As you see it is fine as such.
I don't think acquiring all irqs during probe is a good idea.
mbox_request_channel() is when we should actually be reserving
resources.

>>          };
>>
>>          mhu_client: scb@2e000000 {
>>                  compatible = "fujitsu,mb86s70-scb-1.0";
>>                  reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
>>                  mboxes = <&mhu 1>;
>>          };
>>
>> See the DT for mbox client specifies that it uses channel-1 which is
>> High-Priority_Non-Secure channel.
>>
>
> Yes I noticed that, but still a wrong entry of another mhu_client with
> secure channel might end up crashing MHU driver or even whole system.
> Not sure but still probably one could try to play around with DT
> overlays in future, just a thought. So you need to ensure that's handled
> properly in the MHU driver.
>
You worry too much ;)  what if some 'wrong entry' in DT specifies
memory where there is none or some voltage that could toast the board?

-Jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-26 16:20                             ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-26 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla@arm.com> wrote:
> On 26/11/14 05:37, Jassi Brar wrote:
>>

>>>>    It seems you still don't get my point that the driver should manage
>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>> the DT will specify only some NS channel to be used. The controller
>>>> driver shouldn't be crippled just because you think Linux will never
>>>> be run in Secure mode.
>>>>
>>>
>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>> stands, you can unconditionally try to access the secure channel and
>>> cause aborts if the platform is running in non-secure mode.
>>>
>> No. Please look at the dtsi again ....
>>
>>          mhu: mailbox at 2b1f0000 {
>>                  #mbox-cells = <1>;
>>                  compatible = "arm,mbox-mhu";
>>                  reg = <0 0x2b1f0000 0x1000>;
>>                  interrupts = <0 36 4>, /* LP Non-Sec */
>>                               <0 35 4>, /* HP Non-Sec */
>>                               <0 37 4>; /* Secure */
>
>
> One possible issue I can think of(though current driver design requests
> irq only on channel startup, it could be moved to probe for optimization
> in which case you need a way to make sure secure channel or irq is not
> accessed)
>
As you see it is fine as such.
I don't think acquiring all irqs during probe is a good idea.
mbox_request_channel() is when we should actually be reserving
resources.

>>          };
>>
>>          mhu_client: scb at 2e000000 {
>>                  compatible = "fujitsu,mb86s70-scb-1.0";
>>                  reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
>>                  mboxes = <&mhu 1>;
>>          };
>>
>> See the DT for mbox client specifies that it uses channel-1 which is
>> High-Priority_Non-Secure channel.
>>
>
> Yes I noticed that, but still a wrong entry of another mhu_client with
> secure channel might end up crashing MHU driver or even whole system.
> Not sure but still probably one could try to play around with DT
> overlays in future, just a thought. So you need to ensure that's handled
> properly in the MHU driver.
>
You worry too much ;)  what if some 'wrong entry' in DT specifies
memory where there is none or some voltage that could toast the board?

-Jassi

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 18:46     ` Lorenzo Pieralisi
  2014-11-25 18:59       ` Nicolas Pitre
@ 2014-11-26 16:29       ` Jassi Brar
  2014-11-26 17:18         ` Sudeep Holla
  1 sibling, 1 reply; 97+ messages in thread
From: Jassi Brar @ 2014-11-26 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 26 November 2014 at 00:16, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
> On Tue, Nov 25, 2014 at 05:42:32PM +0000, Nicolas Pitre wrote:
>> On Thu, 20 Nov 2014, Vincent Yang wrote:
>>
>> > The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>> > CPU/CLUSTER power up/down done by SCB over mailbox.
>> >
>> > Signed-off-by: Andy Green <andy.green@linaro.org>
>> > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> > Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> > Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> > ---
>> >  arch/arm/mach-mb86s7x/Makefile |   2 +-
>> >  arch/arm/mach-mb86s7x/mcpm.c   | 360 +++++++++++++++++++++++++++++++++++++++++
>> >  arch/arm/mach-mb86s7x/smc.S    |  27 ++++
>> >  3 files changed, 388 insertions(+), 1 deletion(-)
>> >  create mode 100644 arch/arm/mach-mb86s7x/mcpm.c
>> >  create mode 100644 arch/arm/mach-mb86s7x/smc.S
>> >
>> > diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
>> > index 97640b6..b0fa34b 100644
>> > --- a/arch/arm/mach-mb86s7x/Makefile
>> > +++ b/arch/arm/mach-mb86s7x/Makefile
>> > @@ -1 +1 @@
>> > -obj-$(CONFIG_ARCH_MB86S7X)   += board.o
>> > +obj-$(CONFIG_ARCH_MB86S7X)   += board.o mcpm.o smc.o
>> > diff --git a/arch/arm/mach-mb86s7x/mcpm.c b/arch/arm/mach-mb86s7x/mcpm.c
>> > new file mode 100644
>> > index 0000000..bf1b50a
>> > --- /dev/null
>> > +++ b/arch/arm/mach-mb86s7x/mcpm.c
>> > @@ -0,0 +1,360 @@
>> > +/*
>> > + * arch/arm/mach-mb86s7x/mcpm.c
>> > + * Copyright:        (C) 2013-2014 Fujitsu Semiconductor Limited
>> > + * Copyright:        (C) 2014 Linaro Ltd.
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License version 2 as
>> > + * published by the Free Software Foundation.
>> > + */
>> > +
>> > +#include <linux/io.h>
>> > +#include <linux/pm.h>
>> > +#include <linux/delay.h>
>> > +#include <linux/cpu_pm.h>
>> > +#include <linux/kernel.h>
>> > +#include <linux/module.h>
>> > +#include <linux/arm-cci.h>
>> > +#include <linux/spinlock.h>
>> > +#include <linux/suspend.h>
>> > +#include <linux/of_device.h>
>> > +#include <linux/irqchip/arm-gic.h>
>> > +#include <linux/platform_device.h>
>> > +
>> > +#include <soc/mb86s7x/scb_mhu.h>
>> > +
>> > +#include <asm/mcpm.h>
>> > +#include <asm/cp15.h>
>> > +#include <asm/cputype.h>
>> > +#include <asm/suspend.h>
>> > +#include <asm/idmap.h>
>> > +
>> > +#define S7X_MAX_CLUSTER      2
>> > +#define S7X_MAX_CPU  2
>> > +
>> > +#define MHU_SHM_OFFSET               0x3800
>> > +#define WFI_COLOR_OFFSET     0x3f00
>> > +#define TRAMPOLINE_OFFSET    0x3c00
>> > +#define RESET_OFFSET         (TRAMPOLINE_OFFSET + 0x3fc)
>> > +
>> > +static arch_spinlock_t mb86s7x_pm_lock = __ARCH_SPIN_LOCK_UNLOCKED;
>> > +static int mb86s7x_pm_use_count[S7X_MAX_CLUSTER][S7X_MAX_CPU];
>> > +extern void __iomem *mb86s7x_shm_base;
>> > +
>> > +#define AT_WFI_DO_NOTHING    0x0
>> > +#define AT_WFI_DO_SUSPEND    0x1
>> > +#define AT_WFI_DO_POWEROFF   0x2
>> > +#define AT_WFI_COLOR_MASK    0x3
>> > +
>> > +struct mb86s7x_cpu_gate {
>> > +     u32 payload_size;
>> > +     u32 cluster_class;
>> > +     u32 cluster_id;
>> > +     u32 cpu_id;
>> > +#define SCB_CPU_STATE_OFF    0x0
>> > +#define SCB_CPU_STATE_ON     0x1
>> > +#define SCB_CPU_STATE_SUSP   0x2
>> > +     u32 cpu_state;
>> > +};
>> > +
>> > +asmlinkage void mb86s70evb_outer_flush_all(void)
>> > +{
>> > +     outer_flush_all();
>> > +}
>> > +
>> > +#define mb86s70evb_exit_coherency_flush(level) { \
>> > +     asm volatile( \
>> > +     "stmfd  sp!, {fp, ip}\n\t" \
>> > +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
>> > +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
>> > +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
>> > +     "isb\n\t" \
>> > +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
>> > +     "bl     mb86s70evb_outer_flush_all\n\t" \
>>
>> This is wrong.  As mentioned already, this unconditionally flushes L2 in
>> all cases which shouldn't be necessary in the "louis" case.
>
> Is this a bL system with unified and architected L2s ? I think so, so
> what's the outercache for ?
>
Yes, the CA15 has 1MB and CA7 256KB L2 cache, that's it.
This thing sneaked in via a patch from someone desperate to make
Suspend-To-Ram (not yet submitted) work and I failed to spot it. We
should remove the mb86s70evb_outer_flush_all()

Thanks,
Jassi

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-26 16:20                             ` Jassi Brar
@ 2014-11-26 16:38                                 ` Sudeep Holla
  -1 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-26 16:38 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Sudeep Holla, Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya



On 26/11/14 16:20, Jassi Brar wrote:
> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>> On 26/11/14 05:37, Jassi Brar wrote:
>>>
>
>>>>>     It seems you still don't get my point that the driver should manage
>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>> the DT will specify only some NS channel to be used. The controller
>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>> be run in Secure mode.
>>>>>
>>>>
>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>> stands, you can unconditionally try to access the secure channel and
>>>> cause aborts if the platform is running in non-secure mode.
>>>>
>>> No. Please look at the dtsi again ....
>>>
>>>           mhu: mailbox@2b1f0000 {
>>>                   #mbox-cells = <1>;
>>>                   compatible = "arm,mbox-mhu";
>>>                   reg = <0 0x2b1f0000 0x1000>;
>>>                   interrupts = <0 36 4>, /* LP Non-Sec */
>>>                                <0 35 4>, /* HP Non-Sec */
>>>                                <0 37 4>; /* Secure */
>>
>>
>> One possible issue I can think of(though current driver design requests
>> irq only on channel startup, it could be moved to probe for optimization
>> in which case you need a way to make sure secure channel or irq is not
>> accessed)
>>
> As you see it is fine as such.

Agreed, but assuming some driver logic. I would like to see some way of
identifying that from DT if we adding the support for secure channel in
the driver else I prefer not to add it unless there is a real user of
it(which is not the case with your current patch set). That will be
handy if there's any issue in future due to some firmware that can't be
changed or upgraded.

Regards,
Sudeep

--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-26 16:38                                 ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-26 16:38 UTC (permalink / raw)
  To: linux-arm-kernel



On 26/11/14 16:20, Jassi Brar wrote:
> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla@arm.com> wrote:
>> On 26/11/14 05:37, Jassi Brar wrote:
>>>
>
>>>>>     It seems you still don't get my point that the driver should manage
>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>> the DT will specify only some NS channel to be used. The controller
>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>> be run in Secure mode.
>>>>>
>>>>
>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>> stands, you can unconditionally try to access the secure channel and
>>>> cause aborts if the platform is running in non-secure mode.
>>>>
>>> No. Please look at the dtsi again ....
>>>
>>>           mhu: mailbox at 2b1f0000 {
>>>                   #mbox-cells = <1>;
>>>                   compatible = "arm,mbox-mhu";
>>>                   reg = <0 0x2b1f0000 0x1000>;
>>>                   interrupts = <0 36 4>, /* LP Non-Sec */
>>>                                <0 35 4>, /* HP Non-Sec */
>>>                                <0 37 4>; /* Secure */
>>
>>
>> One possible issue I can think of(though current driver design requests
>> irq only on channel startup, it could be moved to probe for optimization
>> in which case you need a way to make sure secure channel or irq is not
>> accessed)
>>
> As you see it is fine as such.

Agreed, but assuming some driver logic. I would like to see some way of
identifying that from DT if we adding the support for secure channel in
the driver else I prefer not to add it unless there is a real user of
it(which is not the case with your current patch set). That will be
handy if there's any issue in future due to some firmware that can't be
changed or upgraded.

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-26 16:29       ` Jassi Brar
@ 2014-11-26 17:18         ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-26 17:18 UTC (permalink / raw)
  To: linux-arm-kernel



On 26/11/14 16:29, Jassi Brar wrote:
> On 26 November 2014 at 00:16, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
>> On Tue, Nov 25, 2014 at 05:42:32PM +0000, Nicolas Pitre wrote:
>>> On Thu, 20 Nov 2014, Vincent Yang wrote:
>>>
>>>> The remote firmware(SCB) owns the SMP control. This MCPM driver gets
>>>> CPU/CLUSTER power up/down done by SCB over mailbox.
>>>>
>>>> Signed-off-by: Andy Green <andy.green@linaro.org>
>>>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>>>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>>>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>>>> ---

[...]
>>>> +asmlinkage void mb86s70evb_outer_flush_all(void)
>>>> +{
>>>> +     outer_flush_all();
>>>> +}
>>>> +
>>>> +#define mb86s70evb_exit_coherency_flush(level) { \
>>>> +     asm volatile( \
>>>> +     "stmfd  sp!, {fp, ip}\n\t" \
>>>> +     "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR\n\t" \
>>>> +     "bic    r0, r0, #"__stringify(CR_C)"\n\t" \
>>>> +     "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR\n\t" \
>>>> +     "isb\n\t" \
>>>> +     "bl     v7_flush_dcache_"__stringify(level)"\n\t" \
>>>> +     "bl     mb86s70evb_outer_flush_all\n\t" \
>>>
>>> This is wrong.  As mentioned already, this unconditionally flushes L2 in
>>> all cases which shouldn't be necessary in the "louis" case.
>>
>> Is this a bL system with unified and architected L2s ? I think so, so
>> what's the outercache for ?
>>
> Yes, the CA15 has 1MB and CA7 256KB L2 cache, that's it.
> This thing sneaked in via a patch from someone desperate to make
> Suspend-To-Ram (not yet submitted) work and I failed to spot it. We
> should remove the mb86s70evb_outer_flush_all()

Good, so this platform doesn't have any outer cache at all ?
And that shouldn't sneak-in back again for suspend2ram case also.
So you can use the generic v7_exit_coherency_flush as is ?

Regards,
Sudeep

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

* [PATCH 3/9] ARM: MB86S7X: Add MCPM support
  2014-11-25 17:42   ` Nicolas Pitre
  2014-11-25 18:06     ` Sudeep Holla
  2014-11-25 18:46     ` Lorenzo Pieralisi
@ 2014-11-27  4:59     ` Jassi Brar
  2 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-27  4:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 25 November 2014 at 23:12, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

>
>> +
>> +static void
>> +mb86s7x_set_wficolor(unsigned clstr, unsigned cpu, unsigned clr)
>> +{
>> +     u8 val;
>> +
>> +     if (clr & ~AT_WFI_COLOR_MASK)
>> +             return;
>
> Shouldn't this be a BUG() rather than a return?
>
There are only 2 callers of this and they use explicit defines
AT_WFI_DO_xxx, so the check is actually lame and could be removed.

>> +
>> +     val = readb_relaxed(mb86s7x_shm_base
>> +                         + WFI_COLOR_OFFSET + clstr * 2 + cpu);
>> +     val &= ~AT_WFI_COLOR_MASK;
>> +     val |= clr;
>> +     writeb_relaxed(val, mb86s7x_shm_base
>> +                    + WFI_COLOR_OFFSET + clstr * 2 + cpu);
>> +}
>> +
>> +static int mb86s7x_pm_power_up(unsigned int cpu, unsigned int cluster)
>> +{
>> +     int ret = 0;
>> +
>> +     if (cluster >= S7X_MAX_CLUSTER || cpu >= S7X_MAX_CPU)
>> +             return -EINVAL;
>> +
>> +     pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
>> +
>> +     local_irq_disable();
>> +     arch_spin_lock(&mb86s7x_pm_lock);
>> +
>> +     mb86s7x_pm_use_count[cluster][cpu]++;
>> +
>> +     if (mb86s7x_pm_use_count[cluster][cpu] == 1) {
>> +             struct mb86s7x_cpu_gate cmd;
>> +
>> +             arch_spin_unlock(&mb86s7x_pm_lock);
>> +             local_irq_enable();
>
> From that point onward, nothing prevents concurrent execution in
> mb86s7x_pm_suspend() racing to call mb86s7x_set_wficolor() resulting in
> an incoherent state depending on who wins the race.
>
yeah, the set_wficolor() better be before we release the arch_spin_unlock.

Thanks,
Jassi

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-26 16:38                                 ` Sudeep Holla
@ 2014-11-27  5:11                                     ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-27  5:11 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya

On 26 November 2014 at 22:08, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>
>
> On 26/11/14 16:20, Jassi Brar wrote:
>>
>> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>>
>>> On 26/11/14 05:37, Jassi Brar wrote:
>>>>
>>>>
>>
>>>>>>     It seems you still don't get my point that the driver should
>>>>>> manage
>>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>>> the DT will specify only some NS channel to be used. The controller
>>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>>> be run in Secure mode.
>>>>>>
>>>>>
>>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>>> stands, you can unconditionally try to access the secure channel and
>>>>> cause aborts if the platform is running in non-secure mode.
>>>>>
>>>> No. Please look at the dtsi again ....
>>>>
>>>>           mhu: mailbox@2b1f0000 {
>>>>                   #mbox-cells = <1>;
>>>>                   compatible = "arm,mbox-mhu";
>>>>                   reg = <0 0x2b1f0000 0x1000>;
>>>>                   interrupts = <0 36 4>, /* LP Non-Sec */
>>>>                                <0 35 4>, /* HP Non-Sec */
>>>>                                <0 37 4>; /* Secure */
>>>
>>>
>>>
>>> One possible issue I can think of(though current driver design requests
>>> irq only on channel startup, it could be moved to probe for optimization
>>> in which case you need a way to make sure secure channel or irq is not
>>> accessed)
>>>
>> As you see it is fine as such.
>
>
> Agreed, but assuming some driver logic. I would like to see some way of
> identifying that from DT if we adding the support for secure channel in
> the driver else I prefer not to add it unless there is a real user of
> it(which is not the case with your current patch set). That will be
> handy if there's any issue in future due to some firmware that can't be
> changed or upgraded.
>
Could you please suggest some way of identifying that from DT if we
adding the support for secure channel in the driver?

-jassi
--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-27  5:11                                     ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-11-27  5:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 26 November 2014 at 22:08, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 26/11/14 16:20, Jassi Brar wrote:
>>
>> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>
>>> On 26/11/14 05:37, Jassi Brar wrote:
>>>>
>>>>
>>
>>>>>>     It seems you still don't get my point that the driver should
>>>>>> manage
>>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>>> the DT will specify only some NS channel to be used. The controller
>>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>>> be run in Secure mode.
>>>>>>
>>>>>
>>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>>> stands, you can unconditionally try to access the secure channel and
>>>>> cause aborts if the platform is running in non-secure mode.
>>>>>
>>>> No. Please look at the dtsi again ....
>>>>
>>>>           mhu: mailbox at 2b1f0000 {
>>>>                   #mbox-cells = <1>;
>>>>                   compatible = "arm,mbox-mhu";
>>>>                   reg = <0 0x2b1f0000 0x1000>;
>>>>                   interrupts = <0 36 4>, /* LP Non-Sec */
>>>>                                <0 35 4>, /* HP Non-Sec */
>>>>                                <0 37 4>; /* Secure */
>>>
>>>
>>>
>>> One possible issue I can think of(though current driver design requests
>>> irq only on channel startup, it could be moved to probe for optimization
>>> in which case you need a way to make sure secure channel or irq is not
>>> accessed)
>>>
>> As you see it is fine as such.
>
>
> Agreed, but assuming some driver logic. I would like to see some way of
> identifying that from DT if we adding the support for secure channel in
> the driver else I prefer not to add it unless there is a real user of
> it(which is not the case with your current patch set). That will be
> handy if there's any issue in future due to some firmware that can't be
> changed or upgraded.
>
Could you please suggest some way of identifying that from DT if we
adding the support for secure channel in the driver?

-jassi

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

* Re: [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
  2014-11-20 12:37   ` Vincent Yang
@ 2014-11-27  7:33     ` Alexandre Courbot
  -1 siblings, 0 replies; 97+ messages in thread
From: Alexandre Courbot @ 2014-11-27  7:33 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree, linux-gpio, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Grant Likely, Linus Walleij,
	andy.green, patches, jaswinder.singh, Vincent Yang,
	Tetsuya Nuriya

On Thu, Nov 20, 2014 at 9:37 PM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>  .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
>  drivers/gpio/Kconfig                               |   6 +
>  drivers/gpio/Makefile                              |   1 +
>  drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
>  4 files changed, 236 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>  create mode 100644 drivers/gpio/gpio-mb86s7x.c
>
> diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
> new file mode 100644
> index 0000000..38300ee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
> @@ -0,0 +1,18 @@
> +Fujitsu MB86S7x GPIO Controller
> +-------------------------------
> +
> +Required properties:
> +- compatible: Should be "fujitsu,mb86s70-gpio"
> +- gpio-controller: Marks the device node as a gpio controller.
> +- #gpio-cells: Should be <2>. The first cell is the pin number and the
> +  second cell is used to specify optional parameters:
> +   - bit 0 specifies polarity (0 for normal, 1 for inverted).

According to the example below and the code, "reg" and "clocks" are
also required properties.

> +
> +Examples:
> +       gpio0: gpio@31000000 {
> +               compatible = "fujitsu,mb86s70-gpio";
> +               reg = <0 0x31000000 0x10000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               clocks = <&clk_alw_2_1>;

Maybe add a "clocks-names" property so the clock can be given a meaningful name?

> +       };
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 0959ca9..493b7fe 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -181,6 +181,12 @@ config GPIO_F7188X
>           To compile this driver as a module, choose M here: the module will
>           be called f7188x-gpio.
>
> +config GPIO_MB86S7X
> +       bool "GPIO support for Fujitsu MB86S7x Platforms"
> +       depends on ARCH_MB86S7X
> +       help
> +         Say yes here to support the GPIO controller in LSI ZEVIO SoCs.
> +
>  config GPIO_MOXART
>         bool "MOXART GPIO support"
>         depends on ARCH_MOXART
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index e5d346c..eec0664 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X)    += gpio-max730x.o
>  obj-$(CONFIG_GPIO_MAX7300)     += gpio-max7300.o
>  obj-$(CONFIG_GPIO_MAX7301)     += gpio-max7301.o
>  obj-$(CONFIG_GPIO_MAX732X)     += gpio-max732x.o
> +obj-$(CONFIG_GPIO_MB86S7X)     += gpio-mb86s7x.o
>  obj-$(CONFIG_GPIO_MC33880)     += gpio-mc33880.o
>  obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
>  obj-$(CONFIG_GPIO_MCP23S08)    += gpio-mcp23s08.o
> diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
> new file mode 100644
> index 0000000..f0b2dc0
> --- /dev/null
> +++ b/drivers/gpio/gpio-mb86s7x.c
> @@ -0,0 +1,211 @@
> +/*
> + *  linux/drivers/gpio/gpio-mb86s7x.c
> + *
> + *  Copyright (C) 2014 Fujitsu Semiconductor Limited
> + *  Copyright (C) 2014 Linaro Ltd.
> + *
> + *  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, version 2 of the License.
> + *
> + *  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/io.h>
> +#include <linux/init.h>
> +#include <linux/clk.h>
> +#include <linux/gpio.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/ioport.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/slab.h>
> +
> +#define PDR(x) (0x0 + x)
> +#define DDR(x) (0x10 + x)
> +#define PFR(x) (0x20 + x)

Everytime these macros are used in the code, they are called in the
form PFR(offset / 8 * 4). How about doing this operation in the macros
instead of repeating it at every call?

> +
> +struct mb86s70_gpio_chip {
> +       spinlock_t lock;
> +       struct clk *clk;
> +       void __iomem *base;
> +       struct gpio_chip gc;
> +};
> +
> +static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
> +                                       struct mb86s70_gpio_chip, gc);

Please have a chip_to_mb86s70() macro to avoid that cumbersome call to
container_of in every function. Also I suggest you move the gpio_chip
to the top of your mb86s70_gpio_chip structure so the container_of
translates to a simple recast without any arithmetic.

> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + PFR(offset / 8 * 4));

Same, having mb86s70_readl()/mb86s70_writel() functions would prevent
you from explicitly doing pointer arithmetic every time you write a
register.

> +       val &= ~(1 << (offset % 8)); /* as gpio-port */

val &= ~BIT(offset % 8); ? Same everywhere it applies.

> +       writel(val, gchip->base + PFR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void mb86s70_gpio_free(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
> +                                       struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + PFR(offset / 8 * 4));
> +       val |= (1 << (offset % 8)); /* as peri-port */
> +       writel(val, gchip->base + PFR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +}
> +
> +static int mb86s70_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       unsigned char val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + DDR(offset / 8 * 4));
> +       val &= ~(1 << (offset % 8));
> +       writel(val, gchip->base + DDR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mb86s70_gpio_direction_output(struct gpio_chip *gc,
> +                                        unsigned offset, int value)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       unsigned char val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +
> +       val = readl(gchip->base + PDR(offset / 8 * 4));
> +       if (value)
> +               val |= (1 << (offset % 8));
> +       else
> +               val &= ~(1 << (offset % 8));
> +       writel(val, gchip->base + PDR(offset / 8 * 4));
> +
> +       val = readl(gchip->base + DDR(offset / 8 * 4));
> +       val |= (1 << (offset % 8));
> +       writel(val, gchip->base + DDR(offset / 8 * 4));
> +
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned char val;
> +
> +       val = readl(gchip->base + PDR(offset / 8 * 4));
> +       val &= (1 << (offset % 8));
> +       return val ? 1 : 0;

Shouldn't this function be protected by the spin lock as well?

These minor comments aside, the driver looks nice and simple.

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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
@ 2014-11-27  7:33     ` Alexandre Courbot
  0 siblings, 0 replies; 97+ messages in thread
From: Alexandre Courbot @ 2014-11-27  7:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 20, 2014 at 9:37 PM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:
> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
> ---
>  .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
>  drivers/gpio/Kconfig                               |   6 +
>  drivers/gpio/Makefile                              |   1 +
>  drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
>  4 files changed, 236 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>  create mode 100644 drivers/gpio/gpio-mb86s7x.c
>
> diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
> new file mode 100644
> index 0000000..38300ee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
> @@ -0,0 +1,18 @@
> +Fujitsu MB86S7x GPIO Controller
> +-------------------------------
> +
> +Required properties:
> +- compatible: Should be "fujitsu,mb86s70-gpio"
> +- gpio-controller: Marks the device node as a gpio controller.
> +- #gpio-cells: Should be <2>. The first cell is the pin number and the
> +  second cell is used to specify optional parameters:
> +   - bit 0 specifies polarity (0 for normal, 1 for inverted).

According to the example below and the code, "reg" and "clocks" are
also required properties.

> +
> +Examples:
> +       gpio0: gpio at 31000000 {
> +               compatible = "fujitsu,mb86s70-gpio";
> +               reg = <0 0x31000000 0x10000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               clocks = <&clk_alw_2_1>;

Maybe add a "clocks-names" property so the clock can be given a meaningful name?

> +       };
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 0959ca9..493b7fe 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -181,6 +181,12 @@ config GPIO_F7188X
>           To compile this driver as a module, choose M here: the module will
>           be called f7188x-gpio.
>
> +config GPIO_MB86S7X
> +       bool "GPIO support for Fujitsu MB86S7x Platforms"
> +       depends on ARCH_MB86S7X
> +       help
> +         Say yes here to support the GPIO controller in LSI ZEVIO SoCs.
> +
>  config GPIO_MOXART
>         bool "MOXART GPIO support"
>         depends on ARCH_MOXART
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index e5d346c..eec0664 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_MAX730X)    += gpio-max730x.o
>  obj-$(CONFIG_GPIO_MAX7300)     += gpio-max7300.o
>  obj-$(CONFIG_GPIO_MAX7301)     += gpio-max7301.o
>  obj-$(CONFIG_GPIO_MAX732X)     += gpio-max732x.o
> +obj-$(CONFIG_GPIO_MB86S7X)     += gpio-mb86s7x.o
>  obj-$(CONFIG_GPIO_MC33880)     += gpio-mc33880.o
>  obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
>  obj-$(CONFIG_GPIO_MCP23S08)    += gpio-mcp23s08.o
> diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
> new file mode 100644
> index 0000000..f0b2dc0
> --- /dev/null
> +++ b/drivers/gpio/gpio-mb86s7x.c
> @@ -0,0 +1,211 @@
> +/*
> + *  linux/drivers/gpio/gpio-mb86s7x.c
> + *
> + *  Copyright (C) 2014 Fujitsu Semiconductor Limited
> + *  Copyright (C) 2014 Linaro Ltd.
> + *
> + *  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, version 2 of the License.
> + *
> + *  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/io.h>
> +#include <linux/init.h>
> +#include <linux/clk.h>
> +#include <linux/gpio.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/ioport.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/slab.h>
> +
> +#define PDR(x) (0x0 + x)
> +#define DDR(x) (0x10 + x)
> +#define PFR(x) (0x20 + x)

Everytime these macros are used in the code, they are called in the
form PFR(offset / 8 * 4). How about doing this operation in the macros
instead of repeating it at every call?

> +
> +struct mb86s70_gpio_chip {
> +       spinlock_t lock;
> +       struct clk *clk;
> +       void __iomem *base;
> +       struct gpio_chip gc;
> +};
> +
> +static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
> +                                       struct mb86s70_gpio_chip, gc);

Please have a chip_to_mb86s70() macro to avoid that cumbersome call to
container_of in every function. Also I suggest you move the gpio_chip
to the top of your mb86s70_gpio_chip structure so the container_of
translates to a simple recast without any arithmetic.

> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + PFR(offset / 8 * 4));

Same, having mb86s70_readl()/mb86s70_writel() functions would prevent
you from explicitly doing pointer arithmetic every time you write a
register.

> +       val &= ~(1 << (offset % 8)); /* as gpio-port */

val &= ~BIT(offset % 8); ? Same everywhere it applies.

> +       writel(val, gchip->base + PFR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void mb86s70_gpio_free(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
> +                                       struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + PFR(offset / 8 * 4));
> +       val |= (1 << (offset % 8)); /* as peri-port */
> +       writel(val, gchip->base + PFR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +}
> +
> +static int mb86s70_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       unsigned char val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +       val = readl(gchip->base + DDR(offset / 8 * 4));
> +       val &= ~(1 << (offset % 8));
> +       writel(val, gchip->base + DDR(offset / 8 * 4));
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mb86s70_gpio_direction_output(struct gpio_chip *gc,
> +                                        unsigned offset, int value)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned long flags;
> +       unsigned char val;
> +
> +       spin_lock_irqsave(&gchip->lock, flags);
> +
> +       val = readl(gchip->base + PDR(offset / 8 * 4));
> +       if (value)
> +               val |= (1 << (offset % 8));
> +       else
> +               val &= ~(1 << (offset % 8));
> +       writel(val, gchip->base + PDR(offset / 8 * 4));
> +
> +       val = readl(gchip->base + DDR(offset / 8 * 4));
> +       val |= (1 << (offset % 8));
> +       writel(val, gchip->base + DDR(offset / 8 * 4));
> +
> +       spin_unlock_irqrestore(&gchip->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct mb86s70_gpio_chip *gchip =
> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
> +       unsigned char val;
> +
> +       val = readl(gchip->base + PDR(offset / 8 * 4));
> +       val &= (1 << (offset % 8));
> +       return val ? 1 : 0;

Shouldn't this function be protected by the spin lock as well?

These minor comments aside, the driver looks nice and simple.

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

* Re: [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
  2014-11-27  5:11                                     ` Jassi Brar
@ 2014-11-27 13:25                                         ` Sudeep Holla
  -1 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-27 13:25 UTC (permalink / raw)
  To: Jassi Brar
  Cc: Sudeep Holla, Vincent Yang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	Pawel Moll, Mark Rutland, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
	patches-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang, Tetsuya Nuriya



On 27/11/14 05:11, Jassi Brar wrote:
> On 26 November 2014 at 22:08, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>
>>
>> On 26/11/14 16:20, Jassi Brar wrote:
>>>
>>> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla-5wv7dgnIgG8@public.gmane.org> wrote:
>>>>
>>>> On 26/11/14 05:37, Jassi Brar wrote:
>>>>>
>>>>>
>>>
>>>>>>>      It seems you still don't get my point that the driver should
>>>>>>> manage
>>>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>>>> the DT will specify only some NS channel to be used. The controller
>>>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>>>> be run in Secure mode.
>>>>>>>
>>>>>>
>>>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>>>> stands, you can unconditionally try to access the secure channel and
>>>>>> cause aborts if the platform is running in non-secure mode.
>>>>>>
>>>>> No. Please look at the dtsi again ....
>>>>>
>>>>>            mhu: mailbox@2b1f0000 {
>>>>>                    #mbox-cells = <1>;
>>>>>                    compatible = "arm,mbox-mhu";
>>>>>                    reg = <0 0x2b1f0000 0x1000>;
>>>>>                    interrupts = <0 36 4>, /* LP Non-Sec */
>>>>>                                 <0 35 4>, /* HP Non-Sec */
>>>>>                                 <0 37 4>; /* Secure */
>>>>
>>>>
>>>>
>>>> One possible issue I can think of(though current driver design requests
>>>> irq only on channel startup, it could be moved to probe for optimization
>>>> in which case you need a way to make sure secure channel or irq is not
>>>> accessed)
>>>>
>>> As you see it is fine as such.
>>
>>
>> Agreed, but assuming some driver logic. I would like to see some way of
>> identifying that from DT if we adding the support for secure channel in
>> the driver else I prefer not to add it unless there is a real user of
>> it(which is not the case with your current patch set). That will be
>> handy if there's any issue in future due to some firmware that can't be
>> changed or upgraded.
>>
> Could you please suggest some way of identifying that from DT if we
> adding the support for secure channel in the driver?
>

Sorry, I don't have any idea yet on that as the general rule is not to
touch anything secure in kernel assuming Linux always runs in non-secure
mode.

Now if you need an exception, you need to propose the binding and take
up the discussion on the devicetree list.

Regards,
Sudeep

--
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	[flat|nested] 97+ messages in thread

* [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2014-11-27 13:25                                         ` Sudeep Holla
  0 siblings, 0 replies; 97+ messages in thread
From: Sudeep Holla @ 2014-11-27 13:25 UTC (permalink / raw)
  To: linux-arm-kernel



On 27/11/14 05:11, Jassi Brar wrote:
> On 26 November 2014 at 22:08, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>
>>
>> On 26/11/14 16:20, Jassi Brar wrote:
>>>
>>> On 26 November 2014 at 19:30, Sudeep Holla <sudeep.holla@arm.com> wrote:
>>>>
>>>> On 26/11/14 05:37, Jassi Brar wrote:
>>>>>
>>>>>
>>>
>>>>>>>      It seems you still don't get my point that the driver should
>>>>>>> manage
>>>>>>> all channels - S & NS. If Linux is running in NS mode on a platform,
>>>>>>> the DT will specify only some NS channel to be used. The controller
>>>>>>> driver shouldn't be crippled just because you think Linux will never
>>>>>>> be run in Secure mode.
>>>>>>>
>>>>>>
>>>>>> Ok how do you handle that, I don't see that in the DT binding. As it
>>>>>> stands, you can unconditionally try to access the secure channel and
>>>>>> cause aborts if the platform is running in non-secure mode.
>>>>>>
>>>>> No. Please look at the dtsi again ....
>>>>>
>>>>>            mhu: mailbox at 2b1f0000 {
>>>>>                    #mbox-cells = <1>;
>>>>>                    compatible = "arm,mbox-mhu";
>>>>>                    reg = <0 0x2b1f0000 0x1000>;
>>>>>                    interrupts = <0 36 4>, /* LP Non-Sec */
>>>>>                                 <0 35 4>, /* HP Non-Sec */
>>>>>                                 <0 37 4>; /* Secure */
>>>>
>>>>
>>>>
>>>> One possible issue I can think of(though current driver design requests
>>>> irq only on channel startup, it could be moved to probe for optimization
>>>> in which case you need a way to make sure secure channel or irq is not
>>>> accessed)
>>>>
>>> As you see it is fine as such.
>>
>>
>> Agreed, but assuming some driver logic. I would like to see some way of
>> identifying that from DT if we adding the support for secure channel in
>> the driver else I prefer not to add it unless there is a real user of
>> it(which is not the case with your current patch set). That will be
>> handy if there's any issue in future due to some firmware that can't be
>> changed or upgraded.
>>
> Could you please suggest some way of identifying that from DT if we
> adding the support for secure channel in the driver?
>

Sorry, I don't have any idea yet on that as the general rule is not to
touch anything secure in kernel assuming Linux always runs in non-secure
mode.

Now if you need an exception, you need to propose the binding and take
up the discussion on the devicetree list.

Regards,
Sudeep

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

* Re: [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
  2014-11-20 12:37   ` Vincent Yang
@ 2014-12-03 13:32     ` Linus Walleij
  -1 siblings, 0 replies; 97+ messages in thread
From: Linus Walleij @ 2014-12-03 13:32 UTC (permalink / raw)
  To: Vincent Yang
  Cc: devicetree, linux-gpio, linux-arm-kernel, Arnd Bergmann,
	Olof Johansson, Rob Herring, Pawel Moll, Mark Rutland,
	ijc+devicetree, Kumar Gala, Grant Likely, Alexandre Courbot,
	Andy Green, Patch Tracking, Jaswinder Singh, Vincent Yang,
	Tetsuya Nuriya

On Thu, Nov 20, 2014 at 1:37 PM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:

> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>

This is a very simple MMIO GPIO controller.

Why can this *not* just select GPIO_GENERIC and
use drivers/gpio/gpio-generic.c?

You need a smallish driver making use of the generic
MMIO library, see for example
drivers/gpio/gpio-74xx-mmio.c
or any other driver selecting GPIO_GENERIC.

Yours,
Linus Walleij

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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
@ 2014-12-03 13:32     ` Linus Walleij
  0 siblings, 0 replies; 97+ messages in thread
From: Linus Walleij @ 2014-12-03 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 20, 2014 at 1:37 PM, Vincent Yang
<vincent.yang.fujitsu@gmail.com> wrote:

> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>
> Signed-off-by: Andy Green <andy.green@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>

This is a very simple MMIO GPIO controller.

Why can this *not* just select GPIO_GENERIC and
use drivers/gpio/gpio-generic.c?

You need a smallish driver making use of the generic
MMIO library, see for example
drivers/gpio/gpio-74xx-mmio.c
or any other driver selecting GPIO_GENERIC.

Yours,
Linus Walleij

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

* Re: [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
  2014-11-27  7:33     ` Alexandre Courbot
@ 2014-12-11 16:00       ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-12-11 16:00 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Vincent Yang, devicetree, linux-gpio, linux-arm-kernel,
	Arnd Bergmann, Olof Johansson, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Grant Likely,
	Linus Walleij, Andy Green, Patch Tracking, Vincent Yang,
	Tetsuya Nuriya

On 27 November 2014 at 13:03, Alexandre Courbot <gnurou@gmail.com> wrote:
> On Thu, Nov 20, 2014 at 9:37 PM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> ---
>>  .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
>>  drivers/gpio/Kconfig                               |   6 +
>>  drivers/gpio/Makefile                              |   1 +
>>  drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
>>  4 files changed, 236 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>>  create mode 100644 drivers/gpio/gpio-mb86s7x.c
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>> new file mode 100644
>> index 0000000..38300ee
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>> @@ -0,0 +1,18 @@
>> +Fujitsu MB86S7x GPIO Controller
>> +-------------------------------
>> +
>> +Required properties:
>> +- compatible: Should be "fujitsu,mb86s70-gpio"
>> +- gpio-controller: Marks the device node as a gpio controller.
>> +- #gpio-cells: Should be <2>. The first cell is the pin number and the
>> +  second cell is used to specify optional parameters:
>> +   - bit 0 specifies polarity (0 for normal, 1 for inverted).
>
> According to the example below and the code, "reg" and "clocks" are
> also required properties.
>
OK, will add them as well.

>> +
>> +Examples:
>> +       gpio0: gpio@31000000 {
>> +               compatible = "fujitsu,mb86s70-gpio";
>> +               reg = <0 0x31000000 0x10000>;
>> +               gpio-controller;
>> +               #gpio-cells = <2>;
>> +               clocks = <&clk_alw_2_1>;
>
> Maybe add a "clocks-names" property so the clock can be given a meaningful name?
>
Other mb86s7x drivers don't use that either and we do just fine :)

>> +
>> +#define PDR(x) (0x0 + x)
>> +#define DDR(x) (0x10 + x)
>> +#define PFR(x) (0x20 + x)
>
> Everytime these macros are used in the code, they are called in the
> form PFR(offset / 8 * 4). How about doing this operation in the macros
> instead of repeating it at every call?
>
OK

>> +
>> +struct mb86s70_gpio_chip {
>> +       spinlock_t lock;
>> +       struct clk *clk;
>> +       void __iomem *base;
>> +       struct gpio_chip gc;
>> +};
>> +
>> +static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
>> +                                       struct mb86s70_gpio_chip, gc);
>
> Please have a chip_to_mb86s70() macro to avoid that cumbersome call to
> container_of in every function. Also I suggest you move the gpio_chip
> to the top of your mb86s70_gpio_chip structure so the container_of
> translates to a simple recast without any arithmetic.
>
OK

>> +       unsigned long flags;
>> +       u32 val;
>> +
>> +       spin_lock_irqsave(&gchip->lock, flags);
>> +       val = readl(gchip->base + PFR(offset / 8 * 4));
>
> Same, having mb86s70_readl()/mb86s70_writel() functions would prevent
> you from explicitly doing pointer arithmetic every time you write a
> register.
>
This becomes trivial after updating macros.

>> +       val &= ~(1 << (offset % 8)); /* as gpio-port */
>
> val &= ~BIT(offset % 8); ? Same everywhere it applies.
>
OK

>> +
>> +static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct mb86s70_gpio_chip *gchip =
>> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
>> +       unsigned char val;
>> +
>> +       val = readl(gchip->base + PDR(offset / 8 * 4));
>> +       val &= (1 << (offset % 8));
>> +       return val ? 1 : 0;
>
> Shouldn't this function be protected by the spin lock as well?
>
hmm... then we need to fix most other drivers as well :)

> These minor comments aside, the driver looks nice and simple.

Thanks for the review.
-Jassi

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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
@ 2014-12-11 16:00       ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-12-11 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 November 2014 at 13:03, Alexandre Courbot <gnurou@gmail.com> wrote:
> On Thu, Nov 20, 2014 at 9:37 PM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>> ---
>>  .../bindings/gpio/fujitsu,mb86s70-gpio.txt         |  18 ++
>>  drivers/gpio/Kconfig                               |   6 +
>>  drivers/gpio/Makefile                              |   1 +
>>  drivers/gpio/gpio-mb86s7x.c                        | 211 +++++++++++++++++++++
>>  4 files changed, 236 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>>  create mode 100644 drivers/gpio/gpio-mb86s7x.c
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>> new file mode 100644
>> index 0000000..38300ee
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/fujitsu,mb86s70-gpio.txt
>> @@ -0,0 +1,18 @@
>> +Fujitsu MB86S7x GPIO Controller
>> +-------------------------------
>> +
>> +Required properties:
>> +- compatible: Should be "fujitsu,mb86s70-gpio"
>> +- gpio-controller: Marks the device node as a gpio controller.
>> +- #gpio-cells: Should be <2>. The first cell is the pin number and the
>> +  second cell is used to specify optional parameters:
>> +   - bit 0 specifies polarity (0 for normal, 1 for inverted).
>
> According to the example below and the code, "reg" and "clocks" are
> also required properties.
>
OK, will add them as well.

>> +
>> +Examples:
>> +       gpio0: gpio at 31000000 {
>> +               compatible = "fujitsu,mb86s70-gpio";
>> +               reg = <0 0x31000000 0x10000>;
>> +               gpio-controller;
>> +               #gpio-cells = <2>;
>> +               clocks = <&clk_alw_2_1>;
>
> Maybe add a "clocks-names" property so the clock can be given a meaningful name?
>
Other mb86s7x drivers don't use that either and we do just fine :)

>> +
>> +#define PDR(x) (0x0 + x)
>> +#define DDR(x) (0x10 + x)
>> +#define PFR(x) (0x20 + x)
>
> Everytime these macros are used in the code, they are called in the
> form PFR(offset / 8 * 4). How about doing this operation in the macros
> instead of repeating it at every call?
>
OK

>> +
>> +struct mb86s70_gpio_chip {
>> +       spinlock_t lock;
>> +       struct clk *clk;
>> +       void __iomem *base;
>> +       struct gpio_chip gc;
>> +};
>> +
>> +static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct mb86s70_gpio_chip *gchip = container_of(gc,
>> +                                       struct mb86s70_gpio_chip, gc);
>
> Please have a chip_to_mb86s70() macro to avoid that cumbersome call to
> container_of in every function. Also I suggest you move the gpio_chip
> to the top of your mb86s70_gpio_chip structure so the container_of
> translates to a simple recast without any arithmetic.
>
OK

>> +       unsigned long flags;
>> +       u32 val;
>> +
>> +       spin_lock_irqsave(&gchip->lock, flags);
>> +       val = readl(gchip->base + PFR(offset / 8 * 4));
>
> Same, having mb86s70_readl()/mb86s70_writel() functions would prevent
> you from explicitly doing pointer arithmetic every time you write a
> register.
>
This becomes trivial after updating macros.

>> +       val &= ~(1 << (offset % 8)); /* as gpio-port */
>
> val &= ~BIT(offset % 8); ? Same everywhere it applies.
>
OK

>> +
>> +static int mb86s70_gpio_get(struct gpio_chip *gc, unsigned offset)
>> +{
>> +       struct mb86s70_gpio_chip *gchip =
>> +                       container_of(gc, struct mb86s70_gpio_chip, gc);
>> +       unsigned char val;
>> +
>> +       val = readl(gchip->base + PDR(offset / 8 * 4));
>> +       val &= (1 << (offset % 8));
>> +       return val ? 1 : 0;
>
> Shouldn't this function be protected by the spin lock as well?
>
hmm... then we need to fix most other drivers as well :)

> These minor comments aside, the driver looks nice and simple.

Thanks for the review.
-Jassi

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

* Re: [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
  2014-12-03 13:32     ` Linus Walleij
@ 2014-12-11 16:01       ` Jassi Brar
  -1 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-12-11 16:01 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Vincent Yang, devicetree, linux-gpio, linux-arm-kernel,
	Arnd Bergmann, Olof Johansson, Rob Herring, Pawel Moll,
	Mark Rutland, ijc+devicetree, Kumar Gala, Grant Likely,
	Alexandre Courbot, Andy Green, Patch Tracking, Vincent Yang,
	Tetsuya Nuriya

On 3 December 2014 at 19:02, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Thu, Nov 20, 2014 at 1:37 PM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>
>> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>
> This is a very simple MMIO GPIO controller.
>
> Why can this *not* just select GPIO_GENERIC and
> use drivers/gpio/gpio-generic.c?
>
The math isn't the simple shift operation that the gpio-generic.c assumes.

-jassi

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

* [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver
@ 2014-12-11 16:01       ` Jassi Brar
  0 siblings, 0 replies; 97+ messages in thread
From: Jassi Brar @ 2014-12-11 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 3 December 2014 at 19:02, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Thu, Nov 20, 2014 at 1:37 PM, Vincent Yang
> <vincent.yang.fujitsu@gmail.com> wrote:
>
>> Driver for Fujitsu MB86S7x SoCs that have a memory mapped GPIO controller.
>>
>> Signed-off-by: Andy Green <andy.green@linaro.org>
>> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
>> Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
>> Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
>
> This is a very simple MMIO GPIO controller.
>
> Why can this *not* just select GPIO_GENERIC and
> use drivers/gpio/gpio-generic.c?
>
The math isn't the simple shift operation that the gpio-generic.c assumes.

-jassi

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

end of thread, other threads:[~2014-12-11 16:01 UTC | newest]

Thread overview: 97+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-20 12:27 [PATCH 0/9] Support for Fujitsu MB86S7X SoCs Vincent Yang
2014-11-20 12:27 ` Vincent Yang
2014-11-20 12:35 ` [PATCH 3/9] ARM: MB86S7X: Add MCPM support Vincent Yang
2014-11-21 13:02   ` Arnd Bergmann
2014-11-21 13:24     ` Jassi Brar
2014-11-25 11:48   ` Sudeep Holla
2014-11-25 13:42     ` Andy Green
2014-11-25 14:24       ` Sudeep Holla
2014-11-25 16:43         ` Andy Green
2014-11-25 17:00           ` Nicolas Pitre
2014-11-25 17:39           ` Sudeep Holla
2014-11-25 20:31             ` Andy Green
2014-11-25 17:42   ` Nicolas Pitre
2014-11-25 18:06     ` Sudeep Holla
2014-11-25 18:55       ` Nicolas Pitre
2014-11-25 18:46     ` Lorenzo Pieralisi
2014-11-25 18:59       ` Nicolas Pitre
2014-11-25 19:21         ` Sudeep Holla
2014-11-26 16:29       ` Jassi Brar
2014-11-26 17:18         ` Sudeep Holla
2014-11-27  4:59     ` Jassi Brar
2014-11-20 12:37 ` [PATCH 5/9] gpio: Add Fujitsu MB86S7x GPIO driver Vincent Yang
2014-11-20 12:37   ` Vincent Yang
2014-11-27  7:33   ` Alexandre Courbot
2014-11-27  7:33     ` Alexandre Courbot
2014-12-11 16:00     ` Jassi Brar
2014-12-11 16:00       ` Jassi Brar
2014-12-03 13:32   ` Linus Walleij
2014-12-03 13:32     ` Linus Walleij
2014-12-11 16:01     ` Jassi Brar
2014-12-11 16:01       ` Jassi Brar
2014-11-20 12:38 ` [PATCH 6/9] mmc: sdhci: host: add new f_sdh30 Vincent Yang
2014-11-20 12:38   ` Vincent Yang
2014-11-20 15:22   ` Rob Herring
2014-11-20 15:22     ` Rob Herring
2014-11-20 16:59     ` Vincent Yang
2014-11-20 16:59       ` Vincent Yang
2014-11-20 18:18       ` Rob Herring
2014-11-20 18:18         ` Rob Herring
2014-11-21  1:18         ` Vincent Yang
2014-11-21  1:18           ` Vincent Yang
     [not found] ` <1416486442-25200-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
2014-11-20 12:30   ` [PATCH 1/9] ARM: Add platform support for Fujitsu MB86S7X SoCs Vincent Yang
2014-11-20 12:30     ` Vincent Yang
2014-11-20 12:34   ` [PATCH 2/9] mailbox: arm_mhu: add driver for ARM MHU controller Vincent Yang
2014-11-20 12:34     ` Vincent Yang
     [not found]     ` <1416486872-25301-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
2014-11-25 14:37       ` Sudeep Holla
2014-11-25 14:37         ` Sudeep Holla
     [not found]         ` <54749429.9080505-5wv7dgnIgG8@public.gmane.org>
2014-11-25 16:51           ` Jassi Brar
2014-11-25 16:51             ` Jassi Brar
     [not found]             ` <CAJe_ZhciCP2VbmRtrq9d14WhfLhnC-xaitCCiW_6Yf1S-0sdUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-25 18:01               ` Sudeep Holla
2014-11-25 18:01                 ` Sudeep Holla
     [not found]                 ` <5474C3DD.5060706-5wv7dgnIgG8@public.gmane.org>
2014-11-26  5:37                   ` Jassi Brar
2014-11-26  5:37                     ` Jassi Brar
2014-11-26  5:44                     ` Andy Green
     [not found]                     ` <CAJe_ZhfkcSv7oBfXdiW5=F0bZvv+9z3m90cXdy=O66VwZWCQnw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-26 14:00                       ` Sudeep Holla
2014-11-26 14:00                         ` Sudeep Holla
     [not found]                         ` <5475DD19.9000107-5wv7dgnIgG8@public.gmane.org>
2014-11-26 16:20                           ` Jassi Brar
2014-11-26 16:20                             ` Jassi Brar
     [not found]                             ` <CAJe_ZheKfEkdzcNE_5cpDg4qbYNLEJ=kKi+ScRf2=a8irAfnDg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-26 16:38                               ` Sudeep Holla
2014-11-26 16:38                                 ` Sudeep Holla
     [not found]                                 ` <547601EF.7070307-5wv7dgnIgG8@public.gmane.org>
2014-11-27  5:11                                   ` Jassi Brar
2014-11-27  5:11                                     ` Jassi Brar
     [not found]                                     ` <CAJe_Zhdmup3DB5R3gufiveYtOOU+zrMQJVanQxbjSQ996=ZLXQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-27 13:25                                       ` Sudeep Holla
2014-11-27 13:25                                         ` Sudeep Holla
2014-11-20 12:36   ` [PATCH 4/9] clk: Add clock driver for mb86s7x Vincent Yang
2014-11-20 12:36     ` Vincent Yang
     [not found]     ` <1416486975-25385-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
2014-11-21 13:03       ` Arnd Bergmann
2014-11-21 13:03         ` Arnd Bergmann
2014-11-21 13:22         ` Jassi Brar
2014-11-21 13:22           ` Jassi Brar
     [not found]           ` <CAJe_ZhcxHnoUeBUk3w=_xyk5oMAuena9RjDnyRvzLtV2=LpQxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-21 14:34             ` Arnd Bergmann
2014-11-21 14:34               ` Arnd Bergmann
2014-11-21 16:36               ` Jassi Brar
2014-11-21 16:36                 ` Jassi Brar
     [not found]                 ` <CAJe_Zhdg0tRx1SiACpCci3B2XaCxECGvkE7D=fne6vch4Bhk-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-21 17:15                   ` Arnd Bergmann
2014-11-21 17:15                     ` Arnd Bergmann
2014-11-21 17:58                     ` Jassi Brar
2014-11-21 17:58                       ` Jassi Brar
2014-11-21 20:12                       ` Arnd Bergmann
2014-11-21 20:12                         ` Arnd Bergmann
2014-11-20 12:38   ` [PATCH 7/9] dt: mb86s7x: add dt files for MB86S7x evbs Vincent Yang
2014-11-20 12:38     ` Vincent Yang
     [not found]     ` <1416487126-25509-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
2014-11-21 14:26       ` Arnd Bergmann
2014-11-21 14:26         ` Arnd Bergmann
2014-11-21 16:49         ` Jassi Brar
2014-11-21 16:49           ` Jassi Brar
     [not found]           ` <CAJe_ZhfJBftYd7oYNqUsgZsVZS8ccRA5XngJ=msRnt7RSE+C2Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-21 17:09             ` Arnd Bergmann
2014-11-21 17:09               ` Arnd Bergmann
2014-11-21 17:35               ` Jassi Brar
2014-11-21 17:35                 ` Jassi Brar
2014-11-21 20:14                 ` Arnd Bergmann
2014-11-21 20:14                   ` Arnd Bergmann
2014-11-20 12:39   ` [PATCH 8/9] of: add Fujitsu vendor prefix Vincent Yang
2014-11-20 12:39     ` Vincent Yang
     [not found]     ` <1416487165-25551-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
2014-11-20 15:07       ` Rob Herring
2014-11-20 15:07         ` Rob Herring
2014-11-20 12:40 ` [PATCH 9/9] ARM: MB86S7x: Add configs Vincent Yang

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