Devicetree
 help / color / mirror / Atom feed
* [PATCH v0 12/15] ARM: STi: DT: STiH416: 416 DT Entry for clockgen B/C/D/E/F
From: Gabriel FERNANDEZ @ 2014-02-27 15:24 UTC (permalink / raw)
  To: mturquette, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rob, linux, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel
  Cc: Lee Jones, Gabriel Fernandez, Pankaj Dev
In-Reply-To: <1393514668-17440-1-git-send-email-gabriel.fernandez@st.com>

Patch adds DT entries for clockgen B/C/D/E/F

Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
---
 arch/arm/boot/dts/stih416-clock.dtsi | 170 +++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
index f63b0a1..6b2e387 100644
--- a/arch/arm/boot/dts/stih416-clock.dtsi
+++ b/arch/arm/boot/dts/stih416-clock.dtsi
@@ -503,5 +503,175 @@
 						/* Remaining outputs unused */
 			};
 		};
+                /*
+                 * Frequency synthesizers on the SASG2.
+                 *
+                 */
+                CLOCKGEN_B0: CLOCKGEN_B0 {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs216", "st,quadfs";
+                        reg = <0xfee108b4 0x44>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_S_USB48",
+                                             "CLK_S_DSS",
+                                             "CLK_S_STFE_FRC_2",
+                                             "CLK_S_THSENS_SCARD";
+                };
+
+                CLOCKGEN_B1: CLOCKGEN_B1 {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs216", "st,quadfs";
+                        reg = <0xfe8308c4 0x44>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_S_PCM_0",
+                                             "CLK_S_PCM_1",
+                                             "CLK_S_PCM_2",
+                                             "CLK_S_PCM_3";
+                };
+
+                CLOCKGEN_C: CLOCKGEN_C {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs432", "st,quadfs";
+                        reg = <0xfe8307d0 0x44>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_S_C_FS0_CH0",
+                                             "CLK_S_C_VCC_SD",
+                                             "CLK_S_C_FS0_CH2";
+                };
+
+                CLK_S_VCC_HD: CLK_S_VCC_HD {
+                        #clock-cells = <0>;
+                        compatible = "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux";
+                        reg = <0xfe8308b8 4>; /* SYSCFG2558 */
+
+                        clocks = <&CLK_SYSIN>, <&CLOCKGEN_C 0>;
+                };
+
+                /*
+                 * Add a dummy clock for the HDMI PHY for the VCC input mux
+                 */
+                CLK_S_TMDS_FROMPHY: CLK_S_TMDS_FROMPHY {
+                        #clock-cells = <0>;
+                        compatible = "fixed-clock";
+                        clock-frequency = <0>;
+                };
+
+                CLOCKGEN_C_VCC: CLOCKGEN_C_VCC {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
+                        reg = <0xfe8308ac 12>; /* SYSCFG2555,2556,2557 */
+
+                        clocks = <&CLK_S_VCC_HD>, <&CLOCKGEN_C 1>,
+                                 <&CLK_S_TMDS_FROMPHY>, <&CLOCKGEN_C 2>;
+
+                        clock-output-names  =
+                                "CLK_S_PIX_HDMI",  "CLK_S_PIX_DVO",
+                                "CLK_S_OUT_DVO",   "CLK_S_PIX_HD",
+                                "CLK_S_HDDAC",     "CLK_S_DENC",
+                                "CLK_S_SDDAC",     "CLK_S_PIX_MAIN",
+                                "CLK_S_PIX_AUX",   "CLK_S_STFE_FRC_0",
+                                "CLK_S_REF_MCRU",  "CLK_S_SLAVE_MCRU",
+                                "CLK_S_TMDS_HDMI", "CLK_S_HDMI_REJECT_PLL",
+                                "CLK_S_THSENS";
+                };
+
+                CLOCKGEN_D: CLOCKGEN_D {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs216", "st,quadfs";
+                        reg = <0xfee107e0 0x44>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_S_CCSC",
+                                             "CLK_S_STFE_FRC_1",
+                                             "CLK_S_TSOUT_1",
+                                             "CLK_S_MCHI";
+                };
+
+		/*
+		 * Frequency synthesizers on the MPE42
+		 */
+                CLOCKGEN_E: CLOCKGEN_E {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs660-E", "st,quadfs";
+                        reg = <0xfd3208bc 0xB0>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_M_PIX_MDTP_0",
+                                             "CLK_M_PIX_MDTP_1",
+                                             "CLK_M_PIX_MDTP_2",
+                                             "CLK_M_MPELPC";
+                };
+
+                CLOCKGEN_F: CLOCKGEN_F {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-quadfs660-F", "st,quadfs";
+                        reg = <0xfd320878 0xF0>;
+
+                        clocks = <&CLK_SYSIN>;
+                        clock-output-names = "CLK_M_MAIN_VIDFS",
+                                             "CLK_M_HVA_FS",
+                                             "CLK_M_FVDP_VCPU",
+					     "CLK_M_FVDP_PROC_FS";
+                };
+
+                CLK_M_FVDP_PROC: CLK_M_FVDP_PROC {
+                        #clock-cells = <0>;
+                        compatible = "st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux";
+                        reg = <0xfd320910 4>; /* SYSCFG8580 */
+
+                        clocks = <&CLK_M_A1_DIV2 0>, <&CLOCKGEN_F 3>;
+                };
+
+                CLK_M_HVA: CLK_M_HVA {
+                        #clock-cells = <0>;
+                        compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux";
+                        reg = <0xfd690868 4>; /* SYSCFG9538 */
+
+                        clocks = <&CLOCKGEN_F 1>, <&CLK_M_A1_DIV0 3>;
+                };
+
+                CLK_M_F_VCC_HD: CLK_M_F_VCC_HD {
+                        #clock-cells = <0>;
+                        compatible = "st,stih416-clkgenf-vcc-hd", "st,clkgen-mux";
+                        reg = <0xfd32086c 4>; /* SYSCFG8539 */
+
+                        clocks = <&CLOCKGEN_C_VCC 7>, <&CLOCKGEN_F 0>;
+                };
+
+                CLK_M_F_VCC_SD: CLK_M_F_VCC_SD {
+                        #clock-cells = <0>;
+                        compatible = "st,stih416-clkgenf-vcc-sd", "st,clkgen-mux";
+                        reg = <0xfd32086c 4>; /* SYSCFG8539 */
+
+                        clocks = <&CLOCKGEN_C_VCC 8>, <&CLOCKGEN_F 1>;
+                };
+
+                /*
+                 * Add a dummy clock for the HDMIRx external signal clock
+                 */
+                CLK_M_PIX_HDMIRX_SAS: CLK_M_PIX_HDMIRX_SAS {
+                        #clock-cells = <0>;
+                        compatible = "fixed-clock";
+                        clock-frequency = <0>;
+                };
+
+                CLOCKGEN_F_VCC: CLOCKGEN_F_VCC {
+                        #clock-cells = <1>;
+                        compatible = "st,stih416-clkgenf", "st,clkgen-vcc";
+                        reg = <0xfd32086c 12>; /* SYSCFG8539,8540,8541 */
+
+                        clocks = <&CLK_M_F_VCC_HD>, <&CLK_M_F_VCC_SD>,
+                                 <&CLOCKGEN_F 0>, <&CLK_M_PIX_HDMIRX_SAS>;
+
+                        clock-output-names  =
+                                "CLK_M_PIX_MAIN_PIPE",  "CLK_M_PIX_AUX_PIPE",
+                                "CLK_M_PIX_MAIN_CRU",   "CLK_M_PIX_AUX_CRU",
+                                "CLK_M_XFER_BE_COMPO",  "CLK_M_XFER_PIP_COMPO",
+                                "CLK_M_XFER_AUX_COMPO", "CLK_M_VSENS",
+                                "CLK_M_PIX_HDMIRX_0",   "CLK_M_PIX_HDMIRX_1";
+                };
 	};
 };
-- 
1.9.0

^ permalink raw reply related

* [PATCH v0 13/15] ARM: STi: DT: STiH416: 416 DT Entry for clockgen A9/DDR/GPU
From: Gabriel FERNANDEZ @ 2014-02-27 15:24 UTC (permalink / raw)
  To: mturquette-QSEj5FYQhm4dnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, rob-VoJi6FS/r0vR7s880joybQ,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Lee Jones, Gabriel Fernandez, Pankaj Dev
In-Reply-To: <1393514668-17440-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

Patch adds DT entries for clockgen A9/DDR/GPU

Signed-off-by: Pankaj Dev <pankaj.dev-qxv4g6HH51o@public.gmane.org>
---
 arch/arm/boot/dts/stih416-clock.dtsi | 79 ++++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
index 6b2e387..5ff0e6f 100644
--- a/arch/arm/boot/dts/stih416-clock.dtsi
+++ b/arch/arm/boot/dts/stih416-clock.dtsi
@@ -26,15 +26,6 @@
 		};
 
 		/*
-		 * ARM Peripheral clock for timers
-		 */
-		arm_periph_clk: arm_periph_clk {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <600000000>;
-		};
-
-		/*
 		 * ClockGenAs on SASG2
 		 */
 		clockgenA@fee62000 {
@@ -503,6 +494,44 @@
 						/* Remaining outputs unused */
 			};
 		};
+
+		/*
+		 * A9 PLL.
+		 *
+		 */
+		clockgenA9 {
+			reg = <0xfdde08b0 0x70>;
+
+			CLOCKGEN_A9_PLL: CLOCKGEN_A9_PLL {
+				#clock-cells = <1>;
+				compatible = "st,stih416-plls-c32-a9", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+				clock-output-names = "CLOCKGEN_A9_PLL_ODF";
+			};
+		};
+
+		/*
+		 * ARM CPU related clocks.
+		 */
+		CLK_M_A9: CLK_M_A9 {
+			#clock-cells = <0>;
+			compatible = "st,stih416-clkgen-a9-mux", "st,clkgen-mux";
+			reg = <0xfdde08ac 0x4>;
+			clocks = <&CLOCKGEN_A9_PLL 0>, <&CLOCKGEN_A9_PLL 0>, <&CLK_M_A0_DIV1 2>, <&CLK_M_A9_EXT2F_DIV2>;
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: CLK_M_A9_PERIPHS {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clocks = <&CLK_M_A9>;
+			clock-div = <2>;
+			clock-mult = <1>;
+		};
+
                 /*
                  * Frequency synthesizers on the SASG2.
                  *
@@ -673,5 +702,37 @@
                                 "CLK_M_XFER_AUX_COMPO", "CLK_M_VSENS",
                                 "CLK_M_PIX_HDMIRX_0",   "CLK_M_PIX_HDMIRX_1";
                 };
+
+		/*
+		 * DDR PLL.
+		 *
+		 */
+		clockgenDDR {
+			reg = <0xfdde07d8 0x110>;
+
+			CLOCKGEN_DDR_PLL: CLOCKGEN_DDR_PLL {
+				#clock-cells = <1>;
+				compatible = "st,stih416-plls-c32-ddr", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+				clock-output-names = "CLOCKGEN_DDR0", "CLOCKGEN_DDR1";
+			};
+		};
+
+		/*
+		 * GPU PLL.
+		 *
+		 */
+		clockgenGPU {
+			reg = <0xfd68ff00 0x910>;
+
+			CLOCKGEN_GPU_PLL: CLOCKGEN_GPU_PLL {
+				#clock-cells = <1>;
+				compatible = "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32";
+
+				clocks = <&CLK_SYSIN>;
+				clock-output-names = "CLOCKGEN_GPU_PLL";
+			};
+		};
 	};
 };
-- 
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

* [PATCH v0 14/15] ARM: STi: DT: STiH415: 415 DT Entry for clockgen A0/1/10/11/12
From: Gabriel FERNANDEZ @ 2014-02-27 15:24 UTC (permalink / raw)
  To: mturquette, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rob, linux, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel
  Cc: Pankaj Dev, Lee Jones, Gabriel Fernandez
In-Reply-To: <1393514668-17440-1-git-send-email-gabriel.fernandez@st.com>

Patch adds DT entries for clockgen A0/1/10/11/12

Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 arch/arm/boot/dts/stih415-clks.h     |  11 +
 arch/arm/boot/dts/stih415-clock.dtsi | 475 ++++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/stih415.dtsi       |   6 +-
 3 files changed, 484 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-clks.h

diff --git a/arch/arm/boot/dts/stih415-clks.h b/arch/arm/boot/dts/stih415-clks.h
new file mode 100644
index 0000000..341c05b
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-clks.h
@@ -0,0 +1,11 @@
+/*
+ * This header provides constants clk index STMicroelectronics
+ * STiH415 SoC.
+ */
+#ifndef _CLK_STIH415
+#define _CLK_STIH415
+
+/* CLOCKGEN A0 */
+#define CLK_S_ICN_REG_0		0
+
+#endif
diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
index 174c799..24a7508 100644
--- a/arch/arm/boot/dts/stih415-clock.dtsi
+++ b/arch/arm/boot/dts/stih415-clock.dtsi
@@ -5,8 +5,15 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#include "stih415-clks.h"
+
 / {
 	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
 		/*
 		 * Fixed 30MHz oscillator input to SoC
 		 */
@@ -26,13 +33,471 @@
 		};
 
 		/*
-		 * Bootloader initialized system infrastructure clock for
-		 * serial devices.
+		 * ClockGenAs on SASG1
+		 */
+		clockgenA@fee62000 {
+			reg = <0xfee62000 0xb48>;
+
+			CLK_S_A0_PLL: CLK_S_A0_PLL {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-plls-c65";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_S_A0_PLL0_HS",
+						     "CLK_S_A0_PLL0_LS",
+						     "CLK_S_A0_PLL1";
+			};
+
+			CLK_S_A0_OSC_PREDIV: CLK_S_A0_OSC_PREDIV {
+				#clock-cells = <0>;
+				compatible = "st,clkgena-prediv-c65",
+					     "st,clkgena-prediv";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_S_A0_OSC_PREDIV";
+			};
+
+			CLK_S_A0_HS: CLK_S_A0_HS {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c65-hs",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_S_A0_OSC_PREDIV>,
+					 <&CLK_S_A0_PLL 0>, /* PLL0 HS */
+					 <&CLK_S_A0_PLL 2>; /* PLL1 */
+
+				clock-output-names = "CLK_S_FDMA_0",
+						     "CLK_S_FDMA_1",
+						     ""; /* CLK_S_JIT_SENSE */
+						     /* Fourth output unused */
+			};
+
+			CLK_S_A0_LS: CLK_S_A0_LS {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c65-ls",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_S_A0_OSC_PREDIV>,
+					 <&CLK_S_A0_PLL 1>, /* PLL0 LS */
+					 <&CLK_S_A0_PLL 2>; /* PLL1 */
+
+				clock-output-names = "CLK_S_ICN_REG_0",
+						     "CLK_S_ICN_IF_0",
+						     "CLK_S_ICN_REG_LP_0",
+						     "CLK_S_EMISS",
+						     "CLK_S_ETH1_PHY",
+						     "CLK_S_MII_REF_OUT";
+						 /* Remaining outputs unused */
+			};
+		};
+
+		clockgenA@fee81000 {
+			reg = <0xfee81000 0xb48>;
+
+			CLK_S_A1_PLL: CLK_S_A1_PLL {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-plls-c65";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_S_A1_PLL0_HS",
+						     "CLK_S_A1_PLL0_LS",
+						     "CLK_S_A1_PLL1";
+			};
+
+			CLK_S_A1_OSC_PREDIV: CLK_S_A1_OSC_PREDIV {
+				#clock-cells = <0>;
+				compatible = "st,clkgena-prediv-c65",
+					     "st,clkgena-prediv";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_S_A1_OSC_PREDIV";
+			};
+
+			CLK_S_A1_HS: CLK_S_A1_HS {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c65-hs",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_S_A1_OSC_PREDIV>,
+					 <&CLK_S_A1_PLL 0>, /* PLL0 HS */
+					 <&CLK_S_A1_PLL 2>; /* PLL1 */
+
+				clock-output-names = "", /* Reserved */
+						     "", /* Reserved */
+						     "CLK_S_STAC_PHY",
+						     "CLK_S_VTAC_TX_PHY";
+			};
+
+			CLK_S_A1_LS: CLK_S_A1_LS {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c65-ls",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_S_A1_OSC_PREDIV>,
+					 <&CLK_S_A1_PLL 1>, /* PLL0 LS */
+					 <&CLK_S_A1_PLL 2>; /* PLL1 */
+
+				clock-output-names = "CLK_S_ICN_IF_2",
+						     "CLK_S_CARD_MMC",
+						     "CLK_S_ICN_IF_1",
+						     "CLK_S_GMAC0_PHY",
+						     "CLK_S_NAND_CTRL",
+						     "", /* Reserved */
+						     "CLK_S_MII0_REF_OUT",
+						     ""; /* CLK_S_STAC_SYS */
+						 /* Remaining outputs unused */
+			};
+		};
+
+		/*
+		 * ClockGenAs on MPE41
 		 */
-		CLKS_ICN_REG_0: CLKS_ICN_REG_0 {
+		clockgenA@fde12000 {
+			reg = <0xfde12000 0xb50>;
+
+			CLK_M_A0_PLL0: CLK_M_A0_PLL0 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A0_PLL0_PHI0",
+						     "CLK_M_A0_PLL0_PHI1",
+						     "CLK_M_A0_PLL0_PHI2",
+						     "CLK_M_A0_PLL0_PHI3";
+			};
+
+			CLK_M_A0_PLL1: CLK_M_A0_PLL1 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A0_PLL1_PHI0",
+						     "CLK_M_A0_PLL1_PHI1",
+						     "CLK_M_A0_PLL1_PHI2",
+						     "CLK_M_A0_PLL1_PHI3";
+			};
+
+			CLK_M_A0_OSC_PREDIV: CLK_M_A0_OSC_PREDIV {
+				#clock-cells = <0>;
+				compatible = "st,clkgena-prediv-c32",
+					     "st,clkgena-prediv";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A0_OSC_PREDIV";
+			};
+
+			CLK_M_A0_DIV0: CLK_M_A0_DIV0 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf0",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A0_OSC_PREDIV>,
+					 <&CLK_M_A0_PLL0 0>, /* PLL0 PHI0 */
+					 <&CLK_M_A0_PLL1 0>; /* PLL1 PHI0 */
+
+				clock-output-names = "CLK_M_APB_PM", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "CLK_M_PP_DMU_0",
+						     "CLK_M_PP_DMU_1",
+						     "CLK_M_ICM_DISP",
+						     ""; /* Unused */
+			};
+
+			CLK_M_A0_DIV1: CLK_M_A0_DIV1 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf1",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A0_OSC_PREDIV>,
+					 <&CLK_M_A0_PLL0 1>, /* PLL0 PHI1 */
+					 <&CLK_M_A0_PLL1 1>; /* PLL1 PHI1 */
+
+				clock-output-names = "", /* Unused */
+						     "", /* Unused */
+						     "CLK_M_A9_EXT2F",
+						     "CLK_M_ST40RT",
+						     "CLK_M_ST231_DMU_0",
+						     "CLK_M_ST231_DMU_1",
+						     "CLK_M_ST231_AUD",
+						     "CLK_M_ST231_GP_0";
+			};
+
+			CLK_M_A0_DIV2: CLK_M_A0_DIV2 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf2",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A0_OSC_PREDIV>,
+					 <&CLK_M_A0_PLL0 2>, /* PLL0 PHI2 */
+					 <&CLK_M_A0_PLL1 2>; /* PLL1 PHI2 */
+
+				clock-output-names = "CLK_M_ST231_GP_1",
+						     "CLK_M_ICN_CPU",
+						     "CLK_M_ICN_STAC",
+						     "CLK_M_ICN_DMU_0",
+						     "CLK_M_ICN_DMU_1",
+						     "", /* Unused */
+						     "", /* Unused */
+						     ""; /* Unused */
+			};
+
+			CLK_M_A0_DIV3: CLK_M_A0_DIV3 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf3",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A0_OSC_PREDIV>,
+					 <&CLK_M_A0_PLL0 3>, /* PLL0 PHI3 */
+					 <&CLK_M_A0_PLL1 3>; /* PLL1 PHI3 */
+
+				clock-output-names = "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "CLK_M_ICN_ERAM",
+						     "CLK_M_A9_TRACE";
+			};
+		};
+
+		clockgenA@fd6db000 {
+			reg = <0xfd6db000 0xb50>;
+
+			CLK_M_A1_PLL0: CLK_M_A1_PLL0 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A1_PLL0_PHI0",
+						     "CLK_M_A1_PLL0_PHI1",
+						     "CLK_M_A1_PLL0_PHI2",
+						     "CLK_M_A1_PLL0_PHI3";
+			};
+
+			CLK_M_A1_PLL1: CLK_M_A1_PLL1 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A1_PLL1_PHI0",
+						     "CLK_M_A1_PLL1_PHI1",
+						     "CLK_M_A1_PLL1_PHI2",
+						     "CLK_M_A1_PLL1_PHI3";
+			};
+
+			CLK_M_A1_OSC_PREDIV: CLK_M_A1_OSC_PREDIV {
+				#clock-cells = <0>;
+				compatible = "st,clkgena-prediv-c32",
+					     "st,clkgena-prediv";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A1_OSC_PREDIV";
+			};
+
+			CLK_M_A1_DIV0: CLK_M_A1_DIV0 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf0",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A1_OSC_PREDIV>,
+					 <&CLK_M_A1_PLL0 0>, /* PLL0 PHI0 */
+					 <&CLK_M_A1_PLL1 0>; /* PLL1 PHI0 */
+
+				clock-output-names = "CLK_M_FDMA_12",
+						     "CLK_M_FDMA_10",
+						     "CLK_M_FDMA_11",
+						     "CLK_M_HVA_LMI",
+						     "CLK_M_PROC_SC",
+						     "CLK_M_TP",
+						     "CLK_M_ICN_GPU",
+						     "CLK_M_ICN_VDP_0";
+			};
+
+			CLK_M_A1_DIV1: CLK_M_A1_DIV1 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf1",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A1_OSC_PREDIV>,
+					 <&CLK_M_A1_PLL0 1>, /* PLL0 PHI1 */
+					 <&CLK_M_A1_PLL1 1>; /* PLL1 PHI1 */
+
+				clock-output-names = "CLK_M_ICN_VDP_1",
+						     "CLK_M_ICN_VDP_2",
+						     "CLK_M_ICN_VDP_3",
+						     "CLK_M_PRV_T1_BUS",
+						     "CLK_M_ICN_VDP_4",
+						     "CLK_M_ICN_REG_10",
+						     "", /* Unused */
+						     ""; /* CLK_M_ICN_ST231 */
+			};
+
+			CLK_M_A1_DIV2: CLK_M_A1_DIV2 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf2",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A1_OSC_PREDIV>,
+					 <&CLK_M_A1_PLL0 2>, /* PLL0 PHI2 */
+					 <&CLK_M_A1_PLL1 2>; /* PLL1 PHI2 */
+
+				clock-output-names = "CLK_M_FVDP_PROC_ALT",
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     ""; /* Unused */
+			};
+
+			CLK_M_A1_DIV3: CLK_M_A1_DIV3 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf3",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A1_OSC_PREDIV>,
+					 <&CLK_M_A1_PLL0 3>, /* PLL0 PHI3 */
+					 <&CLK_M_A1_PLL1 3>; /* PLL1 PHI3 */
+
+				clock-output-names = "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     "", /* Unused */
+						     ""; /* Unused */
+			};
+		};
+
+		CLK_M_A9_EXT2F_DIV2: CLK_M_A9_EXT2F_DIV2S {
 			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <100000000>;
+			compatible = "fixed-factor-clock";
+			clocks = <&CLK_M_A0_DIV1 2>;
+			clock-div = <2>;
+			clock-mult = <1>;
+		};
+
+		clockgenA@fd345000 {
+			reg = <0xfd345000 0xb50>;
+
+			CLK_M_A2_PLL0: CLK_M_A2_PLL0 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-0", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A2_PLL0_PHI0",
+						     "CLK_M_A2_PLL0_PHI1",
+						     "CLK_M_A2_PLL0_PHI2",
+						     "CLK_M_A2_PLL0_PHI3";
+			};
+
+			CLK_M_A2_PLL1: CLK_M_A2_PLL1 {
+				#clock-cells = <1>;
+				compatible = "st,plls-c32-a1x-1", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A2_PLL1_PHI0",
+						     "CLK_M_A2_PLL1_PHI1",
+						     "CLK_M_A2_PLL1_PHI2",
+						     "CLK_M_A2_PLL1_PHI3";
+			};
+
+			CLK_M_A2_OSC_PREDIV: CLK_M_A2_OSC_PREDIV {
+				#clock-cells = <0>;
+				compatible = "st,clkgena-prediv-c32",
+					     "st,clkgena-prediv";
+
+				clocks = <&CLK_SYSIN>;
+
+				clock-output-names = "CLK_M_A2_OSC_PREDIV";
+			};
+
+			CLK_M_A2_DIV0: CLK_M_A2_DIV0 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf0",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A2_OSC_PREDIV>,
+					 <&CLK_M_A2_PLL0 0>, /* PLL0 PHI0 */
+					 <&CLK_M_A2_PLL1 0>; /* PLL1 PHI0 */
+
+				clock-output-names = "CLK_M_VTAC_MAIN_PHY",
+						     "CLK_M_VTAC_AUX_PHY",
+						     "CLK_M_STAC_PHY",
+						     "CLK_M_STAC_SYS",
+						     "", /* CLK_M_MPESTAC_PG */
+						     "", /* CLK_M_MPESTAC_WC */
+						     "", /* CLK_M_MPEVTACAUX_PG*/
+						     ""; /* CLK_M_MPEVTACMAIN_PG*/
+			};
+
+			CLK_M_A2_DIV1: CLK_M_A2_DIV1 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf1",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A2_OSC_PREDIV>,
+					 <&CLK_M_A2_PLL0 1>, /* PLL0 PHI1 */
+					 <&CLK_M_A2_PLL1 1>; /* PLL1 PHI1 */
+
+				clock-output-names = "", /* CLK_M_MPEVTACRX0_WC */
+						     "", /* CLK_M_MPEVTACRX1_WC */
+						     "CLK_M_COMPO_MAIN",
+						     "CLK_M_COMPO_AUX",
+						     "CLK_M_BDISP_0",
+						     "CLK_M_BDISP_1",
+						     "CLK_M_ICN_BDISP_0",
+						     "CLK_M_ICN_BDISP_1";
+			};
+
+			CLK_M_A2_DIV2: CLK_M_A2_DIV2 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf2",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A2_OSC_PREDIV>,
+					 <&CLK_M_A2_PLL0 2>, /* PLL0 PHI2 */
+					 <&CLK_M_A2_PLL1 2>; /* PLL1 PHI2 */
+
+				clock-output-names = "", /* CLK_M_ICN_HQVDP0 */
+						     "", /* CLK_M_ICN_HQVDP1 */
+						     "CLK_M_ICN_COMPO",
+						     "", /* CLK_M_ICN_VDPAUX */
+						     "CLK_M_ICN_TS",
+						     "CLK_M_ICN_REG_LP_10",
+						     "CLK_M_DCEPHY_IMPCTRL",
+						     ""; /* Unused */
+			};
+
+			CLK_M_A2_DIV3: CLK_M_A2_DIV3 {
+				#clock-cells = <1>;
+				compatible = "st,clkgena-divmux-c32-odf3",
+					     "st,clkgena-divmux";
+
+				clocks = <&CLK_M_A2_OSC_PREDIV>,
+					 <&CLK_M_A2_PLL0 3>, /* PLL0 PHI3 */
+					 <&CLK_M_A2_PLL1 3>; /* PLL1 PHI3 */
+
+				clock-output-names = ""; /* Unused */
+						/* Remaining outputs unused */
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
index d9c7dd1..fcda687 100644
--- a/arch/arm/boot/dts/stih415.dtsi
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -71,7 +71,7 @@
 			interrupts	= <0 197 0>;
 			pinctrl-names 	= "default";
 			pinctrl-0 	= <&pinctrl_serial2>;
-			clocks		= <&CLKS_ICN_REG_0>;
+			clocks		= <&CLK_S_A0_LS CLK_S_ICN_REG_0>;
 		};
 
 		/* SBC comms block ASCs in SASG1 */
@@ -89,7 +89,7 @@
 			compatible	= "st,comms-ssc4-i2c";
 			reg		= <0xfed40000 0x110>;
 			interrupts	= <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
-			clocks		= <&CLKS_ICN_REG_0>;
+			clocks		= <&CLK_S_A0_LS CLK_S_ICN_REG_0>;
 			clock-names	= "ssc";
 			clock-frequency = <400000>;
 			pinctrl-names	= "default";
@@ -102,7 +102,7 @@
 			compatible	= "st,comms-ssc4-i2c";
 			reg		= <0xfed41000 0x110>;
 			interrupts	= <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
-			clocks		= <&CLKS_ICN_REG_0>;
+			clocks		= <&CLK_S_A0_LS CLK_S_ICN_REG_0>;
 			clock-names	= "ssc";
 			clock-frequency = <400000>;
 			pinctrl-names	= "default";
-- 
1.9.0

^ permalink raw reply related

* [PATCH v0 15/15] ARM: STi: DT: STiH415: 415 DT Entry for clockgen A9
From: Gabriel FERNANDEZ @ 2014-02-27 15:24 UTC (permalink / raw)
  To: mturquette, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rob, linux, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel
  Cc: Lee Jones, Gabriel Fernandez, Pankaj Dev
In-Reply-To: <1393514668-17440-1-git-send-email-gabriel.fernandez@st.com>

Patch adds DT entries for clockgen A9

Signed-off-by: Pankaj Dev <pankaj.dev@st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 arch/arm/boot/dts/stih415-clock.dtsi | 67 +++++++++++++++++++++++++++++++-----
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
index 24a7508..8563636 100644
--- a/arch/arm/boot/dts/stih415-clock.dtsi
+++ b/arch/arm/boot/dts/stih415-clock.dtsi
@@ -24,15 +24,6 @@
 		};
 
 		/*
-		 * ARM Peripheral clock for timers
-		 */
-		arm_periph_clk: arm_periph_clk {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <500000000>;
-		};
-
-		/*
 		 * ClockGenAs on SASG1
 		 */
 		clockgenA@fee62000 {
@@ -499,5 +490,63 @@
 						/* Remaining outputs unused */
 			};
 		};
+
+		/*
+		 * A9 PLL.
+		 *
+		 */
+		clockgenA9 {
+			reg = <0xfdde00d8 0x70>;
+
+			CLOCKGEN_A9_PLL: CLOCKGEN_A9_PLL {
+				#clock-cells = <1>;
+				compatible = "st,stih415-plls-c32-a9", "st,clkgen-plls-c32";
+
+				clocks = <&CLK_SYSIN>;
+				clock-output-names = "CLOCKGEN_A9_PLL_ODF";
+			};
+		};
+
+		/*
+		 * ARM CPU related clocks.
+		 */
+		CLK_M_A9: CLK_M_A9 {
+			#clock-cells = <0>;
+			compatible = "st,stih415-clkgen-a9-mux", "st,clkgen-mux";
+			reg = <0xfdde00d8 0x4>;
+			clocks = <&CLOCKGEN_A9_PLL 0>, <&CLOCKGEN_A9_PLL 0>, <&CLK_M_A0_DIV1 2>, <&CLK_M_A9_EXT2F_DIV2>;
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: CLK_M_A9_PERIPHS {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clocks = <&CLK_M_A9>;
+			clock-div = <2>;
+			clock-mult = <1>;
+		};
+
+		CLK_S_USB48: clockgenB0@0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <48000000>;
+			clock-output-names = "CLK_S_USB48";
+		};
+
+		CLKS_B_THSENS: clockgenB@3 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <996000>;
+			clock-output-names = "CLKS_B_THSENS";
+		};
+
+		CLKM_MPETHSENS: clockgenE@3 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <996000>;
+			clock-output-names = "CLKM_MPETHSENS";
+		};
 	};
 };
-- 
1.9.0


^ permalink raw reply related

* [RFC PATCH] sky2: allow mac to come from dt
From: Tim Harvey @ 2014-02-27 15:26 UTC (permalink / raw)
  To: linux-pci, devicetree

The sky2 driver currently reads the mac address from the device registers
which would need to have been programmed by the bootloader.

This patch adds the ability to pull the mac from devicetree via the
aliases/sky2 node.

The RFC is because I'm not clear if there is a better way to reference the
devicetree node for a PCI device from both the bootloader perspective and
the driver perspective.  Using an alias feels a bit like a hack.  An example
of a dts that describes a marvell,sky2 sitting on bus8 of the PCI bus is:

aliases {
	sky2 = &eth1;
};

&pcie { 
        eth1: sky2@8 { /* MAC/PHY on bus 8 */
                compatible = "marvell,sky2";
        };
};

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 drivers/net/ethernet/marvell/sky2.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 55a37ae..4165fc0 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -44,6 +44,8 @@
 #include <linux/prefetch.h>
 #include <linux/debugfs.h>
 #include <linux/mii.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
 
 #include <asm/irq.h>
 
@@ -4748,6 +4750,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
 {
 	struct sky2_port *sky2;
 	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+	unsigned char *iap, tmpaddr[ETH_ALEN];
 
 	if (!dev)
 		return NULL;
@@ -4805,8 +4808,36 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
 
 	dev->features |= dev->hw_features;
 
+	/*
+	 * try to get mac address in the following order:
+	 * 1) from device tree data
+	 * 2) from internal registers set by bootloader
+	 */
+	iap = NULL;
+	if (IS_ENABLED(CONFIG_OF)) {
+		struct device_node *np;
+		np = of_find_node_by_path("/aliases");
+		if (np) {
+			const char *path = of_get_property(np, "sky2", NULL);
+			if (path)
+				np = of_find_node_by_path(path);
+			if (np)
+				path = of_get_mac_address(np);
+			if (path)
+				iap = (unsigned char *) path;
+		}
+	}
+
+	/*
+	 * 2) mac registers set by bootloader
+	 */
+	if (!iap || !is_valid_ether_addr(iap)) {
+		memcpy_fromio(&tmpaddr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+		iap = &tmpaddr[0];
+	}
+
 	/* read the mac address */
-	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+	memcpy(dev->dev_addr, iap, ETH_ALEN);
 
 	return dev;
 }
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH] phy-rcar-gen2-usb: add device tree support
From: Sergei Shtylyov @ 2014-02-27 15:50 UTC (permalink / raw)
  To: Ben Dooks
  Cc: balbi-l0cyMroinI0, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
	galak-sgV2jX0FEOL9JmXXK+q4OQ, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	linux-sh-u79uwXL29TY76Z2rM5mHXA,
	valentine.barshak-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
	rob-VoJi6FS/r0vR7s880joybQ, linux-doc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <530F3637.5050000-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>

Hello.

On 27-02-2014 16:57, Ben Dooks wrote:

>> Add support of the device tree probing for the Renesas R-Car generation 2 SoCs
>> documenting the device tree binding as necessary.

> So what happened w.r.t to my last set of patches for this?

    Hm, I forgot you've posted the OF patch already (and I was tasked with the 
PHY driver OF support). I have re-read the thread now, and the issue was that 
Felipe wanted an ACK from one of DT maintainers. I had issues with the 
"compatible" props the driver reacts on. Also, I didn't see your bindings doc 
patch the last time you posted the driver patch. I have one more issue now and 
will follow up to the patch with it...

WBR, Sergei

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

^ permalink raw reply

* Re: [PATCH 4/6] phy-rcar-usb-gen2: add device tree support
From: Sergei Shtylyov @ 2014-02-27 15:54 UTC (permalink / raw)
  To: Ben Dooks
  Cc: linux-kernel, linux-sh, Magnus Damm, Simon Horman,
	open list:OPEN FIRMWARE AND...
In-Reply-To: <52DCFF31.2040603@codethink.co.uk>

Hello.

On 20-01-2014 14:49, Ben Dooks wrote:

>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>> Reviewed-by: Ian Molton <ian.molton@codethink.co.uk>
>>> ---
>>> Cc: linux-usb@vger.kernel.org (open list:USB PHY LAYER)
>>> Cc: linux-sh@vger.kernel.org (open list:ARM/SHMOBILE ARM...)
>>> Cc: Magnus Damm <magnus.damm@gmail.com> (supporter:ARM/SHMOBILE ARM...)
>>> Cc: Simon Horman <horms@verge.net.au> (supporter:ARM/SHMOBILE ARM...)
>>> Cc: devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND...)
>>> ---
>>>   drivers/usb/phy/phy-rcar-gen2-usb.c | 35
>>> ++++++++++++++++++++++++++++++-----
>>>   1 file changed, 30 insertions(+), 5 deletions(-)

>>> diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c
>>> b/drivers/usb/phy/phy-rcar-gen2-usb.c
>>> index db3ab34..906b74b 100644
>>> --- a/drivers/usb/phy/phy-rcar-gen2-usb.c
>>> +++ b/drivers/usb/phy/phy-rcar-gen2-usb.c
>> [...]
>>> @@ -203,16 +212,31 @@ static int rcar_gen2_usb_phy_probe(struct
>>> platform_device *pdev)
>> [...]
>>> +    if (of_id) {
[...]
>>> +        int len = 0;
>>> +
>>> +        if (of_get_property(dev->of_node, "renesas,usb0-hs", &len))
>>> +            priv->ugctrl2 = USBHS_UGCTRL2_USB0_HS;
>>> +        else
>>> +            priv->ugctrl2 = USBHS_UGCTRL2_USB0_PCI;
>>> +
>>> +        if (of_get_property(dev->of_node, "renesas,usb2-ss", &len))
>>> +            priv->ugctrl2 |= USBHS_UGCTRL2_USB2_SS;

>>     Where is the bindings file you document these properties in?

> Should have been in another patch in the series.

    I didn't see it.

WBR, Sergei


^ permalink raw reply

* Re: [PATCH] phy-rcar-gen2-usb: add device tree support
From: Mark Rutland @ 2014-02-27 15:56 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: balbi-l0cyMroinI0@public.gmane.org,
	linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, Pawel Moll,
	ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
	galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
	linux-sh-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	valentine.barshak-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org,
	rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org,
	linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <201402270312.51588.sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>

On Thu, Feb 27, 2014 at 12:12:50AM +0000, Sergei Shtylyov wrote:
> Add support of the device tree probing for the Renesas R-Car generation 2 SoCs
> documenting the device tree binding as necessary.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
> 
> ---
> This patch is against the 'next' branch of Felipe Balbi's 'usb.git' repo.
> 
>  Documentation/devicetree/bindings/usb/rcar-gen2-phy.txt |   29 +++++++
>  drivers/usb/phy/phy-rcar-gen2-usb.c                     |   64 ++++++++++++++--
>  2 files changed, 85 insertions(+), 8 deletions(-)
> 
> Index: usb/Documentation/devicetree/bindings/usb/rcar-gen2-phy.txt
> ===================================================================
> --- /dev/null
> +++ usb/Documentation/devicetree/bindings/usb/rcar-gen2-phy.txt
> @@ -0,0 +1,29 @@
> +* Renesas R-Car generation 2 USB PHY
> +
> +This file provides information on what the device node for the R-Car generation
> +2 USB PHY contains.
> +
> +Required properties:
> +- compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC.
> +	      "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC.

Is the r8a7791's USB PHY known to be different to that of the r8a7790?

If this is just to possibly handle the two differently in future, why
not have "renesas,usb-phy-r8a7790" as a fallback in the compatible list?
That was you only need it in the driver for now.

> +- reg: offset and length of the register block.
> +- clocks: clock phandle and specifier pair.
> +- clock-names: string, clock input name, must be "usbhs".
> +
> +Optional properties:
> +- renesas,channel0-pci: boolean, specify when USB channel 0 should be connected
> +			to PCI EHCI/OHCI; otherwise, it will be connected to the
> +			USBHS controller.
> +- renesas,channel2-pci: boolean, specify when USB channel 2 should be connected
> +			to PCI EHCI/OHCI; otherwise, it will be connected to the
> +			USBSS controller (xHCI).

When would you want this to connect to PCI, and when would you not? Why
is this not a run-time decision?

> +
> +Example (Lager board):
> +
> +	usb-phy@e6590100 {
> +		compatible = "renesas,usb-phy-r8a7790";
> +		reg = <0 0xe6590100 0 0x100>;
> +		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
> +		clock-names = "usbhs";
> +		renesas,channel2-pci;
> +	};

We're not using the generic phy bindings? How is the linkage to the host
controller expressed?

[...]

> -	clk = devm_clk_get(dev, "usbhs");
> +	if (np)
> +		clk = of_clk_get_by_name(np, "usbhs");
> +	else
> +		clk = clk_get(dev, "usbhs");

Doesn't clk_get (and hence devm_clk_get) call of_clk_get_by_name?

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

^ permalink raw reply

* Re: [PATCH 4/6] phy-rcar-usb-gen2: add device tree support
From: Ben Dooks @ 2014-02-27 16:03 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-kernel, linux-sh, Magnus Damm, Simon Horman,
	open list:OPEN FIRMWARE AND...
In-Reply-To: <530F5FC2.1000608@cogentembedded.com>

On 27/02/14 15:54, Sergei Shtylyov wrote:
> Hello.
>
> On 20-01-2014 14:49, Ben Dooks wrote:
>
>>>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>>>> Reviewed-by: Ian Molton <ian.molton@codethink.co.uk>
>>>> ---
>>>> Cc: linux-usb@vger.kernel.org (open list:USB PHY LAYER)
>>>> Cc: linux-sh@vger.kernel.org (open list:ARM/SHMOBILE ARM...)
>>>> Cc: Magnus Damm <magnus.damm@gmail.com> (supporter:ARM/SHMOBILE ARM...)
>>>> Cc: Simon Horman <horms@verge.net.au> (supporter:ARM/SHMOBILE ARM...)
>>>> Cc: devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND...)
>>>> ---
>>>>   drivers/usb/phy/phy-rcar-gen2-usb.c | 35
>>>> ++++++++++++++++++++++++++++++-----
>>>>   1 file changed, 30 insertions(+), 5 deletions(-)
>
>>>> diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c
>>>> b/drivers/usb/phy/phy-rcar-gen2-usb.c
>>>> index db3ab34..906b74b 100644
>>>> --- a/drivers/usb/phy/phy-rcar-gen2-usb.c
>>>> +++ b/drivers/usb/phy/phy-rcar-gen2-usb.c
>>> [...]
>>>> @@ -203,16 +212,31 @@ static int rcar_gen2_usb_phy_probe(struct
>>>> platform_device *pdev)
>>> [...]
>>>> +    if (of_id) {
> [...]
>>>> +        int len = 0;
>>>> +
>>>> +        if (of_get_property(dev->of_node, "renesas,usb0-hs", &len))
>>>> +            priv->ugctrl2 = USBHS_UGCTRL2_USB0_HS;
>>>> +        else
>>>> +            priv->ugctrl2 = USBHS_UGCTRL2_USB0_PCI;
>>>> +
>>>> +        if (of_get_property(dev->of_node, "renesas,usb2-ss", &len))
>>>> +            priv->ugctrl2 |= USBHS_UGCTRL2_USB2_SS;
>
>>>     Where is the bindings file you document these properties in?
>
>> Should have been in another patch in the series.
>
>     I didn't see it.

I thought it went out, I will need to go check.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply

* Re: [PATCH] phy-rcar-gen2-usb: add device tree support
From: Ben Dooks @ 2014-02-27 16:06 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: balbi, linux-usb, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, grant.likely, devicetree, gregkh, linux-sh,
	valentine.barshak, rob, linux-doc
In-Reply-To: <201402270312.51588.sergei.shtylyov@cogentembedded.com>

On 27/02/14 00:12, Sergei Shtylyov wrote:
> Add support of the device tree probing for the Renesas R-Car generation 2 SoCs
> documenting the device tree binding as necessary.

You've popped in some fixes for the driver probe in here as well.

Could you do the fixes as a patch and send those before the devicetree
code is done?

> +
>   static int rcar_gen2_usb_phy_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
>   	struct rcar_gen2_phy_platform_data *pdata;
>   	struct rcar_gen2_usb_phy_priv *priv;
>   	struct resource *res;
> @@ -177,13 +210,19 @@ static int rcar_gen2_usb_phy_probe(struc
>   	struct clk *clk;
>   	int retval;
>
> -	pdata = dev_get_platdata(dev);
> +	if (np)
> +		pdata = rcar_gen2_usb_phy_parse_dt(dev);
> +	else
> +		pdata = dev_get_platdata(dev);
>   	if (!pdata) {
>   		dev_err(dev, "No platform data\n");
>   		return -EINVAL;
>   	}
>
> -	clk = devm_clk_get(dev, "usbhs");
> +	if (np)
> +		clk = of_clk_get_by_name(np, "usbhs");
> +	else
> +		clk = clk_get(dev, "usbhs");

Can be removed, just add a clock-name of usbhs in the device node.

>   	if (IS_ERR(clk)) {
>   		dev_err(dev, "Can't get the clock\n");
>   		return PTR_ERR(clk);
> @@ -191,13 +230,16 @@ static int rcar_gen2_usb_phy_probe(struc
>
>   	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>   	base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(base))
> -		return PTR_ERR(base);
> +	if (IS_ERR(base)) {
> +		retval = PTR_ERR(base);
> +		goto error;
> +	}
>
>   	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>   	if (!priv) {
>   		dev_err(dev, "Memory allocation failed\n");
> -		return -ENOMEM;
> +		retval = -ENOMEM;
> +		goto error;
>   	}

Probably should be separate patch to fix probe issues.


>
>   	spin_lock_init(&priv->lock);
> @@ -216,12 +258,16 @@ static int rcar_gen2_usb_phy_probe(struc
>   	retval = usb_add_phy_dev(&priv->phy);
>   	if (retval < 0) {
>   		dev_err(dev, "Failed to add USB phy\n");
> -		return retval;
> +		goto error;
>   	}
>
>   	platform_set_drvdata(pdev, priv);
>
>   	return retval;
> +
> +error:
> +	clk_put(clk);
> +	return retval;
>   }

Again, should have been rolled into fix patch.



-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply

* Re: [PATCH v2 3/3] arm64: Add architecture support for PCI
From: Arnd Bergmann @ 2014-02-27 16:06 UTC (permalink / raw)
  To: linaro-kernel
  Cc: devicetree@vger.kernel.org, linux-pci, Liviu Dudau, LKML,
	Will Deacon, Catalin Marinas, Bjorn Helgaas, LAKML
In-Reply-To: <1393506599-11561-4-git-send-email-Liviu.Dudau@arm.com>

On Thursday 27 February 2014 13:09:59 Liviu Dudau wrote:

> +/*
> + * PCI address space differs from physical memory address space
> + */
> +#define PCI_DMA_BUS_IS_PHYS	(0)
> +
> +extern int isa_dma_bridge_buggy;

I got curious about isa_dma_bridge_buggy: apparently this is a quirk for
some old x86 bridges. We don't have those on arm64, and we also don't have
ISA_DMA_API, so just define this to (0).

> +static inline int pci_domain_nr(struct pci_bus *bus)
> +{
> +	struct pci_host_bridge *bridge = to_pci_host_bridge(bus->bridge);
> +
> +	if (bridge)
> +		return bridge->domain_nr;
> +
> +	return 0;
> +}
> +
> +static inline int pci_proc_domain(struct pci_bus *bus)
> +{
> +	return pci_domain_nr(bus);
> +}

And this one I would change to always return '1': we can deal with
domain numbers showing up in /procfs for all buses, since there is
no legacy software to worry about.

> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> new file mode 100644
> index 0000000..496df41
> --- /dev/null
> +++ b/arch/arm64/kernel/pci.c
> @@ -0,1 +1,126 @@

Ok, this is nice and short. Let's see if we can reduce it to nothing ;-)

> +/*
> + * Called after each bus is probed, but before its children are examined
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +	struct pci_dev *dev;
> +	struct resource *res;
> +	int i;
> +
> +	if (!pci_is_root_bus(bus)) {
> +		pci_read_bridge_bases(bus);
> +
> +		pci_bus_for_each_resource(bus, res, i) {
> +			if (!res || !res->flags || res->parent)
> +				continue;
> +
> +			/*
> +			 * If we are going to reassign everything, we can
> +			 * shrink the P2P resource to have zero size to
> +			 * save space
> +			 */
> +			if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
> +				res->flags |= IORESOURCE_UNSET;
> +				res->start = 0;
> +				res->end = -1;
> +				continue;
> +			}
> +		}
> +	}
> +
> +	list_for_each_entry(dev, &bus->devices, bus_list) {
> +		/* Ignore fully discovered devices */
> +		if (dev->is_added)
> +			continue;
> +
> +		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
> +
> +		/* Read default IRQs and fixup if necessary */
> +		dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
> +	}
> +}
> +EXPORT_SYMBOL(pcibios_fixup_bus);

Shrinking the P2P resources I suppose is optional, but everything
else is in fact needed for any DT based architecture. Could this
be turned into a generic helper function in the PCI core that we
can call from architecture code?

If you name it pci_generic_fixup_bus(), we can add a weak helper
like:

void __weak pcibios_fixup_bus(struct pci_bus *bus)
{
	pci_generic_fixup_bus(bus);
}

for architectures like arm64 that don't actually need to do anything
else.

> +/*
> + * We don't have to worry about legacy ISA devices, so nothing to do here
> + */
> +resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> +				resource_size_t size, resource_size_t align)
> +{
> +	return ALIGN(res->start, align);
> +}
> +EXPORT_SYMBOL(pcibios_align_resource);

Where did this come from? The most common implementation seems to be

resource_size_t pcibios_align_resource(void *data, const struct resource *res,
				resource_size_t size, resource_size_t align)
{
	return start;
}
EXPORT_SYMBOL(pcibios_align_resource);

if you don't have to worry about ISA devices. The ALIGN() part seems to
be handled by __find_resource() already.

I'd say that should be made the default implementation in the PCI core.

I'm also pretty sure you don't need the EXPORT_SYMBOL, since the PCI
core cannot be a loadable module (yet).

> +int pcibios_enable_device(struct pci_dev *dev, int mask)
> +{
> +	return pci_enable_resources(dev, mask);
> +}
> +
> +void pcibios_fixup_bridge_ranges(struct list_head *resources)
> +{
> +}

These are clearly the right implementations, but they should be weak
functions, too.

> +#define IO_SPACE_PAGES	((IO_SPACE_LIMIT + 1) / PAGE_SIZE)
> +static DECLARE_BITMAP(pci_iospace, IO_SPACE_PAGES);
> +
> +unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr)
> +{
> +	unsigned long start, len, virt_start;
> +	int err;
> +
> +	if (res->end > IO_SPACE_LIMIT)
> +		return -EINVAL;
> +
> +	/*
> +	 * try finding free space for the whole size first,
> +	 * fall back to 64K if not available
> +	 */
> +	len = resource_size(res);
> +	start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> +				res->start / PAGE_SIZE, len / PAGE_SIZE, 0);
> +	if (start == IO_SPACE_PAGES && len > SZ_64K) {
> +		len = SZ_64K;
> +		start = 0;
> +		start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> +					start, len / PAGE_SIZE, 0);
> +	}
> +
> +	/* no 64K area found */
> +	if (start == IO_SPACE_PAGES)
> +		return -ENOMEM;
> +
> +	/* ioremap physical aperture to virtual aperture */
> +	virt_start = start * PAGE_SIZE + (unsigned long)PCI_IOBASE;
> +	err = ioremap_page_range(virt_start, virt_start + len,
> +				phys_addr, __pgprot(PROT_DEVICE_nGnRE));
> +	if (err)
> +		return err;
> +
> +	bitmap_set(pci_iospace, start, len / PAGE_SIZE);
> +
> +	/* return io_offset */
> +	return start * PAGE_SIZE - res->start;
> +}

Maybe this can become an optional helper function with a separate Kconfig symbol
to enable it.

	Arnd

^ permalink raw reply

* Re: [PATCH] phy-rcar-gen2-usb: add device tree support
From: Sergei Shtylyov @ 2014-02-27 16:34 UTC (permalink / raw)
  To: Ben Dooks
  Cc: balbi, linux-usb, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, grant.likely, devicetree, gregkh, linux-sh,
	valentine.barshak, rob, linux-doc
In-Reply-To: <530F626C.5020900@codethink.co.uk>

On 27-02-2014 20:06, Ben Dooks wrote:

>> Add support of the device tree probing for the Renesas R-Car generation 2 SoCs
>> documenting the device tree binding as necessary.

> You've popped in some fixes for the driver probe in here as well.

    No, I didn't -- it's all the result of not using devm_clk_get().

[...]
>> @@ -177,13 +210,19 @@ static int rcar_gen2_usb_phy_probe(struc
[...]
>> -    clk = devm_clk_get(dev, "usbhs");
>> +    if (np)
>> +        clk = of_clk_get_by_name(np, "usbhs");
>> +    else
>> +        clk = clk_get(dev, "usbhs");

> Can be removed, just add a clock-name of usbhs in the device node.

    Ah, I haven't figured out I should check clk_get() first... Yes, I'm 
adding the "clock-names" prop.

WBR, Sergei


^ permalink raw reply

* Re: [PATCH v0 12/15] ARM: STi: DT: STiH416: 416 DT Entry for clockgen B/C/D/E/F
From: Lee Jones @ 2014-02-27 16:36 UTC (permalink / raw)
  To: Gabriel FERNANDEZ
  Cc: mturquette, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rob, linux, devicetree, linux-doc, linux-kernel,
	linux-arm-kernel, Pankaj Dev
In-Reply-To: <1393514668-17440-13-git-send-email-gabriel.fernandez@st.com>

> Patch adds DT entries for clockgen B/C/D/E/F
> 
> Signed-off-by: Pankaj Dev <pankaj.dev@st.com>

You need to add your Signed-off-by too.

> ---
>  arch/arm/boot/dts/stih416-clock.dtsi | 170 +++++++++++++++++++++++++++++++++++
>  1 file changed, 170 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
> index f63b0a1..6b2e387 100644
> --- a/arch/arm/boot/dts/stih416-clock.dtsi
> +++ b/arch/arm/boot/dts/stih416-clock.dtsi
> @@ -503,5 +503,175 @@
>  						/* Remaining outputs unused */
>  			};
>  		};

This doesn't look right. Have you indented one tab too far?

> +                /*
> +                 * Frequency synthesizers on the SASG2.
> +                 *
> +                 */

Too many *'s

<snip>

> +                CLK_S_VCC_HD: CLK_S_VCC_HD {
> +                        #clock-cells = <0>;
> +                        compatible = "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux";
> +                        reg = <0xfe8308b8 4>; /* SYSCFG2558 */

0x4

> +                /*
> +                 * Add a dummy clock for the HDMI PHY for the VCC input mux
> +                 */
> +                CLK_S_TMDS_FROMPHY: CLK_S_TMDS_FROMPHY {
> +                        #clock-cells = <0>;
> +                        compatible = "fixed-clock";
> +                        clock-frequency = <0>;

What happens when the clock frequency is 0?
> +                };
> +
> +                CLOCKGEN_C_VCC: CLOCKGEN_C_VCC {
> +                        #clock-cells = <1>;
> +                        compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
> +                        reg = <0xfe8308ac 12>; /* SYSCFG2555,2556,2557 */

0x12, or 0x0C, whichever is appropriate.

> +                        clocks = <&CLK_S_VCC_HD>, <&CLOCKGEN_C 1>,
> +                                 <&CLK_S_TMDS_FROMPHY>, <&CLOCKGEN_C 2>;

One per line would probably be better, save confusing them for pairs.

<snip>

> +		/*
> +		 * Frequency synthesizers on the MPE42
> +		 */

Alignment.

<snip>

> +                CLOCKGEN_F: CLOCKGEN_F {
> +                        #clock-cells = <1>;
> +                        compatible = "st,stih416-quadfs660-F", "st,quadfs";
> +                        reg = <0xfd320878 0xF0>;
> +
> +                        clocks = <&CLK_SYSIN>;
> +                        clock-output-names = "CLK_M_MAIN_VIDFS",
> +                                             "CLK_M_HVA_FS",
> +                                             "CLK_M_FVDP_VCPU",
> +					     "CLK_M_FVDP_PROC_FS";

Tabbing. Ensure you're using tabs (and not spaces) everywhere.

<snip>

> +                        reg = <0xfd320910 4>; /* SYSCFG8580 */

0x...

Do this for all of the below too.


<snip>

> +                        clock-output-names  =
> +                                "CLK_M_PIX_MAIN_PIPE",  "CLK_M_PIX_AUX_PIPE",
> +                                "CLK_M_PIX_MAIN_CRU",   "CLK_M_PIX_AUX_CRU",
> +                                "CLK_M_XFER_BE_COMPO",  "CLK_M_XFER_PIP_COMPO",
> +                                "CLK_M_XFER_AUX_COMPO", "CLK_M_VSENS",
> +                                "CLK_M_PIX_HDMIRX_0",   "CLK_M_PIX_HDMIRX_1";
> +                };
>  	};
>  };

Something strange going on with these.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 1/3] PCI: designware: split samsung and fsl bindings
From: Lucas Stach @ 2014-02-27 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: devicetree, linux-pci, Richard Zhu, Bjorn Helgaas, Shawn Guo,
	Mark Rutland, kernel

The glue around the core designware IP is
significantly different between the Exynos and
i.MX, which is reflected in the DT bindings.

Note that this patch doesn't change any bindings,
but just alters the documentation to match reality
of deployed DTs and kernels.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 .../devicetree/bindings/pci/designware-pcie.txt    | 69 +--------------------
 .../devicetree/bindings/pci/fsl,imx6q-pcie.txt     | 38 ++++++++++++
 .../bindings/pci/samsung,exynos5440-pcie.txt       | 70 ++++++++++++++++++++++
 3 files changed, 109 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
index d6fae13ff062..8274c80fe874 100644
--- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -1,15 +1,7 @@
 * Synopsys Designware PCIe interface
 
 Required properties:
-- compatible: should contain "snps,dw-pcie" to identify the
-	core, plus an identifier for the specific instance, such
-	as "samsung,exynos5440-pcie" or "fsl,imx6q-pcie".
-- reg: base addresses and lengths of the pcie controller,
-	the phy controller, additional register for the phy controller.
-- interrupts: interrupt values for level interrupt,
-	pulse interrupt, special interrupt.
-- clocks: from common clock binding: handle to pci clock.
-- clock-names: from common clock binding: should be "pcie" and "pcie_bus".
+- compatible: should contain "snps,dw-pcie" to identify the core.
 - #address-cells: set to <3>
 - #size-cells: set to <2>
 - device_type: set to "pci"
@@ -22,62 +14,3 @@ Required properties:
 
 Optional properties:
 - reset-gpio: gpio pin number of power good signal
-
-Optional properties for fsl,imx6q-pcie
-- power-on-gpio: gpio pin number of power-enable signal
-- wake-up-gpio: gpio pin number of incoming wakeup signal
-- disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
-
-Example:
-
-SoC specific DT Entry:
-
-	pcie@290000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x290000 0x1000
-			0x270000 0x1000
-			0x271000 0x40>;
-		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
-		clocks = <&clock 28>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 53>;
-		num-lanes = <4>;
-	};
-
-	pcie@2a0000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x2a0000 0x1000
-			0x272000 0x1000
-			0x271040 0x40>;
-		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
-		clocks = <&clock 29>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0x0 0 &gic 56>;
-		num-lanes = <4>;
-	};
-
-Board specific DT Entry:
-
-	pcie@290000 {
-		reset-gpio = <&pin_ctrl 5 0>;
-	};
-
-	pcie@2a0000 {
-		reset-gpio = <&pin_ctrl 22 0>;
-	};
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
new file mode 100644
index 000000000000..aade8d29314c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -0,0 +1,38 @@
+* Freescale i.MX6 PCIe interface
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "fsl,imx6q-pcie"
+- reg: base addresse and length of the pcie controller
+- interrupts: Must contain interrupt handle for controller INTA output.
+- clocks: Must contain an entry for each entry in clock-names.
+	See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries: 
+	- "pcie_ref_125m"
+	- "sata_ref_100m"
+	- "lvds_gate"
+	- "pcie_axi"
+
+Optional properties:
+- power-on-gpio: gpio pin number of power-enable signal
+- wake-up-gpio:  gpio pin number of incoming wakeup signal
+- disable-gpio:  gpio pin number of outgoing rfkill/endpoint disable signal
+
+Example:
+
+	pcie@0x01000000 {
+		compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
+		reg = <0x01ffc000 0x4000>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
+			  0x81000000 0 0          0x01f80000 0 0x00010000
+			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
+		num-lanes = <1>;
+		interrupts = <0 123 0x04>;
+		clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
+		clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
+	};
diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
new file mode 100644
index 000000000000..47e862126c05
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
@@ -0,0 +1,70 @@
+* Samsung Exynos 5440 PCIe interface
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "samsung,exynos5440-pcie"
+- reg: base addresses and lengths of the pcie controller,
+	the phy controller, additional register for the phy controller.
+- interrupts: A list of interrupt outputs for level interrupt,
+	pulse interrupt, special interrupt.
+- clocks: Must contain an entry for each entry in clock-names.
+	See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries: 
+	- "pcie"
+	- "pcie_bus"
+
+Example:
+
+SoC specific DT Entry:
+
+	pcie@290000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x290000 0x1000
+			0x270000 0x1000
+			0x271000 0x40>;
+		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+		clocks = <&clock 28>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 53>;
+		num-lanes = <4>;
+	};
+
+	pcie@2a0000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x2a0000 0x1000
+			0x272000 0x1000
+			0x271040 0x40>;
+		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+		clocks = <&clock 29>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 56>;
+		num-lanes = <4>;
+	};
+
+Board specific DT Entry:
+
+	pcie@290000 {
+		reset-gpio = <&pin_ctrl 5 0>;
+	};
+
+	pcie@2a0000 {
+		reset-gpio = <&pin_ctrl 22 0>;
+	};
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v3 2/3] ARM: dts: imx6: extend PCIe interrupt list for MSI
From: Lucas Stach @ 2014-02-27 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: devicetree, linux-pci, Richard Zhu, Bjorn Helgaas, Shawn Guo,
	Mark Rutland, kernel
In-Reply-To: <1393519305-15128-1-git-send-email-l.stach@pengutronix.de>

Add optional irqs, necessary for MSI handling.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | 10 +++++++++-
 arch/arm/boot/dts/imx6qdl.dtsi                           |  3 ++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
index aade8d29314c..3b27ec310ec4 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -16,6 +16,13 @@ Required properties:
 	- "pcie_axi"
 
 Optional properties:
+- interrupts: Must contain an entry for each entry in the
+  interrupt-names property.
+- interrupt-names: May include the following entries:
+	- "inta"
+	- "intb"
+	- "intc"
+	- "intd/msi" if not present the driver won't be able to handle MSI
 - power-on-gpio: gpio pin number of power-enable signal
 - wake-up-gpio:  gpio pin number of incoming wakeup signal
 - disable-gpio:  gpio pin number of outgoing rfkill/endpoint disable signal
@@ -32,7 +39,8 @@ Example:
 			  0x81000000 0 0          0x01f80000 0 0x00010000
 			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
 		num-lanes = <1>;
-		interrupts = <0 123 0x04>;
+		interrupt-names = "inta", "intb", "intc", "intd/msi";
+		interrupts = <0 123 0x04>, <0 122 0x04>, <0 121 0x04>, <0 120 0x04>;
 		clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
 		clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
 	};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index fb28b2ecb1db..e0261dd3fdd3 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -126,7 +126,8 @@
 				  0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
 				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
-			interrupts = <0 123 0x04>;
+			interrupt-names = "inta", "intb", "intc", "intd/msi";
+			interrupts = <0 123 0x04>, <0 122 0x04>, <0 121 0x04>, <0 120 0x04>;
 			clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
 			clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
 			status = "disabled";
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v3 3/3] PCI: imx6: add support for MSI
From: Lucas Stach @ 2014-02-27 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: devicetree, linux-pci, Richard Zhu, Bjorn Helgaas, Shawn Guo,
	Mark Rutland, kernel
In-Reply-To: <1393519305-15128-1-git-send-email-l.stach@pengutronix.de>

This patch adds support for Message Signaled Interrupt in the
imx6q-pcie driver. It is done in a similar way as for the Exynos
PCIe driver (commit f342d940ee0e3a2b5197fd4fbade1cb6bbc960b7),
which is also using the Synopsys designware PCIe IP core.

Signed-off-by: Harro Haan <hrhaan@gmail.com>
Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/pci/host/pci-imx6.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index ee082509b0ba..50f76581bcfb 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -25,6 +25,7 @@
 #include <linux/resource.h>
 #include <linux/signal.h>
 #include <linux/types.h>
+#include <linux/interrupt.h>
 
 #include "pcie-designware.h"
 
@@ -329,6 +330,17 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
 	return 0;
 }
 
+/* legacy IRQD/MSI interrupt */
+static irqreturn_t imx6_pcie_irqd_msi_handler(int irq, void *arg)
+{
+	struct pcie_port *pp = arg;
+
+	if (IS_ENABLED(CONFIG_PCI_MSI))
+		dw_handle_msi_irq(pp);
+
+	return IRQ_HANDLED;
+}
+
 static int imx6_pcie_start_link(struct pcie_port *pp)
 {
 	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
@@ -403,6 +415,9 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
 	dw_pcie_setup_rc(pp);
 
 	imx6_pcie_start_link(pp);
+
+	if (IS_ENABLED(CONFIG_PCI_MSI) && (pp->msi_irq >= 0))
+		dw_pcie_msi_init(pp);
 }
 
 static void imx6_pcie_reset_phy(struct pcie_port *pp)
@@ -498,6 +513,21 @@ static int imx6_add_pcie_port(struct pcie_port *pp,
 		return -ENODEV;
 	}
 
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		pp->msi_irq = platform_get_irq_byname(pdev, "intd/msi");
+		if (pp->msi_irq < 0) {
+			dev_info(&pdev->dev, "failed to get INTD/MSI, PCIe will not support MSI\n");
+		} else {
+			ret = devm_request_irq(&pdev->dev, pp->msi_irq,
+			                       imx6_pcie_irqd_msi_handler,
+			                       IRQF_SHARED, "mx6-pcie-msi", pp);
+			if (ret) {
+				dev_err(&pdev->dev, "failed to request INTD/MSI irq\n");
+				return -ENODEV;
+			}
+		}
+	}
+
 	pp->root_bus_nr = -1;
 	pp->ops = &imx6_pcie_host_ops;
 
-- 
1.8.5.3

^ permalink raw reply related

* Re: [PATCH v2] dt: platform driver: Fill the resources before probe and defer if needed
From: Jean-Jacques Hiblot @ 2014-02-27 16:43 UTC (permalink / raw)
  To: Jean-Jacques Hiblot
  Cc: devicetree@vger.kernel.org, Strashko, Grygorii,
	gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
	robh+dt@kernel.org, gregory.clement@free-electrons.com,
	thierry.reding@gmail.com, Shilimkar, Santosh,
	grant.likely@linaro.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CACh+v5MPTx6nwVj1s3krntJqQ6DMTQ2hQ93Hc+rRNAuFa9+qPw@mail.gmail.com>

Hi Grant,

2014-02-21 17:22 GMT+01:00 Jean-Jacques Hiblot <jjhiblot@traphandler.com>:
> Hi Grygorii,
>
> 2014-02-21 16:37 GMT+01:00 Strashko, Grygorii <grygorii.strashko@ti.com>:
>> Hi  Jean-Jacques,
>>
>> Sorry for top posting.
>>
>> As I know, there have been several attempts to solve the same problem already:)
>> [1] https://lkml.org/lkml/2013/9/18/216
>> [2] https://lkml.org/lkml/2013/11/22/520
>> [3] https://lkml.org/lkml/2014/1/8/240
>>
>> There are some questions related to your approach:
>> 1) How to distinguish between cases "IRQ domain not ready" and "wrong IRQ data in DT" or other IRQ parsing errors?
>> Otherwise, Driver's probe will be deffered wrongly and forever,
>> Thierry Reding has tried to solve this in [1].
>
> This approach doesn't really care about the cause of the problem.  I'm
> of the opinion that never-ending deferred probing is not a big issue,
> being not triggered so often after start-up (only when a new device is
> probed). But if we need to make it right, then we would have to change
> a bit the API of irq_create_of_mapping() and irq_of_parse_and_map()
> (or maybe duplicate this one to keep the patch small) to return a real
> error code instead a simple 0. Then would should be able to
> distinguish the different error causes.

What do you think of the 2nd version of the patch? Is it all right to
allways return EPROBE_DEFER or should we try to discriminate the error
cause?

Jean-Jacques

>
>>
>> 2) How will be handled driver reloading situation?
>> The worst case (sparse IRQ enabled):
>> - remove driver A
>> - remove driver B (irq-controller)
>> - load driver B <--- different set of Linux IRQ numbers can be assigned
>> - load driver A <--- oops. IRQ resources table contains invalid data
>>
>
> It's not handled in the current implementation. But if all interrupts
> entries are re-parsed (see my comment for Grant), it should be all
> right.
> Another problem would appear if the DT is dynamically updated and the
> number of resource is changed. In the 1st version of the patch, this
> was handled but it made the function more expensive.
>
> Jean-Jacques
>>
>>
>> Best regards,
>> Grygorii Strashko
>>
>> =============================================
>>
>> The goal of this patch is to allow drivers to be probed even if at the time of
>> the DT parsing some of their ressources are not available yet.
>>
>> In the current situation, the resource of a platform device are filled from the
>> DT at the time the device is created (of_device_alloc()). The drawbackof this
>> is that a device sitting close to the top of the DT (ahb for example) but
>> depending on ressources that are initialized later (IRQ domain dynamically
>> created for example)  will fail to probe because the ressources don't exist
>> at this time.
>>
>> This patch fills the resource structure only before the device is probed and
>> will defer the probe if the resource are not available yet.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
>> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>
>> Hi Grant,
>>
>> I reworked the patch as you proposed. To keep the overhead minimum, nirq and
>> nreg are computed only the first time.
>> In this implementation, only the missing IRQ ressources are re-tried for. It could
>> easily be changed to re-parse all the IRQs though (replace if (!res->flags)
>> with if ((!res->flags) || (res->flags & IORESOURCE_IRQ)).
>>
>> drivers/base/platform.c     |   5 +++
>>  drivers/of/platform.c       | 100 +++++++++++++++++++++++++++++++++-----------
>>  include/linux/of_platform.h |  10 +++++
>>  3 files changed, 90 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>> index bc78848..cee9b8d 100644
>> --- a/drivers/base/platform.c
>> +++ b/drivers/base/platform.c
>> @@ -481,6 +481,10 @@ static int platform_drv_probe(struct device *_dev)
>>         struct platform_device *dev = to_platform_device(_dev);
>>         int ret;
>>
>> +       ret = of_platform_device_prepare(dev);
>> +       if (ret)
>> +               goto error;
>> +
>>         if (ACPI_HANDLE(_dev))
>>                 acpi_dev_pm_attach(_dev, true);
>>
>> @@ -488,6 +492,7 @@ static int platform_drv_probe(struct device *_dev)
>>         if (ret && ACPI_HANDLE(_dev))
>>                 acpi_dev_pm_detach(_dev, true);
>>
>> +error:
>>         if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
>>                 dev_warn(_dev, "probe deferral not supported\n");
>>                 ret = -ENXIO;
>> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
>> index 404d1da..a4e2602 100644
>> --- a/drivers/of/platform.c
>> +++ b/drivers/of/platform.c
>> @@ -141,36 +141,11 @@ struct platform_device *of_device_alloc(struct device_node *np,
>>                                   struct device *parent)
>>  {
>>         struct platform_device *dev;
>> -       int rc, i, num_reg = 0, num_irq;
>> -       struct resource *res, temp_res;
>>
>>         dev = platform_device_alloc("", -1);
>>         if (!dev)
>>                 return NULL;
>>
>> -       /* count the io and irq resources */
>> -       if (of_can_translate_address(np))
>> -               while (of_address_to_resource(np, num_reg, &temp_res) == 0)
>> -                       num_reg++;
>> -       num_irq = of_irq_count(np);
>> -
>> -       /* Populate the resource table */
>> -       if (num_irq || num_reg) {
>> -               res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
>> -               if (!res) {
>> -                       platform_device_put(dev);
>> -                       return NULL;
>> -               }
>> -
>> -               dev->num_resources = num_reg + num_irq;
>> -               dev->resource = res;
>> -               for (i = 0; i < num_reg; i++, res++) {
>> -                       rc = of_address_to_resource(np, i, res);
>> -                       WARN_ON(rc);
>> -               }
>> -               WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
>> -       }
>> -
>>         dev->dev.of_node = of_node_get(np);
>>  #if defined(CONFIG_MICROBLAZE)
>>         dev->dev.dma_mask = &dev->archdata.dma_mask;
>> @@ -233,6 +208,81 @@ static struct platform_device *of_platform_device_create_pdata(
>>         return dev;
>>  }
>>
>> +static int of_reg_count(struct device_node *np)
>> +{
>> +       int nreg = 0;
>> +       if (of_can_translate_address(np)) {
>> +               struct resource temp_res;
>> +               while (of_address_to_resource(np, nreg, &temp_res) == 0)
>> +                       nreg++;
>> +       }
>> +       return nreg;
>> +}
>> +
>> +int of_platform_device_prepare(struct platform_device *dev)
>> +{
>> +       struct device_node *np;
>> +       int i, irq_index;
>> +       struct resource *res;
>> +
>> +       /*
>> +        * This function applies only devices described in the DT.
>> +        * Other platform devices have their ressources already populated.
>> +        */
>> +       np = dev->dev.of_node;
>> +       if (!np)
>> +               return 0;
>> +
>> +       /* Populate the resource table */
>> +       if (!dev->resource) {
>> +               int rc, nreg = 0, nirq;
>> +               /* count the io and irq resources */
>> +               nreg = of_reg_count(np);
>> +               nirq = of_irq_count(np);
>> +
>> +               if (!nirq && !nreg)
>> +                       return 0;
>> +
>> +               res = kzalloc(sizeof(*res) * (nirq + nreg), GFP_KERNEL);
>> +               if (!res)
>> +                       return -ENOMEM;
>> +
>> +               dev->resource = res;
>> +               dev->num_resources = nreg + nirq;
>> +
>> +               for (i = 0; i < nreg; i++, res++) {
>> +                       rc = of_address_to_resource(np, i, res);
>> +                       if (WARN_ON(rc)) {
>> +                               /* THIS IS BAD; don't try to defer probing */
>> +                               dev->num_resources = 0;
>> +                               dev->resource = NULL;
>> +                               kfree(res);
>> +                               return rc;
>> +                       }
>> +               }
>> +
>> +               if (!rc && of_irq_to_resource_table(np, res, nirq) != nirq) {
>> +                       /* IRQ controller is yet available. defer probing */
>> +                       return -EPROBE_DEFER;
>> +               }
>> +
>> +               return 0;
>> +       }
>> +
>> +       /* See which IRQ resources need to be redone */
>> +       irq_index = 0;
>> +       for (i = 0, res = dev->resource; i < dev->num_resources; i++, res++) {
>> +               if (!res->flags) {
>> +                       if (!of_irq_to_resource(np, irq_index, res))
>> +                               return -EPROBE_DEFER;
>> +                       irq_index++;
>> +               } else if (res->flags & IORESOURCE_IRQ)
>> +                       irq_index++;
>> +       }
>> +       return 0;
>> +}
>> +EXPORT_SYMBOL(of_platform_device_prepare);
>> +
>>  /**
>>   * of_platform_device_create - Alloc, initialize and register an of_device
>>   * @np: pointer to node to create device for
>> diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
>> index 05cb4a9..4e487ff 100644
>> --- a/include/linux/of_platform.h
>> +++ b/include/linux/of_platform.h
>> @@ -53,6 +53,16 @@ struct of_dev_auxdata {
>>
>>  extern const struct of_device_id of_default_bus_match_table[];
>>
>> +/* Populate the resource for a platform device */
>> +#ifdef CONFIG_OF
>> +int of_platform_device_prepare(struct platform_device *dev);
>> +#else
>> +static inline int of_platform_device_prepare(
>> +       struct platform_device *dev)
>> +{
>> +       return 0;
>> +}
>> +#endif
>>  /* Platform drivers register/unregister */
>>  extern struct platform_device *of_device_alloc(struct device_node *np,
>>                                          const char *bus_id,
>> --
>> 1.9.0
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/3] ARM: dts: imx6: extend PCIe interrupt list for MSI
From: Arnd Bergmann @ 2014-02-27 16:44 UTC (permalink / raw)
  To: Lucas Stach
  Cc: linux-arm-kernel, devicetree, linux-pci, Richard Zhu,
	Bjorn Helgaas, Shawn Guo, Mark Rutland, kernel
In-Reply-To: <1393519305-15128-2-git-send-email-l.stach@pengutronix.de>

On Thursday 27 February 2014 17:41:44 Lucas Stach wrote:
>                         num-lanes = <1>;
> -                       interrupts = <0 123 0x04>;
> +                       interrupt-names = "inta", "intb", "intc", "intd/msi";
> +                       interrupts = <0 123 0x04>, <0 122 0x04>, <0 121 0x04>, <0 120 0x04>;
>                         clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
> 

The standard PCI interrupts should not be listed here, you need to
put them into the "interrupt-map" property so the of_irq_parse_and_map_pci()
function can translate them.

	Arnd

^ permalink raw reply

* Re: [PATCH v2 3/3] arm64: Add architecture support for PCI
From: Liviu Dudau @ 2014-02-27 16:48 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linaro-kernel-cunTk1MwBs8s++Sfvej+rw@public.gmane.org, linux-pci,
	Bjorn Helgaas, Catalin Marinas, Will Deacon,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, LKML, LAKML
In-Reply-To: <5402126.Dbh9PNPIjR@wuerfel>

On Thu, Feb 27, 2014 at 04:06:24PM +0000, Arnd Bergmann wrote:
> On Thursday 27 February 2014 13:09:59 Liviu Dudau wrote:
> 
> > +/*
> > + * PCI address space differs from physical memory address space
> > + */
> > +#define PCI_DMA_BUS_IS_PHYS	(0)
> > +
> > +extern int isa_dma_bridge_buggy;
> 
> I got curious about isa_dma_bridge_buggy: apparently this is a quirk for
> some old x86 bridges. We don't have those on arm64, and we also don't have
> ISA_DMA_API, so just define this to (0).

OK.

> 
> > +static inline int pci_domain_nr(struct pci_bus *bus)
> > +{
> > +	struct pci_host_bridge *bridge = to_pci_host_bridge(bus->bridge);
> > +
> > +	if (bridge)
> > +		return bridge->domain_nr;
> > +
> > +	return 0;
> > +}
> > +
> > +static inline int pci_proc_domain(struct pci_bus *bus)
> > +{
> > +	return pci_domain_nr(bus);
> > +}
> 
> And this one I would change to always return '1': we can deal with
> domain numbers showing up in /procfs for all buses, since there is
> no legacy software to worry about.

Will do, thanks for reviewing this.

> 
> > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > new file mode 100644
> > index 0000000..496df41
> > --- /dev/null
> > +++ b/arch/arm64/kernel/pci.c
> > @@ -0,1 +1,126 @@
> 
> Ok, this is nice and short. Let's see if we can reduce it to nothing ;-)
> 
> > +/*
> > + * Called after each bus is probed, but before its children are examined
> > + */
> > +void pcibios_fixup_bus(struct pci_bus *bus)
> > +{
> > +	struct pci_dev *dev;
> > +	struct resource *res;
> > +	int i;
> > +
> > +	if (!pci_is_root_bus(bus)) {
> > +		pci_read_bridge_bases(bus);
> > +
> > +		pci_bus_for_each_resource(bus, res, i) {
> > +			if (!res || !res->flags || res->parent)
> > +				continue;
> > +
> > +			/*
> > +			 * If we are going to reassign everything, we can
> > +			 * shrink the P2P resource to have zero size to
> > +			 * save space
> > +			 */
> > +			if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
> > +				res->flags |= IORESOURCE_UNSET;
> > +				res->start = 0;
> > +				res->end = -1;
> > +				continue;
> > +			}
> > +		}
> > +	}
> > +
> > +	list_for_each_entry(dev, &bus->devices, bus_list) {
> > +		/* Ignore fully discovered devices */
> > +		if (dev->is_added)
> > +			continue;
> > +
> > +		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
> > +
> > +		/* Read default IRQs and fixup if necessary */
> > +		dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
> > +	}
> > +}
> > +EXPORT_SYMBOL(pcibios_fixup_bus);
> 
> Shrinking the P2P resources I suppose is optional, but everything
> else is in fact needed for any DT based architecture. Could this
> be turned into a generic helper function in the PCI core that we
> can call from architecture code?
> 
> If you name it pci_generic_fixup_bus(), we can add a weak helper
> like:
> 
> void __weak pcibios_fixup_bus(struct pci_bus *bus)
> {
> 	pci_generic_fixup_bus(bus);
> }
> 
> for architectures like arm64 that don't actually need to do anything
> else.

Sure, it can be done. Don't know what is the policy for these kind of functions
that are used by architectures, but I can try sending a patch that adds the
weak implementations in the core PCI code.

> 
> > +/*
> > + * We don't have to worry about legacy ISA devices, so nothing to do here
> > + */
> > +resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> > +				resource_size_t size, resource_size_t align)
> > +{
> > +	return ALIGN(res->start, align);
> > +}
> > +EXPORT_SYMBOL(pcibios_align_resource);
> 
> Where did this come from? 

From an internal version that Will posted. See, we do talk to each other ;)


> The most common implementation seems to be
> 
> resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> 				resource_size_t size, resource_size_t align)
> {
> 	return start;
> }
> EXPORT_SYMBOL(pcibios_align_resource);
> 
> if you don't have to worry about ISA devices. The ALIGN() part seems to
> be handled by __find_resource() already.
> 
> I'd say that should be made the default implementation in the PCI core.
> 
> I'm also pretty sure you don't need the EXPORT_SYMBOL, since the PCI
> core cannot be a loadable module (yet).

OK.

> 
> > +int pcibios_enable_device(struct pci_dev *dev, int mask)
> > +{
> > +	return pci_enable_resources(dev, mask);
> > +}
> > +
> > +void pcibios_fixup_bridge_ranges(struct list_head *resources)
> > +{
> > +}
> 
> These are clearly the right implementations, but they should be weak
> functions, too.

pcibios_enable_devices is already subject to a patch series from Bjorn that make
the weak implementation do the right thing for arm64, so the final version will
not contain this.

> 
> > +#define IO_SPACE_PAGES	((IO_SPACE_LIMIT + 1) / PAGE_SIZE)
> > +static DECLARE_BITMAP(pci_iospace, IO_SPACE_PAGES);
> > +
> > +unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr)
> > +{
> > +	unsigned long start, len, virt_start;
> > +	int err;
> > +
> > +	if (res->end > IO_SPACE_LIMIT)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * try finding free space for the whole size first,
> > +	 * fall back to 64K if not available
> > +	 */
> > +	len = resource_size(res);
> > +	start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> > +				res->start / PAGE_SIZE, len / PAGE_SIZE, 0);
> > +	if (start == IO_SPACE_PAGES && len > SZ_64K) {
> > +		len = SZ_64K;
> > +		start = 0;
> > +		start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> > +					start, len / PAGE_SIZE, 0);
> > +	}
> > +
> > +	/* no 64K area found */
> > +	if (start == IO_SPACE_PAGES)
> > +		return -ENOMEM;
> > +
> > +	/* ioremap physical aperture to virtual aperture */
> > +	virt_start = start * PAGE_SIZE + (unsigned long)PCI_IOBASE;
> > +	err = ioremap_page_range(virt_start, virt_start + len,
> > +				phys_addr, __pgprot(PROT_DEVICE_nGnRE));
> > +	if (err)
> > +		return err;
> > +
> > +	bitmap_set(pci_iospace, start, len / PAGE_SIZE);
> > +
> > +	/* return io_offset */
> > +	return start * PAGE_SIZE - res->start;
> > +}
> 
> Maybe this can become an optional helper function with a separate Kconfig symbol
> to enable it.

Probably need to find a different name for it as well when it moves into core, arm
already has an externalised function with this name.

Best regards,
Liviu

> 
> 	Arnd
> 
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

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

^ permalink raw reply

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Philipp Zabel @ 2014-02-27 16:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: devel, devicetree, Russell King - ARM Linux, Greg Kroah-Hartman,
	dri-devel, Laurent Pinchart, kernel, Grant Likely,
	linux-arm-kernel
In-Reply-To: <530F43B9.800@ti.com>

Hi Tomi,

Am Donnerstag, den 27.02.2014, 15:55 +0200 schrieb Tomi Valkeinen:
> On 27/02/14 15:00, Russell King - ARM Linux wrote:
> > On Thu, Feb 27, 2014 at 02:06:25PM +0100, Philipp Zabel wrote:
> >> For the i.MX6 display subsystem there is no clear single master device,
> >> and the physical configuration changes across the SoC family. The
> >> i.MX6Q/i.MX6D SoCs have two separate display controller devices IPU1 and
> >> IPU2, with two output ports each.
> > 
> > Not also forgetting that there's another scenario too: you may wish
> > to drive IPU1 and IPU2 as two completely separate display subsystems
> > in some hardware, but as a combined display subsystem in others.
> > 
> > Here's another scenario.  You may have these two IPUs on the SoC, but
> > there's only one display output.  You want to leave the second IPU
> > disabled, as you wouldn't want it to be probed or even exposed to
> > userland.
> 
> I first want to say I don't see anything wrong with such a super node.
> As you say, it does describe hardware. But I also want to say that I
> still don't see a need for it. Or, maybe more exactly, I don't see a
> need for it in general. Maybe there are certain cases where two devices
> has to be controlled by a master device. Maybe this one is one of those.
> 
> In the imx case, why wouldn't this work, without any master node, with
> the IPU nodes separate in the DT data:
> 
> - One IPU enabled, one disabled: nothing special here, just set the
> other IPU to status="disabled" in the DT data. The driver for the
> enabled IPU would register the required DRM entities.

that should work. Let the enabled IPU create the imx-drm platform device
on probe, parse the device tree and ignore everything only hanging off
of the disabled IPU.

[Reordering a bit...]
>- Two IPUs in combined mode:
> 
> Pick one IPU as the master, and one as slave. Link the IPU nodes in DT
> data with phandles, say: master=<&ipu1> on the slave IPU and
> slave=<&ipu0> on the master.
> 
> The master one will register the DRM entities, and the slave one will
> just do what the master says.

That might work, too. Just let the each IPU scan the graph and try to
find the imx-drm master before creating the imx-drm platform device.
The first IPU fill find no preexisting master and create the imx-drm
platform device as above, adding the other IPU as well as the other
components with component_master_add_child. It just has to make sure
that the other IPU is added to the list before the encoders are.

The second IPU will scan the graph, find a preexisting master for the
other IPU node, register its component and just wait to be bound by the
master.

> - Two IPUs as separate units: almost the same as above, but both would
> independently register the DRM entities.

Here the second IPU would not be connected to the first IPU via the
graph - it would not find a preexisting imx-drm device when scanning its
graph and create its own imx-drm device just like the first IPU did.
As a result there are two completely separate DRM devices.

That being said, this change could be made at any time in the future,
in a backwards compatible fashion, by just declaring the imx-drm node
optional and ignoring it if it exists.

> As for the probe time "are we ready yet?" problem, the IPU driver can
> just delay registering the DRM entities until all the nodes in its graph
> have been probed. The component helpers can probably be used here.

This is what is happening right now, except that the two IPUs are not
obtained from the graph but are given as starting points via the ports
property in the imx-drm node.

> > On the face of it, the top-level super-device node doesn't look very
> > hardware-y, but it actually is - it's about how a board uses the
> > hardware provided.  This is entirely in keeping with the spirit of DT,
> > which is to describe what hardware is present and how it's connected
> > together, whether it be at the chip or board level.
> 
> No disagreement there. I'm mostly put off by the naming. The binding doc
> says it's a "DRM master device", compatible with "fsl,imx-drm". Now,
> naming may not be the most important thing in the world, but I'd rather
> use generic terms, not linux driver stack names.

Did anybody propose such a generic term? How about:

-imx-drm {
-	compatible = "fsl,imx-drm";
-	ports = <&ipu1_di0>, <&ipu1_di1>;
-};
+display-subsystem {
+	compatible = "fsl,imx-display-subsystem";
+	ports = <&ipu1_di0>, <&ipu1_di1>;
+};

> > If this wasn't the case, we wouldn't even attempt to describe what devices
> > we have on which I2C buses - we'd just list the hardware on the board
> > without giving any information about how it's wired together.
> > 
> > This is no different - however, it doesn't have (and shouldn't) be
> > subsystem specific... but - and this is the challenge we then face - how
> > do you decide that on one board with a single zImage kernel, with both
> > DRM and fbdev built-in, whether to use the DRM interfaces or the fbdev
> > interfaces?  We could have both matching the same compatible string, but
> > we'd also need some way to tell each other that they're not allowed to
> > bind.
> 
> Yes, that's an annoying problem, we have that on OMAP. It's a clear sign
> that our video support is rather messed up.
> 
> My opinion is that the fbdev and drm drivers for a single hardware
> should be exclusive at compile time. We don't allow multiple drivers for
> single device for other subsystems either, do we? Eventually we should
> have only one driver for one hardware device.
> 
> If that's not possible, then the drivers in question could have an
> option to enable or disable themselves, passed via the kernel command
> line, so that the user can select which subsystem to use.

That is the exact same problem as having multiple drivers that can bind
to the same device.

> > Before anyone argues against "it isn't hardware-y", stop and think.
> > What if I design a board with two Epson LCD controllers on board and
> > put a muxing arrangement on their output.  Is that one or two devices?
> > What if I want them to operate as one combined system?  What if I have
> > two different LCD controllers on a board.  How is this any different
> > from the two independent IPU hardware blocks integrated inside an iMX6
> > SoC with a muxing arrangement on their output?
> 
> Well, generally speaking, I think one option is to treat the two
> controllers separately and let the userspace handle it. That may or may
> not be viable, depending on the hardware, but to me it resembles very
> much a PC with two video cards.

And two graphics cards connected to the same output with a multiplexer
are a mess. This only works well if it is tightly integrated.

[...]
> So no, I don't have a problem with master device nodes in DT. I have a
> problem having pure SW stack nomenclature in the DT data (or even worse,
> SW stack entities in the DT data), and I have a problem requiring
> everyone to have a master device node if it's only needed for special cases.
>
> And yes, this series is about IMX bindings, not generic ones. And I'm
> also fine with requiring everyone to have a master device node, if it
> can be shown that it's the only sensible approach.

For i.MX, for now, let's keep the mandatory imx-drm node. Maybe rename
it so nobody can say we are leaking linux subsystem names into the
device tree.

regards
Philipp

^ permalink raw reply

* [PATCH v5 0/7] Move device tree graph parsing helpers to drivers/of
From: Philipp Zabel @ 2014-02-27 17:35 UTC (permalink / raw)
  To: Grant Likely, Mauro Carvalho Chehab, Russell King - ARM Linux
  Cc: Rob Herring, Sylwester Nawrocki, Laurent Pinchart,
	Guennadi Liakhovetski, Tomi Valkeinen, Kyungmin Park,
	linux-kernel, linux-media, devicetree, Philipp Zabel

Hi,

this version of the OF graph helper move series addresses a few of
Grant's and Tomi's comments.

Changes since v4:
 - Moved graph helpers into drivers/of/base.c
 - Fixed endpoint parsing patch to update users
 - Improved documentation, emphasizing features that differentiate
   the graph bindings from simple phandle graphs. Made it clear that
   this is not necessarily specific to data connections
 - Added cleanups to of_graph_get_next_endpoint routine
 - Added simplified binding for single port devices

regards
Philipp

Philipp Zabel (7):
  [media] of: move graph helpers from drivers/media/v4l2-core to
    drivers/of
  Documentation: of: Document graph bindings
  of: Warn if of_graph_get_next_endpoint is called with the root node
  of: Reduce indentation in of_graph_get_next_endpoint
  [media] of: move common endpoint parsing to drivers/of
  of: Implement simplified graph binding for single port devices
  of: Document simplified graph binding for single port devices

 Documentation/devicetree/bindings/graph.txt   | 137 +++++++++++++++++++++
 drivers/media/i2c/adv7343.c                   |   4 +-
 drivers/media/i2c/mt9p031.c                   |   4 +-
 drivers/media/i2c/s5k5baf.c                   |   3 +-
 drivers/media/i2c/tvp514x.c                   |   3 +-
 drivers/media/i2c/tvp7002.c                   |   3 +-
 drivers/media/platform/exynos4-is/fimc-is.c   |   6 +-
 drivers/media/platform/exynos4-is/media-dev.c |  13 +-
 drivers/media/platform/exynos4-is/mipi-csis.c |   5 +-
 drivers/media/v4l2-core/v4l2-of.c             | 133 +--------------------
 drivers/of/base.c                             | 165 ++++++++++++++++++++++++++
 include/linux/of_graph.h                      |  66 +++++++++++
 include/media/v4l2-of.h                       |  33 +-----
 13 files changed, 397 insertions(+), 178 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/graph.txt
 create mode 100644 include/linux/of_graph.h

-- 
1.8.5.3

^ permalink raw reply

* [PATCH v5 1/7] [media] of: move graph helpers from drivers/media/v4l2-core to drivers/of
From: Philipp Zabel @ 2014-02-27 17:35 UTC (permalink / raw)
  To: Grant Likely, Mauro Carvalho Chehab, Russell King - ARM Linux
  Cc: Rob Herring, Sylwester Nawrocki, Laurent Pinchart,
	Guennadi Liakhovetski, Tomi Valkeinen, Kyungmin Park,
	linux-kernel, linux-media, devicetree, Philipp Zabel
In-Reply-To: <1393522540-22887-1-git-send-email-p.zabel@pengutronix.de>

This patch moves the parsing helpers used to parse connected graphs
in the device tree, like the video interface bindings documented in
Documentation/devicetree/bindings/media/video-interfaces.txt, from
drivers/media/v4l2-core/v4l2-of.c into drivers/of/base.c.

This allows to reuse the same parser code from outside the V4L2
framework, most importantly from display drivers.
The functions v4l2_of_get_next_endpoint, v4l2_of_get_remote_port,
and v4l2_of_get_remote_port_parent are moved. They are renamed to
of_graph_get_next_endpoint, of_graph_get_remote_port, and
of_graph_get_remote_port_parent, respectively.
Since there are not that many current users yet, switch all of
them to the new functions right away.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
Changes since v4:
 - Moved into drivers/of/base.c instead of creating of_graph.c
---
 drivers/media/i2c/adv7343.c                   |   4 +-
 drivers/media/i2c/mt9p031.c                   |   4 +-
 drivers/media/i2c/s5k5baf.c                   |   3 +-
 drivers/media/i2c/tvp514x.c                   |   3 +-
 drivers/media/i2c/tvp7002.c                   |   3 +-
 drivers/media/platform/exynos4-is/fimc-is.c   |   6 +-
 drivers/media/platform/exynos4-is/media-dev.c |   3 +-
 drivers/media/platform/exynos4-is/mipi-csis.c |   3 +-
 drivers/media/v4l2-core/v4l2-of.c             | 117 -------------------------
 drivers/of/base.c                             | 118 ++++++++++++++++++++++++++
 include/linux/of_graph.h                      |  46 ++++++++++
 include/media/v4l2-of.h                       |  25 +-----
 12 files changed, 182 insertions(+), 153 deletions(-)
 create mode 100644 include/linux/of_graph.h

diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index d4e15a6..9d38f7b 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -26,12 +26,12 @@
 #include <linux/videodev2.h>
 #include <linux/uaccess.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <media/adv7343.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-of.h>
 
 #include "adv7343_regs.h"
 
@@ -410,7 +410,7 @@ adv7343_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index e5ddf47..192c4aa 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/of_graph.h>
 #include <linux/pm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -29,7 +30,6 @@
 #include <media/mt9p031.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-of.h>
 #include <media/v4l2-subdev.h>
 
 #include "aptina-pll.h"
@@ -943,7 +943,7 @@ mt9p031_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 77e10e0..2d768ef 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -21,6 +21,7 @@
 #include <linux/media.h>
 #include <linux/module.h>
 #include <linux/of_gpio.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
@@ -1855,7 +1856,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	node_ep = v4l2_of_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_next_endpoint(node, NULL);
 	if (!node_ep) {
 		dev_err(dev, "no endpoint defined at node %s\n",
 			node->full_name);
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 83d85df..ca00117 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -36,6 +36,7 @@
 #include <linux/module.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
@@ -1068,7 +1069,7 @@ tvp514x_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 912e1cc..c4e1e2c 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -30,6 +30,7 @@
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/v4l2-dv-timings.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-async.h>
@@ -957,7 +958,7 @@ tvp7002_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 13a4228..9bdfa45 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -24,13 +24,13 @@
 #include <linux/i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-of.h>
 #include <media/videobuf2-dma-contig.h>
 
 #include "media-dev.h"
@@ -167,10 +167,10 @@ static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor,
 	u32 tmp = 0;
 	int ret;
 
-	np = v4l2_of_get_next_endpoint(np, NULL);
+	np = of_graph_get_next_endpoint(np, NULL);
 	if (!np)
 		return -ENXIO;
-	np = v4l2_of_get_remote_port(np);
+	np = of_graph_get_remote_port(np);
 	if (!np)
 		return -ENXIO;
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index c1bce17..d0f82da 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
+#include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
@@ -473,7 +474,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 
 	pd->mux_id = (endpoint.port - 1) & 0x1;
 
-	rem = v4l2_of_get_remote_port_parent(ep);
+	rem = of_graph_get_remote_port_parent(ep);
 	of_node_put(ep);
 	if (rem == NULL) {
 		v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n",
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index f3c3591..fd1ae65 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -20,6 +20,7 @@
 #include <linux/memory.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_data/mipi-csis.h>
 #include <linux/platform_device.h>
@@ -762,7 +763,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 				 &state->max_num_lanes))
 		return -EINVAL;
 
-	node = v4l2_of_get_next_endpoint(node, NULL);
+	node = of_graph_get_next_endpoint(node, NULL);
 	if (!node) {
 		dev_err(&pdev->dev, "No port node at %s\n",
 				pdev->dev.of_node->full_name);
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
index 42e3e8a..f919db3 100644
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ b/drivers/media/v4l2-core/v4l2-of.c
@@ -152,120 +152,3 @@ int v4l2_of_parse_endpoint(const struct device_node *node,
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
-
-/**
- * v4l2_of_get_next_endpoint() - get next endpoint node
- * @parent: pointer to the parent device node
- * @prev: previous endpoint node, or NULL to get first
- *
- * Return: An 'endpoint' node pointer with refcount incremented. Refcount
- * of the passed @prev node is not decremented, the caller have to use
- * of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
-					struct device_node *prev)
-{
-	struct device_node *endpoint;
-	struct device_node *port = NULL;
-
-	if (!parent)
-		return NULL;
-
-	if (!prev) {
-		struct device_node *node;
-		/*
-		 * It's the first call, we have to find a port subnode
-		 * within this node or within an optional 'ports' node.
-		 */
-		node = of_get_child_by_name(parent, "ports");
-		if (node)
-			parent = node;
-
-		port = of_get_child_by_name(parent, "port");
-
-		if (port) {
-			/* Found a port, get an endpoint. */
-			endpoint = of_get_next_child(port, NULL);
-			of_node_put(port);
-		} else {
-			endpoint = NULL;
-		}
-
-		if (!endpoint)
-			pr_err("%s(): no endpoint nodes specified for %s\n",
-			       __func__, parent->full_name);
-		of_node_put(node);
-	} else {
-		port = of_get_parent(prev);
-		if (!port)
-			/* Hm, has someone given us the root node ?... */
-			return NULL;
-
-		/* Avoid dropping prev node refcount to 0. */
-		of_node_get(prev);
-		endpoint = of_get_next_child(port, prev);
-		if (endpoint) {
-			of_node_put(port);
-			return endpoint;
-		}
-
-		/* No more endpoints under this port, try the next one. */
-		do {
-			port = of_get_next_child(parent, port);
-			if (!port)
-				return NULL;
-		} while (of_node_cmp(port->name, "port"));
-
-		/* Pick up the first endpoint in this port. */
-		endpoint = of_get_next_child(port, NULL);
-		of_node_put(port);
-	}
-
-	return endpoint;
-}
-EXPORT_SYMBOL(v4l2_of_get_next_endpoint);
-
-/**
- * v4l2_of_get_remote_port_parent() - get remote port's parent node
- * @node: pointer to a local endpoint device_node
- *
- * Return: Remote device node associated with remote endpoint node linked
- *	   to @node. Use of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_remote_port_parent(
-			       const struct device_node *node)
-{
-	struct device_node *np;
-	unsigned int depth;
-
-	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
-
-	/* Walk 3 levels up only if there is 'ports' node. */
-	for (depth = 3; depth && np; depth--) {
-		np = of_get_next_parent(np);
-		if (depth == 2 && of_node_cmp(np->name, "ports"))
-			break;
-	}
-	return np;
-}
-EXPORT_SYMBOL(v4l2_of_get_remote_port_parent);
-
-/**
- * v4l2_of_get_remote_port() - get remote port node
- * @node: pointer to a local endpoint device_node
- *
- * Return: Remote port node associated with remote endpoint node linked
- *	   to @node. Use of_node_put() on it when done.
- */
-struct device_node *v4l2_of_get_remote_port(const struct device_node *node)
-{
-	struct device_node *np;
-
-	/* Get remote endpoint node. */
-	np = of_parse_phandle(node, "remote-endpoint", 0);
-	if (!np)
-		return NULL;
-	return of_get_next_parent(np);
-}
-EXPORT_SYMBOL(v4l2_of_get_remote_port);
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 89e888a..b2f223f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -21,6 +21,7 @@
 #include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
@@ -1982,3 +1983,120 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
 
 	return NULL;
 }
+
+/**
+ * of_graph_get_next_endpoint() - get next endpoint node
+ * @parent: pointer to the parent device node
+ * @prev: previous endpoint node, or NULL to get first
+ *
+ * Return: An 'endpoint' node pointer with refcount incremented. Refcount
+ * of the passed @prev node is not decremented, the caller have to use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
+					struct device_node *prev)
+{
+	struct device_node *endpoint;
+	struct device_node *port = NULL;
+
+	if (!parent)
+		return NULL;
+
+	if (!prev) {
+		struct device_node *node;
+		/*
+		 * It's the first call, we have to find a port subnode
+		 * within this node or within an optional 'ports' node.
+		 */
+		node = of_get_child_by_name(parent, "ports");
+		if (node)
+			parent = node;
+
+		port = of_get_child_by_name(parent, "port");
+
+		if (port) {
+			/* Found a port, get an endpoint. */
+			endpoint = of_get_next_child(port, NULL);
+			of_node_put(port);
+		} else {
+			endpoint = NULL;
+		}
+
+		if (!endpoint)
+			pr_err("%s(): no endpoint nodes specified for %s\n",
+			       __func__, parent->full_name);
+		of_node_put(node);
+	} else {
+		port = of_get_parent(prev);
+		if (!port)
+			/* Hm, has someone given us the root node ?... */
+			return NULL;
+
+		/* Avoid dropping prev node refcount to 0. */
+		of_node_get(prev);
+		endpoint = of_get_next_child(port, prev);
+		if (endpoint) {
+			of_node_put(port);
+			return endpoint;
+		}
+
+		/* No more endpoints under this port, try the next one. */
+		do {
+			port = of_get_next_child(parent, port);
+			if (!port)
+				return NULL;
+		} while (of_node_cmp(port->name, "port"));
+
+		/* Pick up the first endpoint in this port. */
+		endpoint = of_get_next_child(port, NULL);
+		of_node_put(port);
+	}
+
+	return endpoint;
+}
+EXPORT_SYMBOL(of_graph_get_next_endpoint);
+
+/**
+ * of_graph_get_remote_port_parent() - get remote port's parent node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote device node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_port_parent(
+			       const struct device_node *node)
+{
+	struct device_node *np;
+	unsigned int depth;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+
+	/* Walk 3 levels up only if there is 'ports' node. */
+	for (depth = 3; depth && np; depth--) {
+		np = of_get_next_parent(np);
+		if (depth == 2 && of_node_cmp(np->name, "ports"))
+			break;
+	}
+	return np;
+}
+EXPORT_SYMBOL(of_graph_get_remote_port_parent);
+
+/**
+ * of_graph_get_remote_port() - get remote port node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: Remote port node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_port(const struct device_node *node)
+{
+	struct device_node *np;
+
+	/* Get remote endpoint node. */
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!np)
+		return NULL;
+	return of_get_next_parent(np);
+}
+EXPORT_SYMBOL(of_graph_get_remote_port);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
new file mode 100644
index 0000000..3bbeb60
--- /dev/null
+++ b/include/linux/of_graph.h
@@ -0,0 +1,46 @@
+/*
+ * OF graph binding parsing helpers
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_OF_GRAPH_H
+#define __LINUX_OF_GRAPH_H
+
+#ifdef CONFIG_OF
+struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
+					struct device_node *previous);
+struct device_node *of_graph_get_remote_port_parent(
+					const struct device_node *node);
+struct device_node *of_graph_get_remote_port(const struct device_node *node);
+#else
+
+static inline struct device_node *of_graph_get_next_endpoint(
+					const struct device_node *parent,
+					struct device_node *previous)
+{
+	return NULL;
+}
+
+static inline struct device_node *of_graph_get_remote_port_parent(
+					const struct device_node *node)
+{
+	return NULL;
+}
+
+static inline struct device_node *of_graph_get_remote_port(
+					const struct device_node *node)
+{
+	return NULL;
+}
+
+#endif /* CONFIG_OF */
+
+#endif /* __LINUX_OF_GRAPH_H */
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
index 541cea4..3a49735 100644
--- a/include/media/v4l2-of.h
+++ b/include/media/v4l2-of.h
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/of_graph.h>
 
 #include <media/v4l2-mediabus.h>
 
@@ -72,11 +73,6 @@ struct v4l2_of_endpoint {
 #ifdef CONFIG_OF
 int v4l2_of_parse_endpoint(const struct device_node *node,
 			   struct v4l2_of_endpoint *endpoint);
-struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
-					struct device_node *previous);
-struct device_node *v4l2_of_get_remote_port_parent(
-					const struct device_node *node);
-struct device_node *v4l2_of_get_remote_port(const struct device_node *node);
 #else /* CONFIG_OF */
 
 static inline int v4l2_of_parse_endpoint(const struct device_node *node,
@@ -85,25 +81,6 @@ static inline int v4l2_of_parse_endpoint(const struct device_node *node,
 	return -ENOSYS;
 }
 
-static inline struct device_node *v4l2_of_get_next_endpoint(
-					const struct device_node *parent,
-					struct device_node *previous)
-{
-	return NULL;
-}
-
-static inline struct device_node *v4l2_of_get_remote_port_parent(
-					const struct device_node *node)
-{
-	return NULL;
-}
-
-static inline struct device_node *v4l2_of_get_remote_port(
-					const struct device_node *node)
-{
-	return NULL;
-}
-
 #endif /* CONFIG_OF */
 
 #endif /* _V4L2_OF_H */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v5 2/7] Documentation: of: Document graph bindings
From: Philipp Zabel @ 2014-02-27 17:35 UTC (permalink / raw)
  To: Grant Likely, Mauro Carvalho Chehab, Russell King - ARM Linux
  Cc: Rob Herring, Sylwester Nawrocki, Laurent Pinchart,
	Guennadi Liakhovetski, Tomi Valkeinen, Kyungmin Park,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Philipp Zabel
In-Reply-To: <1393522540-22887-1-git-send-email-p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

The device tree graph bindings as used by V4L2 and documented in
Documentation/device-tree/bindings/media/video-interfaces.txt contain
generic parts that are not media specific but could be useful for any
subsystem with data flow between multiple devices. This document
describe the generic bindings.

Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
Changes since v4:
 - Differentiate from graphs made by simple phandle links
 - Do not mention data flow except in video-interfaces example
 - 
---
 Documentation/devicetree/bindings/graph.txt | 129 ++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/graph.txt

diff --git a/Documentation/devicetree/bindings/graph.txt b/Documentation/devicetree/bindings/graph.txt
new file mode 100644
index 0000000..554865b
--- /dev/null
+++ b/Documentation/devicetree/bindings/graph.txt
@@ -0,0 +1,129 @@
+Common bindings for device graphs
+
+General concept
+---------------
+
+The hierarchical organisation of the device tree is well suited to describe
+control flow to devices, but there can be more complex connections between
+devices that work together to form a logical compound device, following an
+arbitrarily complex graph.
+There already is a simple directed graph between devices tree nodes using
+phandle properties pointing to other nodes to describe connections that
+can not be inferred from device tree parent-child relationships. The device
+tree graph bindings described herein abstract more complex devices that can
+have multiple specifiable ports, each of which can be linked to one or more
+ports of other devices.
+
+These common bindings do not contain any information about the direction of
+type of the connections, they just map their existence. Specific properties
+may be described by specialized bindings depending on the type of connection.
+
+To see how this binding applies to video pipelines, for example, see
+Documentation/device-tree/bindings/media/video-interfaces.txt.
+Here the ports describe data interfaces, and the links between them are
+the connecting data buses. A single port with multiple connections can
+correspond to multiple devices being connected to the same physical bus.
+
+Organisation of ports and endpoints
+-----------------------------------
+
+Ports are described by child 'port' nodes contained in the device node.
+Each port node contains an 'endpoint' subnode for each remote device port
+connected to this port. If a single port is connected to more than one
+remote device, an 'endpoint' child node must be provided for each link.
+If more than one port is present in a device node or there is more than one
+endpoint at a port, or a port node needs to be associated with a selected
+hardware interface, a common scheme using '#address-cells', '#size-cells'
+and 'reg' properties is used number the nodes.
+
+device {
+        ...
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+	        #address-cells = <1>;
+	        #size-cells = <0>;
+		reg = <0>;
+
+                endpoint@0 {
+			reg = <0>;
+			...
+		};
+                endpoint@1 {
+			reg = <1>;
+			...
+		};
+        };
+
+        port@1 {
+		reg = <1>;
+
+		endpoint { ... };
+	};
+};
+
+All 'port' nodes can be grouped under an optional 'ports' node, which
+allows to specify #address-cells, #size-cells properties for the 'port'
+nodes independently from any other child device nodes a device might
+have.
+
+device {
+        ...
+        ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                        ...
+                        endpoint@0 { ... };
+                        endpoint@1 { ... };
+                };
+
+                port@1 { ... };
+        };
+};
+
+Links between endpoints
+-----------------------
+
+Each endpoint should contain a 'remote-endpoint' phandle property that points
+to the corresponding endpoint in the port of the remote device. In turn, the
+remote endpoint should contain a 'remote-endpoint' property. If it has one,
+it must not point to another than the local endpoint. Two endpoints with their
+'remote-endpoint' phandles pointing at each other form a link between the
+containing ports.
+
+device_1 {
+        port {
+                device_1_output: endpoint {
+                        remote-endpoint = <&device_2_input>;
+                };
+        };
+};
+
+device_1 {
+        port {
+                device_2_input: endpoint {
+                        remote-endpoint = <&device_1_output>;
+                };
+        };
+};
+
+
+Required properties
+-------------------
+
+If there is more than one 'port' or more than one 'endpoint' node or 'reg'
+property is present in port and/or endpoint nodes the following properties
+are required in a relevant parent node:
+
+ - #address-cells : number of cells required to define port/endpoint
+                    identifier, should be 1.
+ - #size-cells    : should be zero.
+
+Optional endpoint properties
+----------------------------
+
+- remote-endpoint: phandle to an 'endpoint' subnode of a remote device node.
+
-- 
1.8.5.3

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

^ permalink raw reply related

* [PATCH v5 3/7] of: Warn if of_graph_get_next_endpoint is called with the root node
From: Philipp Zabel @ 2014-02-27 17:35 UTC (permalink / raw)
  To: Grant Likely, Mauro Carvalho Chehab, Russell King - ARM Linux
  Cc: Rob Herring, Sylwester Nawrocki, Laurent Pinchart,
	Guennadi Liakhovetski, Tomi Valkeinen, Kyungmin Park,
	linux-kernel, linux-media, devicetree, Philipp Zabel
In-Reply-To: <1393522540-22887-1-git-send-email-p.zabel@pengutronix.de>

If of_graph_get_next_endpoint is given a parentless node instead of an
endpoint node, it is clearly a bug.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/of/base.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index b2f223f..6e650cf 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2028,8 +2028,8 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 		of_node_put(node);
 	} else {
 		port = of_get_parent(prev);
-		if (!port)
-			/* Hm, has someone given us the root node ?... */
+		if (WARN_ONCE(!port, "%s(): endpoint has no parent node\n",
+			      __func__))
 			return NULL;
 
 		/* Avoid dropping prev node refcount to 0. */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v5 4/7] of: Reduce indentation in of_graph_get_next_endpoint
From: Philipp Zabel @ 2014-02-27 17:35 UTC (permalink / raw)
  To: Grant Likely, Mauro Carvalho Chehab, Russell King - ARM Linux
  Cc: Rob Herring, Sylwester Nawrocki, Laurent Pinchart,
	Guennadi Liakhovetski, Tomi Valkeinen, Kyungmin Park,
	linux-kernel, linux-media, devicetree, Philipp Zabel
In-Reply-To: <1393522540-22887-1-git-send-email-p.zabel@pengutronix.de>

A 'return endpoint;' at the end of the (!prev) case allows to
reduce the indentation level of the (prev) case.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/of/base.c | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6e650cf..8ecca7a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2026,32 +2026,34 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 			pr_err("%s(): no endpoint nodes specified for %s\n",
 			       __func__, parent->full_name);
 		of_node_put(node);
-	} else {
-		port = of_get_parent(prev);
-		if (WARN_ONCE(!port, "%s(): endpoint has no parent node\n",
-			      __func__))
-			return NULL;
 
-		/* Avoid dropping prev node refcount to 0. */
-		of_node_get(prev);
-		endpoint = of_get_next_child(port, prev);
-		if (endpoint) {
-			of_node_put(port);
-			return endpoint;
-		}
+		return endpoint;
+	}
 
-		/* No more endpoints under this port, try the next one. */
-		do {
-			port = of_get_next_child(parent, port);
-			if (!port)
-				return NULL;
-		} while (of_node_cmp(port->name, "port"));
+	port = of_get_parent(prev);
+	if (WARN_ONCE(!port, "%s(): endpoint has no parent node\n",
+		      __func__))
+		return NULL;
 
-		/* Pick up the first endpoint in this port. */
-		endpoint = of_get_next_child(port, NULL);
+	/* Avoid dropping prev node refcount to 0. */
+	of_node_get(prev);
+	endpoint = of_get_next_child(port, prev);
+	if (endpoint) {
 		of_node_put(port);
+		return endpoint;
 	}
 
+	/* No more endpoints under this port, try the next one. */
+	do {
+		port = of_get_next_child(parent, port);
+		if (!port)
+			return NULL;
+	} while (of_node_cmp(port->name, "port"));
+
+	/* Pick up the first endpoint in this port. */
+	endpoint = of_get_next_child(port, NULL);
+	of_node_put(port);
+
 	return endpoint;
 }
 EXPORT_SYMBOL(of_graph_get_next_endpoint);
-- 
1.8.5.3

^ permalink raw reply related


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