Devicetree
 help / color / mirror / Atom feed
* [PATCH 06/13] MIPS: jz4780: DTS: Add node for the jz4780-pinctrl driver
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

For a description of the devicetree node, please read
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 arch/mips/boot/dts/ingenic/jz4780.dtsi | 333 +++++++++++++++++++++++++++++++++
 1 file changed, 333 insertions(+)

diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index b868b429add2..0135b2b0c6ad 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -44,6 +44,339 @@
 		#clock-cells = <1>;
 	};
 
+	pinctrl: ingenic-pinctrl@10010000 {
+		compatible = "ingenic,jz4780-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio-chips {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			gpa: gpa {
+				reg = <0x10010000 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <17>;
+
+				ingenic,pull-ups = <0x3fffffff>;
+			};
+
+			gpb: gpb {
+				reg = <0x10010100 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <16>;
+
+				ingenic,pull-downs = <0x000f0c03>;
+				ingenic,pull-ups   = <0xfff0030c>;
+			};
+
+			gpc: gpc {
+				reg = <0x10010200 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <15>;
+
+				ingenic,pull-ups = <0xffffffff>;
+			};
+
+			gpd: gpd {
+				reg = <0x10010300 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <14>;
+
+				ingenic,pull-downs = <0x0000b000>;
+				ingenic,pull-ups   = <0xffff4fff>;
+			};
+
+			gpe: gpe {
+				reg = <0x10010400 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <13>;
+
+				ingenic,pull-downs = <0x00000483>;
+				ingenic,pull-ups   = <0xfffffb7c>;
+			};
+
+			gpf: gpf {
+				reg = <0x10010500 0x100>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				interrupt-parent = <&intc>;
+				interrupts = <12>;
+
+				ingenic,pull-downs = <0x00580ff0>;
+				ingenic,pull-ups   = <0xffa7f00f>;
+			};
+		};
+
+		bias-configs {
+			nobias: nobias {
+				bias-disable;
+			};
+
+			pull_up: pull_up {
+				bias-pull-up;
+			};
+
+			pull_down: pull_down {
+				bias-pull-down;
+			};
+		};
+
+		functions {
+			pinfunc-uart0 {
+				pins_uart0_data: uart0-data {
+					ingenic,pins = <&gpf  0 0 &pull_up  /* rxd */
+							&gpf  3 0 &nobias>; /* txd */
+				};
+
+				pins_uart0_dataplusflow: uart0-dataplusflow {
+					ingenic,pins = <&gpf  0 0 &pull_up  /* rxd */
+							&gpf  1 0 &nobias   /* cts */
+							&gpf  2 0 &nobias   /* rts */
+							&gpf  3 0 &nobias>; /* txd */
+				};
+			};
+
+			pinfunc-uart1 {
+				pins_uart1_data: uart1-data {
+					ingenic,pins = <&gpd  26 0 &pull_up  /* rxd */
+							&gpd  28 0 &nobias>; /* txd */
+				};
+
+				pins_uart1_dataplusflow: uart1-dataplusflow {
+					ingenic,pins = <&gpd  26 0 &pull_up  /* rxd */
+							&gpd  27 0 &nobias   /* cts */
+							&gpd  29 0 &nobias   /* rts */
+							&gpd  28 0 &nobias>; /* txd */
+				};
+			};
+
+			pinfunc-uart2 {
+				pins_uart2_data: uart2-data {
+					ingenic,pins = <&gpd  6 1 &nobias  /* rxd */
+							&gpd  7 1 &nobias>; /* txd */
+				};
+
+				pins_uart2_dataplusflow: uart2-dataplusflow {
+					ingenic,pins = <&gpd  6 1 &nobias  /* rxd */
+							&gpd  5 1 &nobias   /* cts */
+							&gpd  4 1 &nobias   /* rts */
+							&gpd  7 1 &nobias>; /* txd */
+				};
+			};
+
+			pinfunc-uart3 {
+				pins_uart3_data: uart3-data {
+					ingenic,pins = <&gpd 12 0 &pull_down /* rxd */
+							&gpe  5 1 &nobias>;  /* txd */
+				};
+
+				pins_uart3_dataplusflow: uart3-dataplusflow {
+					ingenic,pins = <&gpd 12 0 &pull_down /* rxd */
+							&gpe  5 1 &nobias    /* txd */
+							&gpe  8 0 &nobias    /* cts */
+							&gpe  9 0 &nobias>;  /* rts */
+				};
+			};
+
+			pinfunc-uart4 {
+				pins_uart4_data: uart4-data {
+					ingenic,pins = <&gpc 20 2 &pull_up   /* rxd */
+							&gpc 10 2 &nobias>;  /* txd */
+				};
+			};
+
+			pinfunc-msc0 {
+				pins_msc0_pa: msc0-pa {
+					ingenic,pins = <&gpa  4 1 &nobias   /* d4 */
+							&gpa  5 1 &nobias   /* d5 */
+							&gpa  6 1 &nobias   /* d6 */
+							&gpa  7 1 &nobias   /* d7 */
+							&gpa 18 1 &nobias   /* clk */
+							&gpa 19 1 &nobias   /* cmd */
+							&gpa 20 1 &nobias   /* d0 */
+							&gpa 21 1 &nobias   /* d1 */
+							&gpa 22 1 &nobias   /* d2 */
+							&gpa 23 1 &nobias   /* d3 */
+							&gpa 24 1 &nobias>; /* rst */
+				};
+
+				pins_msc0_pe: msc0-pe {
+					ingenic,pins = <&gpe 20 0 &nobias   /* d0 */
+							&gpe 21 0 &nobias   /* d1 */
+							&gpe 22 0 &nobias   /* d2 */
+							&gpe 23 0 &nobias   /* d3 */
+							&gpe 28 0 &nobias   /* clk */
+							&gpe 29 0 &nobias>; /* cmd */
+				};
+			};
+
+			pinfunc-msc1 {
+				pins_msc1_pd: msc1-pd {
+					ingenic,pins = <&gpd 20 0 &nobias   /* d0 */
+							&gpd 21 0 &nobias   /* d1 */
+							&gpd 22 0 &nobias   /* d2 */
+							&gpd 23 0 &nobias   /* d3 */
+							&gpd 24 0 &nobias   /* clk */
+							&gpd 25 0 &nobias>; /* cmd */
+				};
+
+				pins_msc1_pe: msc1-pe {
+					ingenic,pins = <&gpe 20 1 &nobias   /* d0 */
+							&gpe 21 1 &nobias   /* d1 */
+							&gpe 22 1 &nobias   /* d2 */
+							&gpe 23 1 &nobias   /* d3 */
+							&gpe 28 1 &nobias   /* clk */
+							&gpe 29 1 &nobias>; /* cmd */
+				};
+			};
+
+			pinfunc-nemc {
+				pins_nemc_data: nemc-data {
+					ingenic,pins = <&gpa 0 0 &nobias    /* sd0 */
+							&gpa 1 0 &nobias    /* sd1 */
+							&gpa 2 0 &nobias    /* sd2 */
+							&gpa 3 0 &nobias    /* sd3 */
+							&gpa 4 0 &nobias    /* sd4 */
+							&gpa 5 0 &nobias    /* sd5 */
+							&gpa 6 0 &nobias    /* sd6 */
+							&gpa 7 0 &nobias>;  /* sd7 */
+				};
+
+				pins_nemc_cle_ale: nemc-cle-ale {
+					ingenic,pins = <&gpb 0 0 &nobias    /* sa0_cl */
+							&gpb 1 0 &nobias>;  /* sa1_al */
+				};
+
+				pins_nemc_addr: nemc-addr {
+					ingenic,pins = <&gpb 0 0 &nobias    /* sa0_cl */
+							&gpb 1 0 &nobias    /* sa1_al */
+							&gpb 2 0 &nobias    /* sa2 */
+							&gpb 3 0 &nobias    /* sa3 */
+							&gpb 4 0 &nobias    /* sa4 */
+							&gpb 5 0 &nobias>;  /* sa5 */
+				};
+
+				pins_nemc_rd_we: nemc-rd-we {
+					ingenic,pins = <&gpa 16 0 &nobias   /* rd */
+							&gpa 17 0 &nobias>; /* we */
+				};
+
+				pins_nemc_frd_fwe: nemc-frd-fwe {
+					ingenic,pins = <&gpa 18 0 &nobias   /* rd */
+							&gpa 19 0 &nobias>; /* we */
+				};
+
+				pins_nemc_cs1: nemc-cs1 {
+					ingenic,pins = <&gpa 21 0 &nobias>; /* cs1 */
+				};
+
+				pins_nemc_cs6: nemc-cs6 {
+					ingenic,pins = <&gpa 26 0 &nobias>; /* cs6 */
+				};
+			};
+
+			pinfunc-i2c0 {
+				pins_i2c0_data: i2c0-data{
+					ingenic,pins = <&gpd  30 0 &nobias  /* sda */
+							&gpd  31 0 &nobias>; /* sck */
+				};
+			};
+
+			pinfunc-i2c1 {
+				pins_i2c1_data: i2c1-data{
+					ingenic,pins = <&gpe  30 0 &nobias  /* sda */
+							&gpe  31 0 &nobias>; /* sck */
+				};
+			};
+
+			pinfunc-i2c2 {
+				pins_i2c2_data: i2c2-data{
+					ingenic,pins = <&gpf  16 2 &nobias  /* sda */
+							&gpf  17 2 &nobias>; /* sck */
+				};
+			};
+
+			pinfunc-i2c3 {
+				pins_i2c3_data: i2c3-data{
+					ingenic,pins = <&gpd  10 1 &nobias  /* sda */
+							&gpd  11 1 &nobias>; /* sck */
+				};
+			};
+
+			pinfunc-i2c4 {
+				pins_i2c4_data: i2c4-data-pe{
+					ingenic,pins = <&gpe  12 1 &nobias  /* sda */
+							&gpe  13 1 &nobias>; /* sck */
+				};
+
+				pins_i2c4_data_pf: i2c4-data-pf{
+					ingenic,pins = <&gpf 25 1 &nobias /* hdmi_sda */
+							&gpf 24 1 &nobias>; /* hdmi_sck */
+				};
+			};
+
+			pinfunc-cim {
+				pins_cim: cim-pb {
+					ingenic,pins = <&gpb   6 0 &nobias
+							&gpb   7 0 &nobias
+							&gpb   8 0 &nobias
+							&gpb   9 0 &nobias
+							&gpb  10 0 &nobias
+							&gpb  11 0 &nobias
+							&gpb  12 0 &nobias
+							&gpb  13 0 &nobias
+							&gpb  14 0 &nobias
+							&gpb  15 0 &nobias
+							&gpb  16 0 &nobias
+							&gpb  17 0 &nobias>;
+				};
+			};
+		};
+	};
+
 	uart0: serial@10030000 {
 		compatible = "ingenic,jz4780-uart";
 		reg = <0x10030000 0x100>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH 07/13] MIPS: JZ4740: Qi LB60: Add pinctrl configuration for several drivers
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

We set the pin configuration for the jz4740-nand, jz4740-mmc,
jz4740-fb, jz4740-pwm and jz4740-uart drivers.

This will permit those drivers to be cleaned out of the custom GPIO code
that they currently use.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 arch/mips/boot/dts/ingenic/qi_lb60.dts |  5 ++++
 arch/mips/jz4740/board-qi_lb60.c       | 47 +++++++++++++++++++++++++++-------
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts
index be1a7d3a3e1b..7b98c4f57b1c 100644
--- a/arch/mips/boot/dts/ingenic/qi_lb60.dts
+++ b/arch/mips/boot/dts/ingenic/qi_lb60.dts
@@ -17,3 +17,8 @@
 &rtc_dev {
 	system-power-controller;
 };
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart0_data>;
+};
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index a5bd94b95263..c6ee50a44cb3 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -22,6 +22,8 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/power_supply.h>
 #include <linux/power/jz4740-battery.h>
 #include <linux/power/gpio-charger.h>
@@ -447,13 +449,41 @@ static struct platform_device *jz_platform_devices[] __initdata = {
 	&qi_lb60_audio_device,
 };
 
-static void __init board_gpio_setup(void)
-{
-	/* We only need to enable/disable pullup here for pins used in generic
-	 * drivers. Everything else is done by the drivers themselves. */
-	jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N);
-	jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD);
-}
+static unsigned long pin_cfg_bias_disable[] = {
+	    PIN_CONFIG_BIAS_DISABLE,
+};
+
+static struct pinctrl_map pin_map[] __initdata = {
+	/* NAND pin configuration */
+	PIN_MAP_MUX_GROUP_DEFAULT("jz4740-nand",
+			"10010000.jz4740-pinctrl",
+			"pinfunc-nand", "pins-nand"),
+
+	/* fbdev pin configuration */
+	PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_DEFAULT,
+			"10010000.jz4740-pinctrl",
+			"pinfunc-lcd", "pins-lcd-8bit"),
+	PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_SLEEP,
+			"10010000.jz4740-pinctrl",
+			"pinfunc-lcd", "pins-lcd-no-pins"),
+
+	/* MMC pin configuration */
+	PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0",
+			"10010000.jz4740-pinctrl",
+			"pinfunc-msc", "pins-msc-4bit"),
+	PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
+			"10010000.jz4740-pinctrl",
+			"PD0", pin_cfg_bias_disable),
+	PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0",
+			"10010000.jz4740-pinctrl",
+			"PD2", pin_cfg_bias_disable),
+
+	/* PWM pin configuration */
+	PIN_MAP_MUX_GROUP_DEFAULT("jz4740-pwm",
+			"10010000.jz4740-pinctrl",
+			"pinfunc-pwm4", "pins-pwm4"),
+};
+
 
 static int __init qi_lb60_init_platform_devices(void)
 {
@@ -469,6 +499,7 @@ static int __init qi_lb60_init_platform_devices(void)
 				ARRAY_SIZE(qi_lb60_spi_board_info));
 
 	pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup));
+	pinctrl_register_mappings(pin_map, ARRAY_SIZE(pin_map));
 
 	return platform_add_devices(jz_platform_devices,
 					ARRAY_SIZE(jz_platform_devices));
@@ -479,8 +510,6 @@ static int __init qi_lb60_board_setup(void)
 {
 	printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n");
 
-	board_gpio_setup();
-
 	if (qi_lb60_init_platform_devices())
 		panic("Failed to initialize platform devices");
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 08/13] MIPS: JZ4780: CI20: Add pinctrl configuration for several drivers
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

We set the pin configuration for the jz4780-nand and jz4780-uart
drivers.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 arch/mips/boot/dts/ingenic/ci20.dts | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 1652d8d60b1e..e2cd3ebb7be8 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -29,18 +29,30 @@
 
 &uart0 {
 	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart0_data>;
 };
 
 &uart1 {
 	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart1_data>;
 };
 
 &uart3 {
 	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart2_dataplusflow>;
 };
 
 &uart4 {
 	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pins_uart4_data>;
 };
 
 &nemc {
@@ -61,6 +73,16 @@
 		ingenic,nemc-tAW = <15>;
 		ingenic,nemc-tSTRV = <100>;
 
+		/*
+		 * Only CLE/ALE are needed for the devices that are connected, rather
+		 * than the full address line set.
+		 */
+		pinctrl-names = "default";
+		pinctrl-0 = <&pins_nemc_data
+				 &pins_nemc_cle_ale
+				 &pins_nemc_rd_we
+				 &pins_nemc_frd_fwe>;
+
 		nand@1 {
 			reg = <1>;
 
@@ -69,6 +91,9 @@
 			nand-ecc-mode = "hw";
 			nand-on-flash-bbt;
 
+			pinctrl-names = "default";
+			pinctrl-0 = <&pins_nemc_cs1>;
+
 			partitions {
 				compatible = "fixed-partitions";
 				#address-cells = <2>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH 09/13] mmc: jz4740: Let the pinctrl driver configure the pins
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

Now that the JZ4740 and similar SoCs have a pinctrl driver, we rely on
the pins being properly configured before the driver probes.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/mmc/host/jz4740_mmc.c | 59 ++-----------------------------------------
 1 file changed, 2 insertions(+), 57 deletions(-)

diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 819ad32964fc..28a8e0acd70a 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -27,7 +27,6 @@
 
 #include <linux/bitops.h>
 #include <linux/gpio.h>
-#include <asm/mach-jz4740/gpio.h>
 #include <asm/cacheflush.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
@@ -906,15 +905,6 @@ static const struct mmc_host_ops jz4740_mmc_ops = {
 	.enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
 };
 
-static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = {
-	JZ_GPIO_BULK_PIN(MSC_CMD),
-	JZ_GPIO_BULK_PIN(MSC_CLK),
-	JZ_GPIO_BULK_PIN(MSC_DATA0),
-	JZ_GPIO_BULK_PIN(MSC_DATA1),
-	JZ_GPIO_BULK_PIN(MSC_DATA2),
-	JZ_GPIO_BULK_PIN(MSC_DATA3),
-};
-
 static int jz4740_mmc_request_gpio(struct device *dev, int gpio,
 	const char *name, bool output, int value)
 {
@@ -978,15 +968,6 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev)
 		gpio_free(pdata->gpio_power);
 }
 
-static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host)
-{
-	size_t num_pins = ARRAY_SIZE(jz4740_mmc_pins);
-	if (host->pdata && host->pdata->data_1bit)
-		num_pins -= 3;
-
-	return num_pins;
-}
-
 static int jz4740_mmc_probe(struct platform_device* pdev)
 {
 	int ret;
@@ -1027,15 +1008,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
 		goto err_free_host;
 	}
 
-	ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to request mmc pins: %d\n", ret);
-		goto err_free_host;
-	}
-
 	ret = jz4740_mmc_request_gpios(mmc, pdev);
 	if (ret)
-		goto err_gpio_bulk_free;
+		goto err_release_dma;
 
 	mmc->ops = &jz4740_mmc_ops;
 	mmc->f_min = JZ_MMC_CLK_RATE / 128;
@@ -1091,10 +1066,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
 	free_irq(host->irq, host);
 err_free_gpios:
 	jz4740_mmc_free_gpios(pdev);
-err_gpio_bulk_free:
+err_release_dma:
 	if (host->use_dma)
 		jz4740_mmc_release_dma_channels(host);
-	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
 err_free_host:
 	mmc_free_host(mmc);
 
@@ -1114,7 +1088,6 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
 	free_irq(host->irq, host);
 
 	jz4740_mmc_free_gpios(pdev);
-	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
 
 	if (host->use_dma)
 		jz4740_mmc_release_dma_channels(host);
@@ -1124,39 +1097,11 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
-static int jz4740_mmc_suspend(struct device *dev)
-{
-	struct jz4740_mmc_host *host = dev_get_drvdata(dev);
-
-	jz_gpio_bulk_suspend(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
-
-	return 0;
-}
-
-static int jz4740_mmc_resume(struct device *dev)
-{
-	struct jz4740_mmc_host *host = dev_get_drvdata(dev);
-
-	jz_gpio_bulk_resume(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
-
-	return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,
-	jz4740_mmc_resume);
-#define JZ4740_MMC_PM_OPS (&jz4740_mmc_pm_ops)
-#else
-#define JZ4740_MMC_PM_OPS NULL
-#endif
-
 static struct platform_driver jz4740_mmc_driver = {
 	.probe = jz4740_mmc_probe,
 	.remove = jz4740_mmc_remove,
 	.driver = {
 		.name = "jz4740-mmc",
-		.pm = JZ4740_MMC_PM_OPS,
 	},
 };
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 10/13] mtd: nand: jz4740: Let the pinctrl driver configure the pins
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

Before, this NAND driver would set itself the configuration of the
chip-select pins for the various NAND banks.

Now that the JZ4740 and similar SoCs have a pinctrl driver, we rely on
the pins being properly configured before the driver probes.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/mtd/nand/jz4740_nand.c | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index 5551c36adbdf..0d06a1f07d82 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -25,7 +25,6 @@
 
 #include <linux/gpio.h>
 
-#include <asm/mach-jz4740/gpio.h>
 #include <asm/mach-jz4740/jz4740_nand.h>
 
 #define JZ_REG_NAND_CTRL	0x50
@@ -310,34 +309,20 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 			       uint8_t *nand_dev_id)
 {
 	int ret;
-	int gpio;
-	char gpio_name[9];
 	char res_name[6];
 	uint32_t ctrl;
 	struct nand_chip *chip = &nand->chip;
 	struct mtd_info *mtd = nand_to_mtd(chip);
 
-	/* Request GPIO port. */
-	gpio = JZ_GPIO_MEM_CS0 + bank - 1;
-	sprintf(gpio_name, "NAND CS%d", bank);
-	ret = gpio_request(gpio, gpio_name);
-	if (ret) {
-		dev_warn(&pdev->dev,
-			"Failed to request %s gpio %d: %d\n",
-			gpio_name, gpio, ret);
-		goto notfound_gpio;
-	}
-
 	/* Request I/O resource. */
 	sprintf(res_name, "bank%d", bank);
 	ret = jz_nand_ioremap_resource(pdev, res_name,
 					&nand->bank_mem[bank - 1],
 					&nand->bank_base[bank - 1]);
 	if (ret)
-		goto notfound_resource;
+		return ret;
 
 	/* Enable chip in bank. */
-	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
 	ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
 	ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
 	writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
@@ -377,12 +362,8 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 	dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
 	ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
 	writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
-	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
 	jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
 				 nand->bank_base[bank - 1]);
-notfound_resource:
-	gpio_free(gpio);
-notfound_gpio:
 	return ret;
 }
 
@@ -503,7 +484,6 @@ static int jz_nand_probe(struct platform_device *pdev)
 err_unclaim_banks:
 	while (chipnr--) {
 		unsigned char bank = nand->banks[chipnr];
-		gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
 		jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
 					 nand->bank_base[bank - 1]);
 	}
@@ -530,7 +510,6 @@ static int jz_nand_remove(struct platform_device *pdev)
 		if (bank != 0) {
 			jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
 						 nand->bank_base[bank - 1]);
-			gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
 		}
 	}
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 11/13] fbdev: jz4740-fb: Let the pinctrl driver configure the pins
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

Now that the JZ4740 and similar SoCs have a pinctrl driver, we rely on
the pins being properly configured before the driver probes.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/video/fbdev/jz4740_fb.c | 104 ++--------------------------------------
 1 file changed, 3 insertions(+), 101 deletions(-)

diff --git a/drivers/video/fbdev/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c
index 87790e9644d0..b57df83fdbd3 100644
--- a/drivers/video/fbdev/jz4740_fb.c
+++ b/drivers/video/fbdev/jz4740_fb.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -27,7 +28,6 @@
 #include <linux/dma-mapping.h>
 
 #include <asm/mach-jz4740/jz4740_fb.h>
-#include <asm/mach-jz4740/gpio.h>
 
 #define JZ_REG_LCD_CFG		0x00
 #define JZ_REG_LCD_VSYNC	0x04
@@ -146,93 +146,6 @@ static const struct fb_fix_screeninfo jzfb_fix = {
 	.accel		= FB_ACCEL_NONE,
 };
 
-static const struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = {
-	JZ_GPIO_BULK_PIN(LCD_PCLK),
-	JZ_GPIO_BULK_PIN(LCD_HSYNC),
-	JZ_GPIO_BULK_PIN(LCD_VSYNC),
-	JZ_GPIO_BULK_PIN(LCD_DE),
-	JZ_GPIO_BULK_PIN(LCD_PS),
-	JZ_GPIO_BULK_PIN(LCD_REV),
-	JZ_GPIO_BULK_PIN(LCD_CLS),
-	JZ_GPIO_BULK_PIN(LCD_SPL),
-};
-
-static const struct jz_gpio_bulk_request jz_lcd_data_pins[] = {
-	JZ_GPIO_BULK_PIN(LCD_DATA0),
-	JZ_GPIO_BULK_PIN(LCD_DATA1),
-	JZ_GPIO_BULK_PIN(LCD_DATA2),
-	JZ_GPIO_BULK_PIN(LCD_DATA3),
-	JZ_GPIO_BULK_PIN(LCD_DATA4),
-	JZ_GPIO_BULK_PIN(LCD_DATA5),
-	JZ_GPIO_BULK_PIN(LCD_DATA6),
-	JZ_GPIO_BULK_PIN(LCD_DATA7),
-	JZ_GPIO_BULK_PIN(LCD_DATA8),
-	JZ_GPIO_BULK_PIN(LCD_DATA9),
-	JZ_GPIO_BULK_PIN(LCD_DATA10),
-	JZ_GPIO_BULK_PIN(LCD_DATA11),
-	JZ_GPIO_BULK_PIN(LCD_DATA12),
-	JZ_GPIO_BULK_PIN(LCD_DATA13),
-	JZ_GPIO_BULK_PIN(LCD_DATA14),
-	JZ_GPIO_BULK_PIN(LCD_DATA15),
-	JZ_GPIO_BULK_PIN(LCD_DATA16),
-	JZ_GPIO_BULK_PIN(LCD_DATA17),
-};
-
-static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
-{
-	unsigned int num;
-
-	switch (jzfb->pdata->lcd_type) {
-	case JZ_LCD_TYPE_GENERIC_16_BIT:
-		num = 4;
-		break;
-	case JZ_LCD_TYPE_GENERIC_18_BIT:
-		num = 4;
-		break;
-	case JZ_LCD_TYPE_8BIT_SERIAL:
-		num = 3;
-		break;
-	case JZ_LCD_TYPE_SPECIAL_TFT_1:
-	case JZ_LCD_TYPE_SPECIAL_TFT_2:
-	case JZ_LCD_TYPE_SPECIAL_TFT_3:
-		num = 8;
-		break;
-	default:
-		num = 0;
-		break;
-	}
-	return num;
-}
-
-static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
-{
-	unsigned int num;
-
-	switch (jzfb->pdata->lcd_type) {
-	case JZ_LCD_TYPE_GENERIC_16_BIT:
-		num = 16;
-		break;
-	case JZ_LCD_TYPE_GENERIC_18_BIT:
-		num = 18;
-		break;
-	case JZ_LCD_TYPE_8BIT_SERIAL:
-		num = 8;
-		break;
-	case JZ_LCD_TYPE_SPECIAL_TFT_1:
-	case JZ_LCD_TYPE_SPECIAL_TFT_2:
-	case JZ_LCD_TYPE_SPECIAL_TFT_3:
-		if (jzfb->pdata->bpp == 18)
-			num = 18;
-		else
-			num = 16;
-		break;
-	default:
-		num = 0;
-		break;
-	}
-	return num;
-}
-
 /* Based on CNVT_TOHW macro from skeletonfb.c */
 static inline uint32_t jzfb_convert_color_to_hw(unsigned val,
 	struct fb_bitfield *bf)
@@ -487,8 +400,7 @@ static void jzfb_enable(struct jzfb *jzfb)
 
 	clk_prepare_enable(jzfb->ldclk);
 
-	jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
-	jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+	pinctrl_pm_select_default_state(&jzfb->pdev->dev);
 
 	writel(0, jzfb->base + JZ_REG_LCD_STATE);
 
@@ -511,8 +423,7 @@ static void jzfb_disable(struct jzfb *jzfb)
 		ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
 	} while (!(ctrl & JZ_LCD_STATE_DISABLED));
 
-	jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
-	jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
+	pinctrl_pm_select_sleep_state(&jzfb->pdev->dev);
 
 	clk_disable_unprepare(jzfb->ldclk);
 }
@@ -701,9 +612,6 @@ static int jzfb_probe(struct platform_device *pdev)
 	fb->mode = NULL;
 	jzfb_set_par(fb);
 
-	jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
-	jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
-
 	ret = register_framebuffer(fb);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
@@ -715,9 +623,6 @@ static int jzfb_probe(struct platform_device *pdev)
 	return 0;
 
 err_free_devmem:
-	jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
-	jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
-
 	fb_dealloc_cmap(&fb->cmap);
 	jzfb_free_devmem(jzfb);
 err_framebuffer_release:
@@ -731,9 +636,6 @@ static int jzfb_remove(struct platform_device *pdev)
 
 	jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
 
-	jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
-	jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
-
 	fb_dealloc_cmap(&jzfb->fb->cmap);
 	jzfb_free_devmem(jzfb);
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 12/13] pwm: jz4740: Let the pinctrl driver configure the pins
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

Now that the JZ4740 and similar SoCs have a pinctrl driver, we rely on
the pins being properly configured before the driver probes.

One inherent problem of this new approach is that the pinctrl framework
does not allow us to configure each pin on demand, when the various PWM
channels are requested or released. For instance, the PWM channels can
be configured from sysfs, which would require all PWM pins to be configured
properly beforehand for the PWM function, eventually causing conflicts
with other platform or board drivers.

The proper solution here would be to modify the pwm-jz4740 driver to
handle only one PWM channel, and create an instance of this driver
for each one of the 8 PWM channels. Then, it could use the pinctrl
framework to dynamically configure the PWM pin it controls.

Until this can be done, the only jz4740 board supported upstream
(Qi lb60) could configure all of its connected PWM pins in PWM function
mode, if those are not used by other drivers nor by GPIOs on the
board.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/pwm/pwm-jz4740.c | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
index 76d13150283f..a75ff3622450 100644
--- a/drivers/pwm/pwm-jz4740.c
+++ b/drivers/pwm/pwm-jz4740.c
@@ -21,22 +21,10 @@
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 
-#include <asm/mach-jz4740/gpio.h>
 #include <asm/mach-jz4740/timer.h>
 
 #define NUM_PWM 8
 
-static const unsigned int jz4740_pwm_gpio_list[NUM_PWM] = {
-	JZ_GPIO_PWM0,
-	JZ_GPIO_PWM1,
-	JZ_GPIO_PWM2,
-	JZ_GPIO_PWM3,
-	JZ_GPIO_PWM4,
-	JZ_GPIO_PWM5,
-	JZ_GPIO_PWM6,
-	JZ_GPIO_PWM7,
-};
-
 struct jz4740_pwm_chip {
 	struct pwm_chip chip;
 	struct clk *clk;
@@ -49,9 +37,6 @@ static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
 
 static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-	unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
-	int ret;
-
 	/*
 	 * Timers 0 and 1 are used for system tasks, so they are unavailable
 	 * for use as PWMs.
@@ -59,15 +44,6 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 	if (pwm->hwpwm < 2)
 		return -EBUSY;
 
-	ret = gpio_request(gpio, pwm->label);
-	if (ret) {
-		dev_err(chip->dev, "Failed to request GPIO#%u for PWM: %d\n",
-			gpio, ret);
-		return ret;
-	}
-
-	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_PWM);
-
 	jz4740_timer_start(pwm->hwpwm);
 
 	return 0;
@@ -75,13 +51,8 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 
 static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-	unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
-
 	jz4740_timer_set_ctrl(pwm->hwpwm, 0);
 
-	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
-	gpio_free(gpio);
-
 	jz4740_timer_stop(pwm->hwpwm);
 }
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH 13/13] MIPS: jz4740: Remove custom GPIO code
From: Paul Cercueil @ 2017-01-17 23:14 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Mark Rutland, Ralf Baechle,
	Ulf Hansson, Boris Brezillon, Thierry Reding,
	Bartlomiej Zolnierkiewicz, Maarten ter Huurne, Lars-Peter Clausen,
	Paul Burton
  Cc: linux-gpio, devicetree, linux-kernel, linux-mips, linux-mmc,
	linux-mtd, linux-pwm, linux-fbdev, james.hogan, Paul Cercueil
In-Reply-To: <20170117231421.16310-1-paul@crapouillou.net>

All the drivers for the various hardware elements of the jz4740 SoC have
been modified to use the pinctrl framework for their pin configuration
needs.
As such, this platform code is now unused and can be deleted.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 arch/mips/include/asm/mach-jz4740/gpio.h | 371 ----------------------
 arch/mips/jz4740/Makefile                |   2 -
 arch/mips/jz4740/gpio.c                  | 519 -------------------------------
 3 files changed, 892 deletions(-)
 delete mode 100644 arch/mips/jz4740/gpio.c

diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h
index 7c7708a23baa..fd847c984701 100644
--- a/arch/mips/include/asm/mach-jz4740/gpio.h
+++ b/arch/mips/include/asm/mach-jz4740/gpio.h
@@ -16,380 +16,9 @@
 #ifndef _JZ_GPIO_H
 #define _JZ_GPIO_H
 
-#include <linux/types.h>
-
-enum jz_gpio_function {
-    JZ_GPIO_FUNC_NONE,
-    JZ_GPIO_FUNC1,
-    JZ_GPIO_FUNC2,
-    JZ_GPIO_FUNC3,
-};
-
-/*
- Usually a driver for a SoC component has to request several gpio pins and
- configure them as function pins.
- jz_gpio_bulk_request can be used to ease this process.
- Usually one would do something like:
-
- static const struct jz_gpio_bulk_request i2c_pins[] = {
-	JZ_GPIO_BULK_PIN(I2C_SDA),
-	JZ_GPIO_BULK_PIN(I2C_SCK),
- };
-
- inside the probe function:
-
-    ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
-    if (ret) {
-	...
-
- inside the remove function:
-
-    jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
-
-*/
-
-struct jz_gpio_bulk_request {
-	int gpio;
-	const char *name;
-	enum jz_gpio_function function;
-};
-
-#define JZ_GPIO_BULK_PIN(pin) { \
-    .gpio = JZ_GPIO_ ## pin, \
-    .name = #pin, \
-    .function = JZ_GPIO_FUNC_ ## pin \
-}
-
-int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
-void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
-void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
-void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
-void jz_gpio_enable_pullup(unsigned gpio);
-void jz_gpio_disable_pullup(unsigned gpio);
-int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
-
-int jz_gpio_port_direction_input(int port, uint32_t mask);
-int jz_gpio_port_direction_output(int port, uint32_t mask);
-void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
-uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
-
 #define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
 #define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
 #define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
 #define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
 
-/* Port A function pins */
-#define JZ_GPIO_MEM_DATA0		JZ_GPIO_PORTA(0)
-#define JZ_GPIO_MEM_DATA1		JZ_GPIO_PORTA(1)
-#define JZ_GPIO_MEM_DATA2		JZ_GPIO_PORTA(2)
-#define JZ_GPIO_MEM_DATA3		JZ_GPIO_PORTA(3)
-#define JZ_GPIO_MEM_DATA4		JZ_GPIO_PORTA(4)
-#define JZ_GPIO_MEM_DATA5		JZ_GPIO_PORTA(5)
-#define JZ_GPIO_MEM_DATA6		JZ_GPIO_PORTA(6)
-#define JZ_GPIO_MEM_DATA7		JZ_GPIO_PORTA(7)
-#define JZ_GPIO_MEM_DATA8		JZ_GPIO_PORTA(8)
-#define JZ_GPIO_MEM_DATA9		JZ_GPIO_PORTA(9)
-#define JZ_GPIO_MEM_DATA10		JZ_GPIO_PORTA(10)
-#define JZ_GPIO_MEM_DATA11		JZ_GPIO_PORTA(11)
-#define JZ_GPIO_MEM_DATA12		JZ_GPIO_PORTA(12)
-#define JZ_GPIO_MEM_DATA13		JZ_GPIO_PORTA(13)
-#define JZ_GPIO_MEM_DATA14		JZ_GPIO_PORTA(14)
-#define JZ_GPIO_MEM_DATA15		JZ_GPIO_PORTA(15)
-#define JZ_GPIO_MEM_DATA16		JZ_GPIO_PORTA(16)
-#define JZ_GPIO_MEM_DATA17		JZ_GPIO_PORTA(17)
-#define JZ_GPIO_MEM_DATA18		JZ_GPIO_PORTA(18)
-#define JZ_GPIO_MEM_DATA19		JZ_GPIO_PORTA(19)
-#define JZ_GPIO_MEM_DATA20		JZ_GPIO_PORTA(20)
-#define JZ_GPIO_MEM_DATA21		JZ_GPIO_PORTA(21)
-#define JZ_GPIO_MEM_DATA22		JZ_GPIO_PORTA(22)
-#define JZ_GPIO_MEM_DATA23		JZ_GPIO_PORTA(23)
-#define JZ_GPIO_MEM_DATA24		JZ_GPIO_PORTA(24)
-#define JZ_GPIO_MEM_DATA25		JZ_GPIO_PORTA(25)
-#define JZ_GPIO_MEM_DATA26		JZ_GPIO_PORTA(26)
-#define JZ_GPIO_MEM_DATA27		JZ_GPIO_PORTA(27)
-#define JZ_GPIO_MEM_DATA28		JZ_GPIO_PORTA(28)
-#define JZ_GPIO_MEM_DATA29		JZ_GPIO_PORTA(29)
-#define JZ_GPIO_MEM_DATA30		JZ_GPIO_PORTA(30)
-#define JZ_GPIO_MEM_DATA31		JZ_GPIO_PORTA(31)
-
-#define JZ_GPIO_FUNC_MEM_DATA0		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA1		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA2		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA3		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA4		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA5		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA6		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA7		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA8		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA9		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA10		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA11		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA12		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA13		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA14		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA15		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA16		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA17		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA18		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA19		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA20		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA21		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA22		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA23		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA24		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA25		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA26		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA27		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA28		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA29		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA30		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DATA31		JZ_GPIO_FUNC1
-
-/* Port B function pins */
-#define JZ_GPIO_MEM_ADDR0		JZ_GPIO_PORTB(0)
-#define JZ_GPIO_MEM_ADDR1		JZ_GPIO_PORTB(1)
-#define JZ_GPIO_MEM_ADDR2		JZ_GPIO_PORTB(2)
-#define JZ_GPIO_MEM_ADDR3		JZ_GPIO_PORTB(3)
-#define JZ_GPIO_MEM_ADDR4		JZ_GPIO_PORTB(4)
-#define JZ_GPIO_MEM_ADDR5		JZ_GPIO_PORTB(5)
-#define JZ_GPIO_MEM_ADDR6		JZ_GPIO_PORTB(6)
-#define JZ_GPIO_MEM_ADDR7		JZ_GPIO_PORTB(7)
-#define JZ_GPIO_MEM_ADDR8		JZ_GPIO_PORTB(8)
-#define JZ_GPIO_MEM_ADDR9		JZ_GPIO_PORTB(9)
-#define JZ_GPIO_MEM_ADDR10		JZ_GPIO_PORTB(10)
-#define JZ_GPIO_MEM_ADDR11		JZ_GPIO_PORTB(11)
-#define JZ_GPIO_MEM_ADDR12		JZ_GPIO_PORTB(12)
-#define JZ_GPIO_MEM_ADDR13		JZ_GPIO_PORTB(13)
-#define JZ_GPIO_MEM_ADDR14		JZ_GPIO_PORTB(14)
-#define JZ_GPIO_MEM_ADDR15		JZ_GPIO_PORTB(15)
-#define JZ_GPIO_MEM_ADDR16		JZ_GPIO_PORTB(16)
-#define JZ_GPIO_LCD_CLS			JZ_GPIO_PORTB(17)
-#define JZ_GPIO_LCD_SPL			JZ_GPIO_PORTB(18)
-#define JZ_GPIO_MEM_DCS			JZ_GPIO_PORTB(19)
-#define JZ_GPIO_MEM_RAS			JZ_GPIO_PORTB(20)
-#define JZ_GPIO_MEM_CAS			JZ_GPIO_PORTB(21)
-#define JZ_GPIO_MEM_SDWE		JZ_GPIO_PORTB(22)
-#define JZ_GPIO_MEM_CKE			JZ_GPIO_PORTB(23)
-#define JZ_GPIO_MEM_CKO			JZ_GPIO_PORTB(24)
-#define JZ_GPIO_MEM_CS0			JZ_GPIO_PORTB(25)
-#define JZ_GPIO_MEM_CS1			JZ_GPIO_PORTB(26)
-#define JZ_GPIO_MEM_CS2			JZ_GPIO_PORTB(27)
-#define JZ_GPIO_MEM_CS3			JZ_GPIO_PORTB(28)
-#define JZ_GPIO_MEM_RD			JZ_GPIO_PORTB(29)
-#define JZ_GPIO_MEM_WR			JZ_GPIO_PORTB(30)
-#define JZ_GPIO_MEM_WE0			JZ_GPIO_PORTB(31)
-
-#define JZ_GPIO_FUNC_MEM_ADDR0		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR1		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR2		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR3		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR4		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR5		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR6		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR7		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR8		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR9		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR10		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR11		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR12		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR13		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR14		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR15		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_ADDR16		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_CLS		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_SPL		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_DCS		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_RAS		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CAS		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_SDWE		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CKE		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CKO		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CS0		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CS1		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CS2		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_CS3		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_RD		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WR		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WE0		JZ_GPIO_FUNC1
-
-
-#define JZ_GPIO_MEM_ADDR21		JZ_GPIO_PORTB(17)
-#define JZ_GPIO_MEM_ADDR22		JZ_GPIO_PORTB(18)
-
-#define JZ_GPIO_FUNC_MEM_ADDR21		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_ADDR22		JZ_GPIO_FUNC2
-
-/* Port C function pins */
-#define JZ_GPIO_LCD_DATA0		JZ_GPIO_PORTC(0)
-#define JZ_GPIO_LCD_DATA1		JZ_GPIO_PORTC(1)
-#define JZ_GPIO_LCD_DATA2		JZ_GPIO_PORTC(2)
-#define JZ_GPIO_LCD_DATA3		JZ_GPIO_PORTC(3)
-#define JZ_GPIO_LCD_DATA4		JZ_GPIO_PORTC(4)
-#define JZ_GPIO_LCD_DATA5		JZ_GPIO_PORTC(5)
-#define JZ_GPIO_LCD_DATA6		JZ_GPIO_PORTC(6)
-#define JZ_GPIO_LCD_DATA7		JZ_GPIO_PORTC(7)
-#define JZ_GPIO_LCD_DATA8		JZ_GPIO_PORTC(8)
-#define JZ_GPIO_LCD_DATA9		JZ_GPIO_PORTC(9)
-#define JZ_GPIO_LCD_DATA10		JZ_GPIO_PORTC(10)
-#define JZ_GPIO_LCD_DATA11		JZ_GPIO_PORTC(11)
-#define JZ_GPIO_LCD_DATA12		JZ_GPIO_PORTC(12)
-#define JZ_GPIO_LCD_DATA13		JZ_GPIO_PORTC(13)
-#define JZ_GPIO_LCD_DATA14		JZ_GPIO_PORTC(14)
-#define JZ_GPIO_LCD_DATA15		JZ_GPIO_PORTC(15)
-#define JZ_GPIO_LCD_DATA16		JZ_GPIO_PORTC(16)
-#define JZ_GPIO_LCD_DATA17		JZ_GPIO_PORTC(17)
-#define JZ_GPIO_LCD_PCLK		JZ_GPIO_PORTC(18)
-#define JZ_GPIO_LCD_HSYNC		JZ_GPIO_PORTC(19)
-#define JZ_GPIO_LCD_VSYNC		JZ_GPIO_PORTC(20)
-#define JZ_GPIO_LCD_DE			JZ_GPIO_PORTC(21)
-#define JZ_GPIO_LCD_PS			JZ_GPIO_PORTC(22)
-#define JZ_GPIO_LCD_REV			JZ_GPIO_PORTC(23)
-#define JZ_GPIO_MEM_WE1			JZ_GPIO_PORTC(24)
-#define JZ_GPIO_MEM_WE2			JZ_GPIO_PORTC(25)
-#define JZ_GPIO_MEM_WE3			JZ_GPIO_PORTC(26)
-#define JZ_GPIO_MEM_WAIT		JZ_GPIO_PORTC(27)
-#define JZ_GPIO_MEM_FRE			JZ_GPIO_PORTC(28)
-#define JZ_GPIO_MEM_FWE			JZ_GPIO_PORTC(29)
-
-#define JZ_GPIO_FUNC_LCD_DATA0		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA1		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA2		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA3		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA4		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA5		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA6		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA7		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA8		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA9		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA10		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA11		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA12		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA13		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA14		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA15		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA16		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DATA17		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_PCLK		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_VSYNC		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_HSYNC		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_DE		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_PS		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_LCD_REV		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WE1		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WE2		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WE3		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_WAIT		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_FRE		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MEM_FWE		JZ_GPIO_FUNC1
-
-
-#define JZ_GPIO_MEM_ADDR19		JZ_GPIO_PORTB(22)
-#define JZ_GPIO_MEM_ADDR20		JZ_GPIO_PORTB(23)
-
-#define JZ_GPIO_FUNC_MEM_ADDR19		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_ADDR20		JZ_GPIO_FUNC2
-
-/* Port D function pins */
-#define JZ_GPIO_CIM_DATA0		JZ_GPIO_PORTD(0)
-#define JZ_GPIO_CIM_DATA1		JZ_GPIO_PORTD(1)
-#define JZ_GPIO_CIM_DATA2		JZ_GPIO_PORTD(2)
-#define JZ_GPIO_CIM_DATA3		JZ_GPIO_PORTD(3)
-#define JZ_GPIO_CIM_DATA4		JZ_GPIO_PORTD(4)
-#define JZ_GPIO_CIM_DATA5		JZ_GPIO_PORTD(5)
-#define JZ_GPIO_CIM_DATA6		JZ_GPIO_PORTD(6)
-#define JZ_GPIO_CIM_DATA7		JZ_GPIO_PORTD(7)
-#define JZ_GPIO_MSC_CMD			JZ_GPIO_PORTD(8)
-#define JZ_GPIO_MSC_CLK			JZ_GPIO_PORTD(9)
-#define JZ_GPIO_MSC_DATA0		JZ_GPIO_PORTD(10)
-#define JZ_GPIO_MSC_DATA1		JZ_GPIO_PORTD(11)
-#define JZ_GPIO_MSC_DATA2		JZ_GPIO_PORTD(12)
-#define JZ_GPIO_MSC_DATA3		JZ_GPIO_PORTD(13)
-#define JZ_GPIO_CIM_MCLK		JZ_GPIO_PORTD(14)
-#define JZ_GPIO_CIM_PCLK		JZ_GPIO_PORTD(15)
-#define JZ_GPIO_CIM_VSYNC		JZ_GPIO_PORTD(16)
-#define JZ_GPIO_CIM_HSYNC		JZ_GPIO_PORTD(17)
-#define JZ_GPIO_SPI_CLK			JZ_GPIO_PORTD(18)
-#define JZ_GPIO_SPI_CE0			JZ_GPIO_PORTD(19)
-#define JZ_GPIO_SPI_DT			JZ_GPIO_PORTD(20)
-#define JZ_GPIO_SPI_DR			JZ_GPIO_PORTD(21)
-#define JZ_GPIO_SPI_CE1			JZ_GPIO_PORTD(22)
-#define JZ_GPIO_PWM0			JZ_GPIO_PORTD(23)
-#define JZ_GPIO_PWM1			JZ_GPIO_PORTD(24)
-#define JZ_GPIO_PWM2			JZ_GPIO_PORTD(25)
-#define JZ_GPIO_PWM3			JZ_GPIO_PORTD(26)
-#define JZ_GPIO_PWM4			JZ_GPIO_PORTD(27)
-#define JZ_GPIO_PWM5			JZ_GPIO_PORTD(28)
-#define JZ_GPIO_PWM6			JZ_GPIO_PORTD(30)
-#define JZ_GPIO_PWM7			JZ_GPIO_PORTD(31)
-
-#define JZ_GPIO_FUNC_CIM_DATA		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_CIM_DATA0		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA1		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA2		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA3		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA4		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA5		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA6		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_CIM_DATA7		JZ_GPIO_FUNC_CIM_DATA
-#define JZ_GPIO_FUNC_MSC_CMD		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MSC_CLK		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MSC_DATA		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_MSC_DATA0		JZ_GPIO_FUNC_MSC_DATA
-#define JZ_GPIO_FUNC_MSC_DATA1		JZ_GPIO_FUNC_MSC_DATA
-#define JZ_GPIO_FUNC_MSC_DATA2		JZ_GPIO_FUNC_MSC_DATA
-#define JZ_GPIO_FUNC_MSC_DATA3		JZ_GPIO_FUNC_MSC_DATA
-#define JZ_GPIO_FUNC_CIM_MCLK		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_CIM_PCLK		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_CIM_VSYNC		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_CIM_HSYNC		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_SPI_CLK		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_SPI_CE0		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_SPI_DT		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_SPI_DR		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_SPI_CE1		JZ_GPIO_FUNC1
-
-#define JZ_GPIO_FUNC_PWM		JZ_GPIO_FUNC1
-#define JZ_GPIO_FUNC_PWM0		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM1		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM2		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM3		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM4		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM5		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM6		JZ_GPIO_FUNC_PWM
-#define JZ_GPIO_FUNC_PWM7		JZ_GPIO_FUNC_PWM
-
-#define JZ_GPIO_MEM_SCLK_RSTN		JZ_GPIO_PORTD(18)
-#define JZ_GPIO_MEM_BCLK		JZ_GPIO_PORTD(19)
-#define JZ_GPIO_MEM_SDATO		JZ_GPIO_PORTD(20)
-#define JZ_GPIO_MEM_SDATI		JZ_GPIO_PORTD(21)
-#define JZ_GPIO_MEM_SYNC		JZ_GPIO_PORTD(22)
-#define JZ_GPIO_I2C_SDA			JZ_GPIO_PORTD(23)
-#define JZ_GPIO_I2C_SCK			JZ_GPIO_PORTD(24)
-#define JZ_GPIO_UART0_TXD		JZ_GPIO_PORTD(25)
-#define JZ_GPIO_UART0_RXD		JZ_GPIO_PORTD(26)
-#define JZ_GPIO_MEM_ADDR17		JZ_GPIO_PORTD(27)
-#define JZ_GPIO_MEM_ADDR18		JZ_GPIO_PORTD(28)
-#define JZ_GPIO_UART0_CTS		JZ_GPIO_PORTD(30)
-#define JZ_GPIO_UART0_RTS		JZ_GPIO_PORTD(31)
-
-#define JZ_GPIO_FUNC_MEM_SCLK_RSTN	JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_BCLK		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_SDATO		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_SDATI		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_SYNC		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_I2C_SDA		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_I2C_SCK		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_UART0_TXD		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_UART0_RXD		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_ADDR17		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_MEM_ADDR18		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_UART0_CTS		JZ_GPIO_FUNC2
-#define JZ_GPIO_FUNC_UART0_RTS		JZ_GPIO_FUNC2
-
-#define JZ_GPIO_UART1_RXD		JZ_GPIO_PORTD(30)
-#define JZ_GPIO_UART1_TXD		JZ_GPIO_PORTD(31)
-
-#define JZ_GPIO_FUNC_UART1_RXD		JZ_GPIO_FUNC3
-#define JZ_GPIO_FUNC_UART1_TXD		JZ_GPIO_FUNC3
-
 #endif
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 39d70bde8cfe..6b9c1f7c31c9 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,8 +7,6 @@
 obj-y += prom.o time.o reset.o setup.o \
 	platform.o timer.o
 
-obj-$(CONFIG_MACH_JZ4740) += gpio.o
-
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
 # board specific support
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
deleted file mode 100644
index b765773ab8aa..000000000000
--- a/arch/mips/jz4740/gpio.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 platform GPIO support
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/io.h>
-#include <linux/gpio/driver.h>
-/* FIXME: needed for gpio_request(), try to remove consumer API from driver */
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/irqchip/ingenic.h>
-#include <linux/bitops.h>
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#include <asm/mach-jz4740/base.h>
-#include <asm/mach-jz4740/gpio.h>
-
-#define JZ4740_GPIO_BASE_A (32*0)
-#define JZ4740_GPIO_BASE_B (32*1)
-#define JZ4740_GPIO_BASE_C (32*2)
-#define JZ4740_GPIO_BASE_D (32*3)
-
-#define JZ4740_GPIO_NUM_A 32
-#define JZ4740_GPIO_NUM_B 32
-#define JZ4740_GPIO_NUM_C 31
-#define JZ4740_GPIO_NUM_D 32
-
-#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
-#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
-#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
-#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
-
-#define JZ_REG_GPIO_PIN			0x00
-#define JZ_REG_GPIO_DATA		0x10
-#define JZ_REG_GPIO_DATA_SET		0x14
-#define JZ_REG_GPIO_DATA_CLEAR		0x18
-#define JZ_REG_GPIO_MASK		0x20
-#define JZ_REG_GPIO_MASK_SET		0x24
-#define JZ_REG_GPIO_MASK_CLEAR		0x28
-#define JZ_REG_GPIO_PULL		0x30
-#define JZ_REG_GPIO_PULL_SET		0x34
-#define JZ_REG_GPIO_PULL_CLEAR		0x38
-#define JZ_REG_GPIO_FUNC		0x40
-#define JZ_REG_GPIO_FUNC_SET		0x44
-#define JZ_REG_GPIO_FUNC_CLEAR		0x48
-#define JZ_REG_GPIO_SELECT		0x50
-#define JZ_REG_GPIO_SELECT_SET		0x54
-#define JZ_REG_GPIO_SELECT_CLEAR	0x58
-#define JZ_REG_GPIO_DIRECTION		0x60
-#define JZ_REG_GPIO_DIRECTION_SET	0x64
-#define JZ_REG_GPIO_DIRECTION_CLEAR	0x68
-#define JZ_REG_GPIO_TRIGGER		0x70
-#define JZ_REG_GPIO_TRIGGER_SET		0x74
-#define JZ_REG_GPIO_TRIGGER_CLEAR	0x78
-#define JZ_REG_GPIO_FLAG		0x80
-#define JZ_REG_GPIO_FLAG_CLEAR		0x14
-
-#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
-#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
-#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
-
-struct jz_gpio_chip {
-	unsigned int irq;
-	unsigned int irq_base;
-	uint32_t edge_trigger_both;
-
-	void __iomem *base;
-
-	struct gpio_chip gpio_chip;
-};
-
-static struct jz_gpio_chip jz4740_gpio_chips[];
-
-static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
-{
-	return &jz4740_gpio_chips[gpio >> 5];
-}
-
-static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gc)
-{
-	return gpiochip_get_data(gc);
-}
-
-static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
-{
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
-	return gc->private;
-}
-
-static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
-{
-	writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
-}
-
-int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
-{
-	if (function == JZ_GPIO_FUNC_NONE) {
-		jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
-		jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
-		jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
-	} else {
-		jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
-		jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
-		switch (function) {
-		case JZ_GPIO_FUNC1:
-			jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
-			break;
-		case JZ_GPIO_FUNC3:
-			jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
-		case JZ_GPIO_FUNC2: /* Falltrough */
-			jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
-			break;
-		default:
-			BUG();
-			break;
-		}
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(jz_gpio_set_function);
-
-int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
-{
-	size_t i;
-	int ret;
-
-	for (i = 0; i < num; ++i, ++request) {
-		ret = gpio_request(request->gpio, request->name);
-		if (ret)
-			goto err;
-		jz_gpio_set_function(request->gpio, request->function);
-	}
-
-	return 0;
-
-err:
-	for (--request; i > 0; --i, --request) {
-		gpio_free(request->gpio);
-		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
-
-void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
-{
-	size_t i;
-
-	for (i = 0; i < num; ++i, ++request) {
-		gpio_free(request->gpio);
-		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
-	}
-
-}
-EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
-
-void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
-{
-	size_t i;
-
-	for (i = 0; i < num; ++i, ++request) {
-		jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
-		jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
-		jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
-	}
-}
-EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
-
-void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
-{
-	size_t i;
-
-	for (i = 0; i < num; ++i, ++request)
-		jz_gpio_set_function(request->gpio, request->function);
-}
-EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
-
-void jz_gpio_enable_pullup(unsigned gpio)
-{
-	jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
-}
-EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
-
-void jz_gpio_disable_pullup(unsigned gpio)
-{
-	jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
-}
-EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
-
-static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
-{
-	return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
-}
-
-static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
-{
-	uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
-	reg += !value;
-	writel(BIT(gpio), reg);
-}
-
-static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
-	int value)
-{
-	writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
-	jz_gpio_set_value(chip, gpio, value);
-
-	return 0;
-}
-
-static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-{
-	writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
-
-	return 0;
-}
-
-static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
-{
-	struct jz_gpio_chip *jz_gpio = gpiochip_get_data(chip);
-
-	return jz_gpio->irq_base + gpio;
-}
-
-int jz_gpio_port_direction_input(int port, uint32_t mask)
-{
-	writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
-
-	return 0;
-}
-EXPORT_SYMBOL(jz_gpio_port_direction_input);
-
-int jz_gpio_port_direction_output(int port, uint32_t mask)
-{
-	writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
-
-	return 0;
-}
-EXPORT_SYMBOL(jz_gpio_port_direction_output);
-
-void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
-{
-	writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
-	writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
-}
-EXPORT_SYMBOL(jz_gpio_port_set_value);
-
-uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
-{
-	uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
-
-	return value & mask;
-}
-EXPORT_SYMBOL(jz_gpio_port_get_value);
-
-#define IRQ_TO_BIT(irq) BIT((irq - JZ4740_IRQ_GPIO(0)) & 0x1f)
-
-static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
-{
-	uint32_t value;
-	void __iomem *reg;
-	uint32_t mask = IRQ_TO_BIT(irq);
-
-	if (!(chip->edge_trigger_both & mask))
-		return;
-
-	reg = chip->base;
-
-	value = readl(chip->base + JZ_REG_GPIO_PIN);
-	if (value & mask)
-		reg += JZ_REG_GPIO_DIRECTION_CLEAR;
-	else
-		reg += JZ_REG_GPIO_DIRECTION_SET;
-
-	writel(mask, reg);
-}
-
-static void jz_gpio_irq_demux_handler(struct irq_desc *desc)
-{
-	uint32_t flag;
-	unsigned int gpio_irq;
-	struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
-
-	flag = readl(chip->base + JZ_REG_GPIO_FLAG);
-	if (!flag)
-		return;
-
-	gpio_irq = chip->irq_base + __fls(flag);
-
-	jz_gpio_check_trigger_both(chip, gpio_irq);
-
-	generic_handle_irq(gpio_irq);
-};
-
-static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
-{
-	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
-	writel(IRQ_TO_BIT(data->irq), chip->base + reg);
-}
-
-static void jz_gpio_irq_unmask(struct irq_data *data)
-{
-	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
-
-	jz_gpio_check_trigger_both(chip, data->irq);
-	irq_gc_unmask_enable_reg(data);
-};
-
-/* TODO: Check if function is gpio */
-static unsigned int jz_gpio_irq_startup(struct irq_data *data)
-{
-	jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
-	jz_gpio_irq_unmask(data);
-	return 0;
-}
-
-static void jz_gpio_irq_shutdown(struct irq_data *data)
-{
-	irq_gc_mask_disable_reg(data);
-
-	/* Set direction to input */
-	jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
-	jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
-}
-
-static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
-{
-	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
-	unsigned int irq = data->irq;
-
-	if (flow_type == IRQ_TYPE_EDGE_BOTH) {
-		uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
-		if (value & IRQ_TO_BIT(irq))
-			flow_type = IRQ_TYPE_EDGE_FALLING;
-		else
-			flow_type = IRQ_TYPE_EDGE_RISING;
-		chip->edge_trigger_both |= IRQ_TO_BIT(irq);
-	} else {
-		chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
-	}
-
-	switch (flow_type) {
-	case IRQ_TYPE_EDGE_RISING:
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
-		jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
-{
-	struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
-
-	irq_gc_set_wake(data, on);
-	irq_set_irq_wake(chip->irq, on);
-
-	return 0;
-}
-
-#define JZ4740_GPIO_CHIP(_bank) { \
-	.irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
-	.gpio_chip = { \
-		.label = "Bank " # _bank, \
-		.owner = THIS_MODULE, \
-		.set = jz_gpio_set_value, \
-		.get = jz_gpio_get_value, \
-		.direction_output = jz_gpio_direction_output, \
-		.direction_input = jz_gpio_direction_input, \
-		.to_irq = jz_gpio_to_irq, \
-		.base = JZ4740_GPIO_BASE_ ## _bank, \
-		.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
-	}, \
-}
-
-static struct jz_gpio_chip jz4740_gpio_chips[] = {
-	JZ4740_GPIO_CHIP(A),
-	JZ4740_GPIO_CHIP(B),
-	JZ4740_GPIO_CHIP(C),
-	JZ4740_GPIO_CHIP(D),
-};
-
-static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
-{
-	struct irq_chip_generic *gc;
-	struct irq_chip_type *ct;
-
-	chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
-
-	chip->irq = JZ4740_IRQ_INTC_GPIO(id);
-	irq_set_chained_handler_and_data(chip->irq,
-					 jz_gpio_irq_demux_handler, chip);
-
-	gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
-		chip->base, handle_level_irq);
-
-	gc->wake_enabled = IRQ_MSK(chip->gpio_chip.ngpio);
-	gc->private = chip;
-
-	ct = gc->chip_types;
-	ct->regs.enable = JZ_REG_GPIO_MASK_CLEAR;
-	ct->regs.disable = JZ_REG_GPIO_MASK_SET;
-	ct->regs.ack = JZ_REG_GPIO_FLAG_CLEAR;
-
-	ct->chip.name = "GPIO";
-	ct->chip.irq_mask = irq_gc_mask_disable_reg;
-	ct->chip.irq_unmask = jz_gpio_irq_unmask;
-	ct->chip.irq_ack = irq_gc_ack_set_bit;
-	ct->chip.irq_suspend = ingenic_intc_irq_suspend;
-	ct->chip.irq_resume = ingenic_intc_irq_resume;
-	ct->chip.irq_startup = jz_gpio_irq_startup;
-	ct->chip.irq_shutdown = jz_gpio_irq_shutdown;
-	ct->chip.irq_set_type = jz_gpio_irq_set_type;
-	ct->chip.irq_set_wake = jz_gpio_irq_set_wake;
-	ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
-
-	irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
-		IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
-
-	gpiochip_add_data(&chip->gpio_chip, chip);
-}
-
-static int __init jz4740_gpio_init(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
-		jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
-
-	printk(KERN_INFO "JZ4740 GPIO initialized\n");
-
-	return 0;
-}
-arch_initcall(jz4740_gpio_init);
-
-#ifdef CONFIG_DEBUG_FS
-
-static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
-	const char *name, unsigned int reg)
-{
-	seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
-}
-
-static int gpio_regs_show(struct seq_file *s, void *unused)
-{
-	struct jz_gpio_chip *chip = jz4740_gpio_chips;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
-		seq_printf(s, "==GPIO %d==\n", i);
-		gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
-		gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
-		gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
-		gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
-		gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
-		gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
-		gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
-		gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
-		gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
-	}
-
-	return 0;
-}
-
-static int gpio_regs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, gpio_regs_show, NULL);
-}
-
-static const struct file_operations gpio_regs_operations = {
-	.open		= gpio_regs_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static int __init gpio_debugfs_init(void)
-{
-	(void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
-				NULL, NULL, &gpio_regs_operations);
-	return 0;
-}
-subsys_initcall(gpio_debugfs_init);
-
-#endif
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH 1/5] ARM: OMAP2+: omap_hwmod: Add support for earlycon
From: Tony Lindgren @ 2017-01-17 23:23 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Linux OMAP Mailing List, Device Tree Mailing List, Rob Herring,
	Tero Kristo, Sekhar Nori, Vignesh R, Nishanth Menon
In-Reply-To: <20170117040336.21700-2-lokeshvutla-l0cyMroinI0@public.gmane.org>

* Lokesh Vutla <lokeshvutla-l0cyMroinI0@public.gmane.org> [170116 20:06]:
> Hwmod core tries to reset and idles each IP that is registered with hwmod.
> In case of earlycon, that specific uart IP cannot be reset or keep it in
> idle state else earlycon hangs once hwmod resets that uart IP. So add support
> to not reset uart that is being used as earlycon only if CONFIG_SERIAL_EARLYCON
> is enabled.

Nice :)

I guess this has no dependency to SERIAL_OMAP vs 8250_OMAP selection?

Regards,

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

^ permalink raw reply

* Re: [PATCH V2 1/4] clk: gcc: Updates for SDHCI enablement
From: Stephen Boyd @ 2017-01-17 23:25 UTC (permalink / raw)
  To: Jeremy McNicoll
  Cc: linux-arm-msm, linux-soc, devicetree, linux-mmc, andy.gross, robh,
	arnd, bjorn.andersson, riteshh, git, ulf.hansson, jszhang
In-Reply-To: <1484614729-26751-2-git-send-email-jeremymc@redhat.com>

On 01/16, Jeremy McNicoll wrote:
> Global clock updates to enable onboard SDHCI / MMC.
> Re-tabify dt-bindings to align correctly in vim.

We need much more words here on what's going on in this patch.

> 
> Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
> ---
>  drivers/clk/qcom/gcc-msm8994.c               | 108 +++++++++++++++++++++------
>  include/dt-bindings/clock/qcom,gcc-msm8994.h |  32 ++++----
>  2 files changed, 106 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
> index 8afd830..2bf8d1b 100644
> --- a/drivers/clk/qcom/gcc-msm8994.c
> +++ b/drivers/clk/qcom/gcc-msm8994.c
> @@ -24,6 +24,7 @@
>  
>  #include "common.h"
>  #include "clk-regmap.h"
> +#include "clk-pll.h"

Why?

>  #include "clk-alpha-pll.h"
>  #include "clk-rcg.h"
>  #include "clk-branch.h"
> @@ -54,7 +55,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
>  static const char * const gcc_xo_gpll0_gpll4[] = {
>  	"xo",
>  	"gpll0",
> -	"gpll4",
> +	"gpll4_vote",
>  };
>  
>  #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
> @@ -97,29 +98,65 @@ static struct clk_alpha_pll_postdiv gpll0 = {
>  	},
>  };
>  
> -static struct clk_alpha_pll gpll4_early = {
> -	.offset = 0x1dc0,
> -	.clkr = {
> -		.enable_reg = 0x1480,
> -		.enable_mask = BIT(4),

This is doing PLL voting.

> -		.hw.init = &(struct clk_init_data)
> -		{
> -			.name = "gpll4_early",
> -			.parent_names = (const char *[]) { "xo" },
> -			.num_parents = 1,
> -			.ops = &clk_alpha_pll_ops,
> -		},
> +
> +static struct clk_rcg2 config_noc_clk_src = {
> +	.cmd_rcgr = 0x0150,
> +	.hid_width = 5,
> +	.parent_map = gcc_xo_gpll0_map,
> +	.clkr.hw.init = &(struct clk_init_data) {
> +		.name = "config_noc_clk_src",
> +		.parent_names = gcc_xo_gpll0,
> +		.num_parents = 2,
> +		.ops = &clk_rcg2_ops,
> +	},
> +};
> +
> +static struct clk_rcg2 periph_noc_clk_src = {
> +	.cmd_rcgr = 0x0190,
> +	.hid_width = 5,
> +	.mnd_width = 8,
> +	.parent_map = gcc_xo_gpll0_map,
> +	.clkr.hw.init = &(struct clk_init_data) {
> +		.name = "periph_noc_clk_src",
> +		.parent_names = gcc_xo_gpll0,
> +		.num_parents = 2,
> +		.ops = &clk_rcg2_ops,
> +	},
> +};
> +
> +static struct clk_rcg2 system_noc_clk_src = {
> +	.cmd_rcgr = 0x0120, //TODO

This is right.

> +	.hid_width = 5,
> +	.parent_map = gcc_xo_gpll0_map,
> +	.clkr.hw.init = &(struct clk_init_data) {
> +		.name = "system_noc_clk_src",
> +		.parent_names = gcc_xo_gpll0,
> +		.num_parents = 2,
> +		.ops = &clk_rcg2_ops,
>  	},
>  };
>  
> -static struct clk_alpha_pll_postdiv gpll4 = {
> -	.offset = 0x1dc0,
> +static struct clk_pll gpll4 = {

gpll4 is an alpha PLL though.

> +	.status_reg = 0x1dc0,
> +	.status_bit = 30,
>  	.clkr.hw.init = &(struct clk_init_data)
>  	{
>  		.name = "gpll4",
> -		.parent_names = (const char *[]) { "gpll4_early" },
> +		.parent_names = (const char *[]) { "xo" },
>  		.num_parents = 1,
> -		.ops = &clk_alpha_pll_postdiv_ops,
> +		.ops = &clk_pll_ops,
> +	},
> +};
> +
> +static struct clk_regmap gpll4_vote = {
> +	.enable_reg = 0x1480,
> +	.enable_mask = BIT(4),
> +	.hw.init = &(struct clk_init_data)

This part is rather confusing.

> +	{
> +		.name = "gpll4_vote",
> +		.parent_names = (const char *[]) { "gpll4" },
> +		.num_parents = 1,
> +		.ops = &clk_pll_vote_ops,
>  	},
>  };
>  
> @@ -896,8 +933,8 @@ static struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
>  	F(25000000, P_GPLL0, 12, 1, 2),
>  	F(50000000, P_GPLL0, 12, 0, 0),
>  	F(100000000, P_GPLL0, 6, 0, 0),
> -	F(192000000, P_GPLL4, 2, 0, 0),
> -	F(384000000, P_GPLL4, 1, 0, 0),
> +	F(172000000, P_GPLL4, 2, 0, 0),
> +	F(344000000, P_GPLL4, 1, 0, 0),

It seems that gpll4 runs at slightly different speeds on 8994 and
8992. You'll need to differentiate which SoC it is and update the
frequency table appropriately. That can be done with the gcc
node's compatible string. That also means gcc-msm8992 needs to be
added and used as a compatible string.

>  	{ }
>  };
>  
> @@ -1057,6 +1094,10 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
>  		.hw.init = &(struct clk_init_data)
>  		{
>  			.name = "gcc_blsp1_ahb_clk",
> +			.parent_names = (const char *[]){
> +				"periph_noc_clk_src",
> +			},
> +			.num_parents = 1,
>  			.ops = &clk_branch2_ops,
>  		},
>  	},
> @@ -1872,6 +1913,7 @@ static struct clk_branch gcc_pdm2_clk = {
>  
>  static struct clk_branch gcc_sdcc1_apps_clk = {
>  	.halt_reg = 0x04c4,
> +	.halt_check = BRANCH_HALT_VOTED,
>  	.clkr = {
>  		.enable_reg = 0x04c4,
>  		.enable_mask = BIT(0),
> @@ -1888,6 +1930,26 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
>  	},
>  };
>  
> +
> +static struct clk_branch gcc_sdcc1_ahb_clk = {
> +	.halt_reg = 0x04c8,
> +	.halt_check = BRANCH_HALT_VOTED,

Why voted?

> diff --git a/include/dt-bindings/clock/qcom,gcc-msm8994.h b/include/dt-bindings/clock/qcom,gcc-msm8994.h
> index 8fa535b..e4063d5 100644
> --- a/include/dt-bindings/clock/qcom,gcc-msm8994.h
> +++ b/include/dt-bindings/clock/qcom,gcc-msm8994.h
> @@ -15,10 +15,10 @@
>  #ifndef _DT_BINDINGS_CLK_MSM_GCC_8994_H
>  #define _DT_BINDINGS_CLK_MSM_GCC_8994_H
>  
> -#define GPLL0_EARLY				0
>  #define GPLL0					1
> -#define GPLL4_EARLY				2
> -#define GPLL4					3
> +#define GPLL0_VOTE				0

Please keep the numbers ordered.

> +#define GPLL4					2
> +#define GPLL4_VOTE				3
>  #define UFS_AXI_CLK_SRC				4
>  #define USB30_MASTER_CLK_SRC			5
>  #define BLSP1_QUP1_I2C_APPS_CLK_SRC		6
> @@ -123,15 +123,21 @@
>  #define GCC_SDCC2_APPS_CLK			105
>  #define GCC_SDCC3_APPS_CLK			106
>  #define GCC_SDCC4_APPS_CLK			107
> -#define GCC_SYS_NOC_UFS_AXI_CLK			108
> -#define GCC_SYS_NOC_USB3_AXI_CLK		109
> -#define GCC_TSIF_REF_CLK			110
> -#define GCC_UFS_AXI_CLK				111
> -#define GCC_UFS_RX_CFG_CLK			112
> -#define GCC_UFS_TX_CFG_CLK			113
> -#define GCC_USB30_MASTER_CLK			114
> -#define GCC_USB30_MOCK_UTMI_CLK			115
> -#define GCC_USB3_PHY_AUX_CLK			116
> -#define GCC_USB_HS_SYSTEM_CLK			117
> +#define GCC_SDCC1_AHB_CLK			108
> +#define GCC_SDCC2_AHB_CLK			109

There should be an ahb clk for sdcc3 and sdcc4 too. Please just
add the defines even if they're not used.

> +
> +#define GCC_SYS_NOC_UFS_AXI_CLK			110

And don't change the numbering randomly. This should still be
108.

> +#define GCC_SYS_NOC_USB3_AXI_CLK		111
> +#define GCC_TSIF_REF_CLK			112
> +#define GCC_UFS_AXI_CLK				113
> +#define GCC_UFS_RX_CFG_CLK			114
> +#define GCC_UFS_TX_CFG_CLK			115
> +#define GCC_USB30_MASTER_CLK			116
> +#define GCC_USB30_MOCK_UTMI_CLK			117
> +#define GCC_USB3_PHY_AUX_CLK			118
> +#define GCC_USB_HS_SYSTEM_CLK			119
> +#define SYSTEM_NOC_CLK_SRC			120
> +#define PERIPH_NOC_CLK_SRC			121
> +#define CONFIG_NOC_CLK_SRC			122

And then the diff will be understandable.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH 1/2] ARM: dts: dra7-evm: increase QSPI SPL partition size
From: Tony Lindgren @ 2017-01-17 23:27 UTC (permalink / raw)
  To: B, Ravi
  Cc: devicetree@vger.kernel.org, nsekhar@list.ti.com, Nori, Sekhar,
	bcousson@baylibre.com, linux-omap@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <6C6B28D4DC342643927BEAFCE8707BF6C0A8C367@DBDE04.ent.ti.com>

* B, Ravi <ravibabu@ti.com> [170117 00:15]:
> Hi Tony
> 
> >* Ravi Babu <ravibabu@ti.com> [170113 04:41]:
> >> The SPL size for DRA74x platform has increased and is now more than 
> >> 64KB. Increase QSPI SPL partition size to 256KB for DRA74x EVM.
> >> 
> >> QSPI partition numbering changes because of this.
> 
> >And this will break the existing partitions potentially..
> >See what was discussed on the list few days ago in thread "[PATCH 1/6] ARM: dts: am335x-phycore-som: Update NAND partition table".
> 
> >It's best to have these left empty or as they originally were and let u-boot configure the partitions.
> 
> Agree with you. For dra7xx platform the SPL size has been increased to 256KB and hence the existing QSPI SPL partition in kernel (64K size) will break when latest mainline u-boot is used. 
> Here only SPL partition has been changed and other partition & size is NOT changed and kept intact. I feel it will not break the existing partitions for dra7xx platform.

What about the renumbering of partitions in your patch?

Probably just best to make the partition information empty in the
kernel as discussed.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH] fbdev: ssd1307fb: allow reset-gpios is missing
From: Andy Shevchenko @ 2017-01-17 23:29 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Icenowy Zheng, David Airlie, linux-fbdev, Rob Herring,
	linux-kernel@vger.kernel.org, devicetree
In-Reply-To: <20170117074013.iqzfuoc3ys27347y@lukather>

On Tue, Jan 17, 2017 at 9:40 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Mon, Jan 16, 2017 at 05:50:21PM +0800, Icenowy Zheng wrote:
>>
>> 2017年1月16日 16:02于 Maxime Ripard <maxime.ripard@free-electrons.com>写道:
>> >
>> > On Sun, Jan 15, 2017 at 07:21:46PM +0800, Icenowy Zheng wrote:
>> > > Currently some SSD1306 OLED modules are sold without a reset pin (only
>> > > VCC, GND, SCK, SDA four pins).
>> > >
>> > > Add support for missing reset-gpios property.
>> > >
>> > > Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
>> >
>> > Unfortunately, a similar patch has been sent a couple of times
>> > already:
>> > https://www.spinics.net/lists/devicetree/msg158330.html
>>
>> Why is it never merged?
>
> It was sent 4 days ago...
>
> And since you didn't have the right maintainers in the cc list, yours
> didn't have a chance to be merged either.
>
>> There are really boards that needs this function.
>
> Then  you can accelerate its inclusion by reviewing it.

Perhaps someone eventually adds drivers/reset/reset-gpio.c and uses
devm_get_reset_optional_exclusive() instead?


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH v3 2/4] dt-bindings: Add TI SCI PM Domains
From: Rob Herring @ 2017-01-17 23:37 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Nishanth Menon, devicetree@vger.kernel.org, Ulf Hansson,
	Santosh Shilimkar, Kevin Hilman, Lokesh Vutla, Keerthy,
	linux-pm@vger.kernel.org, Dave Gerlach, Rafael J . Wysocki,
	linux-kernel@vger.kernel.org, Russell King, Sudeep Holla,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <4cb25cf9-216f-2e18-f45d-ef7e48fa6c5e@ti.com>

On Tue, Jan 17, 2017 at 1:48 AM, Tero Kristo <t-kristo@ti.com> wrote:
> On 17/01/17 00:12, Dave Gerlach wrote:
>>
>> On 01/13/2017 08:40 PM, Rob Herring wrote:
>>>
>>> On Fri, Jan 13, 2017 at 2:28 PM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>>
>>>> On 01/13/2017 01:25 PM, Rob Herring wrote:
>>>>>
>>>>>
>>>>> On Thu, Jan 12, 2017 at 9:27 AM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>>>>
>>>>>>
>>>>>> Rob,
>>>>>>
>>>>>> On 01/11/2017 03:34 PM, Rob Herring wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jan 9, 2017 at 11:57 AM, Dave Gerlach <d-gerlach@ti.com>
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Rob,
>>>>>>>>
>>>>>>>> On 01/09/2017 11:50 AM, Rob Herring wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, Jan 04, 2017 at 02:55:34PM -0600, Dave Gerlach wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Add a generic power domain implementation, TI SCI PM Domains, that
>>>>>>>>>> will hook into the genpd framework and allow the TI SCI
>>>>>>>>>> protocol to
>>>>>>>>>> control device power states.
>>>>>>>>>>
>>>>>>>>>> Also, provide macros representing each device index as understood
>>>>>>>>>> by TI SCI to be used in the device node power-domain references.
>>>>>>>>>> These are identifiers for the K2G devices managed by the PMMC.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>>>>>>>> Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
>>>>>>>>>> ---
>>>>>>>>>> v2->v3:
>>>>>>>>>>         Update k2g_pds node docs to show it should be a child
>>>>>>>>>> of pmmc
>>>>>>>>>> node.
>>>>>>>>>>         In early versions a phandle was used to point to pmmc and
>>>>>>>>>> docs
>>>>>>>>>> still
>>>>>>>>>>         incorrectly showed this.
>>>>>>>>>>
>>>>>>>>>>  .../devicetree/bindings/soc/ti/sci-pm-domain.txt   | 59
>>>>>>>>>> ++++++++++++++
>>>>>>>>>>  MAINTAINERS                                        |  2 +
>>>>>>>>>>  include/dt-bindings/genpd/k2g.h                    | 90
>>>>>>>>>> ++++++++++++++++++++++
>>>>>>>>>>  3 files changed, 151 insertions(+)
>>>>>>>>>>  create mode 100644
>>>>>>>>>> Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>>  create mode 100644 include/dt-bindings/genpd/k2g.h
>>>>>>>>>>
>>>>>>>>>> diff --git
>>>>>>>>>> a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> new file mode 100644
>>>>>>>>>> index 000000000000..4c9064e512cb
>>>>>>>>>> --- /dev/null
>>>>>>>>>> +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> @@ -0,0 +1,59 @@
>>>>>>>>>> +Texas Instruments TI-SCI Generic Power Domain
>>>>>>>>>> +---------------------------------------------
>>>>>>>>>> +
>>>>>>>>>> +Some TI SoCs contain a system controller (like the PMMC, etc...)
>>>>>>>>>> that
>>>>>>>>>> is
>>>>>>>>>> +responsible for controlling the state of the IPs that are
>>>>>>>>>> present.
>>>>>>>>>> +Communication between the host processor running an OS and the
>>>>>>>>>> system
>>>>>>>>>> +controller happens through a protocol known as TI-SCI [1].
>>>>>>>>>> This pm
>>>>>>>>>> domain
>>>>>>>>>> +implementation plugs into the generic pm domain framework and
>>>>>>>>>> makes
>>>>>>>>>> use
>>>>>>>>>> of
>>>>>>>>>> +the TI SCI protocol power on and off each device when needed.
>>>>>>>>>> +
>>>>>>>>>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>>>>>>>> +
>>>>>>>>>> +PM Domain Node
>>>>>>>>>> +==============
>>>>>>>>>> +The PM domain node represents the global PM domain managed by the
>>>>>>>>>> PMMC,
>>>>>>>>>> +which in this case is the single implementation as documented
>>>>>>>>>> by the
>>>>>>>>>> generic
>>>>>>>>>> +PM domain bindings in
>>>>>>>>>> Documentation/devicetree/bindings/power/power_domain.txt.
>>>>>>>>>> +Because this relies on the TI SCI protocol to communicate with
>>>>>>>>>> the
>>>>>>>>>> PMMC
>>>>>>>>>> it
>>>>>>>>>> +must be a child of the pmmc node.
>>>>>>>>>> +
>>>>>>>>>> +Required Properties:
>>>>>>>>>> +--------------------
>>>>>>>>>> +- compatible: should be "ti,sci-pm-domain"
>>>>>>>>>> +- #power-domain-cells: Must be 0.
>>>>>>>>>> +
>>>>>>>>>> +Example (K2G):
>>>>>>>>>> +-------------
>>>>>>>>>> +       pmmc: pmmc {
>>>>>>>>>> +               compatible = "ti,k2g-sci";
>>>>>>>>>> +               ...
>>>>>>>>>> +
>>>>>>>>>> +               k2g_pds: k2g_pds {
>>>>>>>>>> +                       compatible = "ti,sci-pm-domain";
>>>>>>>>>> +                       #power-domain-cells = <0>;
>>>>>>>>>> +               };
>>>>>>>>>> +       };
>>>>>>>>>> +
>>>>>>>>>> +PM Domain Consumers
>>>>>>>>>> +===================
>>>>>>>>>> +Hardware blocks that require SCI control over their state must
>>>>>>>>>> provide
>>>>>>>>>> +a reference to the sci-pm-domain they are part of and a unique
>>>>>>>>>> device
>>>>>>>>>> +specific ID that identifies the device.
>>>>>>>>>> +
>>>>>>>>>> +Required Properties:
>>>>>>>>>> +--------------------
>>>>>>>>>> +- power-domains: phandle pointing to the corresponding PM domain
>>>>>>>>>> node.
>>>>>>>>>> +- ti,sci-id: index representing the device id to be passed
>>>>>>>>>> oevr SCI
>>>>>>>>>> to
>>>>>>>>>> +            be used for device control.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> As I've already stated before, this goes in power-domain cells.
>>>>>>>>> When
>>>>>>>>> you
>>>>>>>>> have a single thing (i.e. node) that controls multiple things, then
>>>>>>>>> you
>>>>>>>>> you need to specify the ID for each of them in phandle args.
>>>>>>>>> This is
>>>>>>>>> how
>>>>>>>>> irqs, gpio, clocks, *everything* in DT works.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> You think the reasoning for doing it this way provided by both
>>>>>>>> Ulf and
>>>>>>>> myself on v2 [1] is not valid then?
>>>>>>>>
>>>>>>>> From Ulf:
>>>>>>>>
>>>>>>>> To me, the TI SCI ID, is similar to a "conid" for any another
>>>>>>>> "device
>>>>>>>> resource" (like clock, pinctrl, regulator etc) which we can describe
>>>>>>>> in DT and assign to a device node. The only difference here, is that
>>>>>>>> we don't have common API to fetch the resource (like clk_get(),
>>>>>>>> regulator_get()), but instead we fetches the device's resource from
>>>>>>>> SoC specific code, via genpd's device ->attach() callback.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Sorry, but that sounds like a kernel problem to me and has nothing to
>>>>>>> do with DT bindings.
>>>>>>>
>>>>>>>> From me:
>>>>>>>>
>>>>>>>> Yes, you've pretty much hit it on the head. It is not an index
>>>>>>>> into a
>>>>>>>> list
>>>>>>>> of genpds but rather identifies the device *within* a single
>>>>>>>> genpd. It
>>>>>>>> is
>>>>>>>> a
>>>>>>>> property specific to each device that resides in a ti-sci-genpd,
>>>>>>>> not a
>>>>>>>> mapping describing which genpd the device belongs to. The generic
>>>>>>>> power
>>>>>>>> domain binding is concerned with mapping the device to a specific
>>>>>>>> genpd,
>>>>>>>> which is does fine for us, but we have a sub mapping for devices
>>>>>>>> that
>>>>>>>> exist
>>>>>>>> inside a genpd which, we must describe as well, hence the ti,sci-id.
>>>>>>>>
>>>>>>>>
>>>>>>>> So to summarize, the genpd framework does interpret the phandle
>>>>>>>> arg as
>>>>>>>> an
>>>>>>>> index into multiple genpds, just as you've said other frameworks do,
>>>>>>>> but
>>>>>>>> this is not what I am trying to do, we have multiple devices within
>>>>>>>> this
>>>>>>>> *single* genpd, hence the need for the ti,sci-id property.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Fix the genpd framework rather than work around it in DT.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> I still disagree that this has nothing to do with DT bindings, as the
>>>>>> current DT binding represents something different already. I am
>>>>>> trying to
>>>>>> extend it to give me additional information needed for our
>>>>>> platforms. Are
>>>>>> you saying that we should break what the current DT binding already
>>>>>> represents to mean something else?
>>>>>
>>>>>
>>>>>
>>>>> No idea because what's the current binding? From the patch, looks like
>>>>> a new binding to me.
>>>>
>>>>
>>>>
>>>> Yes, ti,sci-id is a new binding. I am referring to the current
>>>> meaning of
>>>> the "power-domains" binding, which is where you are asking this
>>>> property to
>>>> be added, in "power-domains" cells. This is documented here [1] in the
>>>> kernel, although looking at it I must admit it is not very clear.
>>>>
>>>> The power-domains cell represents an offset into an array of power
>>>> domains,
>>>> if you choose to use it. That's what the genpd framework is hard
>>>> coded to
>>>> interpret it as. This is correct, as it is an index into a static
>>>> list of
>>>> power domains, used to identify which power domain a device belongs to,
>>>> which is exactly what the genpd framework itself is concerned with.
>>>> This is
>>>> already how it is used in the kernel today.
>>>
>>>
>>> Strictly speaking, the cells are purely for the interpretation of the
>>> phandle they are associated with. If some controller wants to have 20
>>> cells, then it could assuming a good reason. The reality is we tend to
>>> align the meaning of the cells. If genpd is interpreting the cells and
>>> not letting the driver for the power domain controller interpret them,
>>> then still, genpd needs to be fixed.
>>
>>
>> Ok, perhaps the genpd folks on the thread can jump in here with any
>> thoughts that they have.
>>
>>>
>>> IIRC, initially it was said genpd required 0 cells, hence my confusion.
>>>
>>>> My ti,sci-id is not an index into a list of power domains, so it
>>>> should not
>>>> go in the power-domains cells and go against what the power-domains
>>>> binding
>>>> says that the cell expects. We have one single power domain, and the new
>>>> ti,sci-id binding is not something the genpd framework itself is
>>>> concerned
>>>> with as it's our property to identify a device inside a power domain,
>>>> not to
>>>> identify which power domain it is associated with.
>>>
>>>
>>> What is the id used for? I can understand why you need to know what
>>> power domain a device is in (as power-domains identifies), but not
>>> what devices are in a power domain.
>>
>>
>> We have a system control processor that provides power management
>> services to the OS and it responsible for handling the power state of
>> each device. This control happens over a communication interface we have
>> called TI SCI (implemented at drivers/firmware/ti-sci.c). The
>> communication protocol uses these ids to identify each device within the
>> power domain so that the control processor can do what is necessary to
>> enable that device.
>
>
> I think a minor detail here that Rob might be missing right now is, that the
> ti,sci-id is only controlling the PM runtime handling, and providing the ID
> per-device for this purpose only. AFAIK, it is not really connected to the
> power domain anymore as such, as we don't have power-domains / per device
> anymore as was the case in some earlier revision of this work.

So you used to have multiple power domains and now you don't? Did the
h/w change?

> One could argue though that the whole usage of power-domains is now moot, as
> we basically only have implemented one genpd in the whole SoC, which doesn't
> really reflect the reality. I wonder if better approach would be to have
> this replaced with proper power domains at some point (if needed), and just
> have a runtime-pm implementation in place for the devices that require it.

We're talking about bindings here. Any explanation in terms of
runtime-pm and genpd a) goes over my head and b) isn't relevant to
describing the hardware.

I'm still confused with how many power domains (as defined by the h/w
design) there are controlled by the SCI? Is it 1 or multiple? If 1,
then why do you need the sci-id? For other things that are not the
power domain?

Or perhaps the SCI abstracts things such that you don't really know
what the relationship between devices and power domains is? IOW, you
can't tell from the SCI interface how many power domains there are.

>
> So, as an example in DT, we would only have:
>
> uart0: serial@02530c00 {
>   compatible = "xyz";
>   ...
>   ti,sci-id = <K2G_DEV_UART0>;
> };
>
> This is somewhat analogous to what OMAP family of SoCs have in place now,
> under "ti,hwmods" property. I also wonder if the "ti,sci-id" should be
> replaced with something like "ti,sci-dev-id" to make its purpose clearer.

Describing in terms of hwmods doesn't help me either. Never understood
that either. Sorry.

Rob

^ permalink raw reply

* Re: [PATCH v4] ARM64: dts: meson-gx: Add reserved memory zone and usable memory range
From: Andreas Färber @ 2017-01-18  0:00 UTC (permalink / raw)
  To: Neil Armstrong, Kevin Hilman
  Cc: Olof Johansson, devicetree@vger.kernel.org, xypron.glpk,
	linux-kernel@vger.kernel.org, Carlo Caione, linux-amlogic,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <ecb5ff50-f5d5-ffe6-0732-faf5e51906f8@baylibre.com>

Hi Neil,

Am 17.01.2017 um 09:21 schrieb Neil Armstrong:
> As I finally understand, the real issue here is the usage of the "linux,useable-memory" property that
> overrides the reg property that is changed by the bootloader to provide the "real" memory size.

Yes, exactly. It assured that 0..0x01000000 was always unavailable, as
intended, but at the same time it ignored any lowered or heightened
upper limit coming from the bootloader side.

As a rule of thumb, any nodes that have device_type set can be expected
to be modified during boot.

> As I understand the mainline U-Boot does it right, and it's a good news, and it seems uEFI need to provide
> some specialized memory range aswell, but the vendor U-Boot versions only provide the full memory range here.
> It seems obvious that whatever range is provided by u-boot, the first 16MiB should be reserved.
> 
> The stress-ng package provides this "stress" command and is used to force the kernel to map more memory
> zones,

Thanks, its binary is called stress-ng in openSUSE Tumbleweed. ;)

> but I also got the issue while running a fully fledged Desktop Environment thanks to the
> recently merged DRM driver.

I'll happily test once HDMI is ready. :)

> You may not be able to trigger the issue since it seems Amlogic reduces this reserved size on GXL/GXM :
> https://github.com/khadas/linux/commit/698df2c6cfbb0d1a9359743208e83517b31da6ce
> But it should be confirmed.

Confirming no issues on three runs on meson-gxm-rbox-pro:

boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s &
[1] 2528
boxer:~ # stress-ng: info:  [2528] dispatching hogs: 4 vm
stress-ng: info:  [2528] cache allocate: default cache size: 256K
stress-ng: info:  [2528] successful run completed in 10.07s

[1]+  Done                    stress-ng --vm 4 --vm-bytes 128M --timeout 10s
boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s
stress-ng: info:  [2537] dispatching hogs: 4 vm
stress-ng: info:  [2537] cache allocate: default cache size: 256K
stress-ng: info:  [2537] successful run completed in 10.07s
boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s
stress-ng: info:  [2546] dispatching hogs: 4 vm
stress-ng: info:  [2546] cache allocate: default cache size: 256K
stress-ng: info:  [2546] successful run completed in 10.07s
boxer:~ #

> Kevin asked me initially to handle this "start of ddr" reserved zone via a reserved-memory entry, but
> at that time it seemed a better idea to use "linux,useable-memory", but I recon it may be an error.
> 
> I will push a v5 with a supplementary reserved-memory entry and will postpone the boards memory size
> fixup for a future DTS cleanup.
> 
> Andreas, is this ok for you ?

Yes, sounds fine to me, thanks. I'll note a few more nits to consider.

Kevin, I noticed that this supposedly applied patch did not show up in
linux-next for testing - could you merge your fixes branch into for-next
please for those of us working on new stuff?

> This issue exists since forever on mainline linux, and even 4.9 has it.
> Olof, How could a similar fix go in 4.9 stable ?

I guess it would then be best to consider splitting this patch up per
board/SoC so that you can set appropriate Fixes: headers indicating how
far back each one needs to be fixed.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply

* Re: [PATCH v3 2/4] dt-bindings: Add TI SCI PM Domains
From: Kevin Hilman @ 2017-01-18  0:07 UTC (permalink / raw)
  To: Tero Kristo
  Cc: Dave Gerlach, Rob Herring, Ulf Hansson, Rafael J . Wysocki,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	devicetree@vger.kernel.org, Nishanth Menon, Keerthy, Russell King,
	Sudeep Holla, Santosh Shilimkar, Lokesh Vutla
In-Reply-To: <4cb25cf9-216f-2e18-f45d-ef7e48fa6c5e@ti.com>

Tero Kristo <t-kristo@ti.com> writes:

> On 17/01/17 00:12, Dave Gerlach wrote:
>> On 01/13/2017 08:40 PM, Rob Herring wrote:
>>> On Fri, Jan 13, 2017 at 2:28 PM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>> On 01/13/2017 01:25 PM, Rob Herring wrote:
>>>>>
>>>>> On Thu, Jan 12, 2017 at 9:27 AM, Dave Gerlach <d-gerlach@ti.com> wrote:
>>>>>>
>>>>>> Rob,
>>>>>>
>>>>>> On 01/11/2017 03:34 PM, Rob Herring wrote:
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jan 9, 2017 at 11:57 AM, Dave Gerlach <d-gerlach@ti.com>
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> Rob,
>>>>>>>>
>>>>>>>> On 01/09/2017 11:50 AM, Rob Herring wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, Jan 04, 2017 at 02:55:34PM -0600, Dave Gerlach wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Add a generic power domain implementation, TI SCI PM Domains, that
>>>>>>>>>> will hook into the genpd framework and allow the TI SCI
>>>>>>>>>> protocol to
>>>>>>>>>> control device power states.
>>>>>>>>>>
>>>>>>>>>> Also, provide macros representing each device index as understood
>>>>>>>>>> by TI SCI to be used in the device node power-domain references.
>>>>>>>>>> These are identifiers for the K2G devices managed by the PMMC.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>>>>>>>> Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
>>>>>>>>>> ---
>>>>>>>>>> v2->v3:
>>>>>>>>>>         Update k2g_pds node docs to show it should be a child
>>>>>>>>>> of pmmc
>>>>>>>>>> node.
>>>>>>>>>>         In early versions a phandle was used to point to pmmc and
>>>>>>>>>> docs
>>>>>>>>>> still
>>>>>>>>>>         incorrectly showed this.
>>>>>>>>>>
>>>>>>>>>>  .../devicetree/bindings/soc/ti/sci-pm-domain.txt   | 59
>>>>>>>>>> ++++++++++++++
>>>>>>>>>>  MAINTAINERS                                        |  2 +
>>>>>>>>>>  include/dt-bindings/genpd/k2g.h                    | 90
>>>>>>>>>> ++++++++++++++++++++++
>>>>>>>>>>  3 files changed, 151 insertions(+)
>>>>>>>>>>  create mode 100644
>>>>>>>>>> Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>>  create mode 100644 include/dt-bindings/genpd/k2g.h
>>>>>>>>>>
>>>>>>>>>> diff --git
>>>>>>>>>> a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> new file mode 100644
>>>>>>>>>> index 000000000000..4c9064e512cb
>>>>>>>>>> --- /dev/null
>>>>>>>>>> +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>>>>>>>>> @@ -0,0 +1,59 @@
>>>>>>>>>> +Texas Instruments TI-SCI Generic Power Domain
>>>>>>>>>> +---------------------------------------------
>>>>>>>>>> +
>>>>>>>>>> +Some TI SoCs contain a system controller (like the PMMC, etc...)
>>>>>>>>>> that
>>>>>>>>>> is
>>>>>>>>>> +responsible for controlling the state of the IPs that are
>>>>>>>>>> present.
>>>>>>>>>> +Communication between the host processor running an OS and the
>>>>>>>>>> system
>>>>>>>>>> +controller happens through a protocol known as TI-SCI [1].
>>>>>>>>>> This pm
>>>>>>>>>> domain
>>>>>>>>>> +implementation plugs into the generic pm domain framework and
>>>>>>>>>> makes
>>>>>>>>>> use
>>>>>>>>>> of
>>>>>>>>>> +the TI SCI protocol power on and off each device when needed.
>>>>>>>>>> +
>>>>>>>>>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>>>>>>>> +
>>>>>>>>>> +PM Domain Node
>>>>>>>>>> +==============
>>>>>>>>>> +The PM domain node represents the global PM domain managed by the
>>>>>>>>>> PMMC,
>>>>>>>>>> +which in this case is the single implementation as documented
>>>>>>>>>> by the
>>>>>>>>>> generic
>>>>>>>>>> +PM domain bindings in
>>>>>>>>>> Documentation/devicetree/bindings/power/power_domain.txt.
>>>>>>>>>> +Because this relies on the TI SCI protocol to communicate with
>>>>>>>>>> the
>>>>>>>>>> PMMC
>>>>>>>>>> it
>>>>>>>>>> +must be a child of the pmmc node.
>>>>>>>>>> +
>>>>>>>>>> +Required Properties:
>>>>>>>>>> +--------------------
>>>>>>>>>> +- compatible: should be "ti,sci-pm-domain"
>>>>>>>>>> +- #power-domain-cells: Must be 0.
>>>>>>>>>> +
>>>>>>>>>> +Example (K2G):
>>>>>>>>>> +-------------
>>>>>>>>>> +       pmmc: pmmc {
>>>>>>>>>> +               compatible = "ti,k2g-sci";
>>>>>>>>>> +               ...
>>>>>>>>>> +
>>>>>>>>>> +               k2g_pds: k2g_pds {
>>>>>>>>>> +                       compatible = "ti,sci-pm-domain";
>>>>>>>>>> +                       #power-domain-cells = <0>;
>>>>>>>>>> +               };
>>>>>>>>>> +       };
>>>>>>>>>> +
>>>>>>>>>> +PM Domain Consumers
>>>>>>>>>> +===================
>>>>>>>>>> +Hardware blocks that require SCI control over their state must
>>>>>>>>>> provide
>>>>>>>>>> +a reference to the sci-pm-domain they are part of and a unique
>>>>>>>>>> device
>>>>>>>>>> +specific ID that identifies the device.
>>>>>>>>>> +
>>>>>>>>>> +Required Properties:
>>>>>>>>>> +--------------------
>>>>>>>>>> +- power-domains: phandle pointing to the corresponding PM domain
>>>>>>>>>> node.
>>>>>>>>>> +- ti,sci-id: index representing the device id to be passed
>>>>>>>>>> oevr SCI
>>>>>>>>>> to
>>>>>>>>>> +            be used for device control.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> As I've already stated before, this goes in power-domain cells.
>>>>>>>>> When
>>>>>>>>> you
>>>>>>>>> have a single thing (i.e. node) that controls multiple things, then
>>>>>>>>> you
>>>>>>>>> you need to specify the ID for each of them in phandle args.
>>>>>>>>> This is
>>>>>>>>> how
>>>>>>>>> irqs, gpio, clocks, *everything* in DT works.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> You think the reasoning for doing it this way provided by both
>>>>>>>> Ulf and
>>>>>>>> myself on v2 [1] is not valid then?
>>>>>>>>
>>>>>>>> From Ulf:
>>>>>>>>
>>>>>>>> To me, the TI SCI ID, is similar to a "conid" for any another
>>>>>>>> "device
>>>>>>>> resource" (like clock, pinctrl, regulator etc) which we can describe
>>>>>>>> in DT and assign to a device node. The only difference here, is that
>>>>>>>> we don't have common API to fetch the resource (like clk_get(),
>>>>>>>> regulator_get()), but instead we fetches the device's resource from
>>>>>>>> SoC specific code, via genpd's device ->attach() callback.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Sorry, but that sounds like a kernel problem to me and has nothing to
>>>>>>> do with DT bindings.
>>>>>>>
>>>>>>>> From me:
>>>>>>>>
>>>>>>>> Yes, you've pretty much hit it on the head. It is not an index
>>>>>>>> into a
>>>>>>>> list
>>>>>>>> of genpds but rather identifies the device *within* a single
>>>>>>>> genpd. It
>>>>>>>> is
>>>>>>>> a
>>>>>>>> property specific to each device that resides in a ti-sci-genpd,
>>>>>>>> not a
>>>>>>>> mapping describing which genpd the device belongs to. The generic
>>>>>>>> power
>>>>>>>> domain binding is concerned with mapping the device to a specific
>>>>>>>> genpd,
>>>>>>>> which is does fine for us, but we have a sub mapping for devices
>>>>>>>> that
>>>>>>>> exist
>>>>>>>> inside a genpd which, we must describe as well, hence the ti,sci-id.
>>>>>>>>
>>>>>>>>
>>>>>>>> So to summarize, the genpd framework does interpret the phandle
>>>>>>>> arg as
>>>>>>>> an
>>>>>>>> index into multiple genpds, just as you've said other frameworks do,
>>>>>>>> but
>>>>>>>> this is not what I am trying to do, we have multiple devices within
>>>>>>>> this
>>>>>>>> *single* genpd, hence the need for the ti,sci-id property.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Fix the genpd framework rather than work around it in DT.
>>>>>>
>>>>>>
>>>>>>
>>>>>> I still disagree that this has nothing to do with DT bindings, as the
>>>>>> current DT binding represents something different already. I am
>>>>>> trying to
>>>>>> extend it to give me additional information needed for our
>>>>>> platforms. Are
>>>>>> you saying that we should break what the current DT binding already
>>>>>> represents to mean something else?
>>>>>
>>>>>
>>>>> No idea because what's the current binding? From the patch, looks like
>>>>> a new binding to me.
>>>>
>>>>
>>>> Yes, ti,sci-id is a new binding. I am referring to the current
>>>> meaning of
>>>> the "power-domains" binding, which is where you are asking this
>>>> property to
>>>> be added, in "power-domains" cells. This is documented here [1] in the
>>>> kernel, although looking at it I must admit it is not very clear.
>>>>
>>>> The power-domains cell represents an offset into an array of power
>>>> domains,
>>>> if you choose to use it. That's what the genpd framework is hard
>>>> coded to
>>>> interpret it as. This is correct, as it is an index into a static
>>>> list of
>>>> power domains, used to identify which power domain a device belongs to,
>>>> which is exactly what the genpd framework itself is concerned with.
>>>> This is
>>>> already how it is used in the kernel today.
>>>
>>> Strictly speaking, the cells are purely for the interpretation of the
>>> phandle they are associated with. If some controller wants to have 20
>>> cells, then it could assuming a good reason. The reality is we tend to
>>> align the meaning of the cells. If genpd is interpreting the cells and
>>> not letting the driver for the power domain controller interpret them,
>>> then still, genpd needs to be fixed.
>>
>> Ok, perhaps the genpd folks on the thread can jump in here with any
>> thoughts that they have.
>>
>>>
>>> IIRC, initially it was said genpd required 0 cells, hence my confusion.
>>>
>>>> My ti,sci-id is not an index into a list of power domains, so it
>>>> should not
>>>> go in the power-domains cells and go against what the power-domains
>>>> binding
>>>> says that the cell expects. We have one single power domain, and the new
>>>> ti,sci-id binding is not something the genpd framework itself is
>>>> concerned
>>>> with as it's our property to identify a device inside a power domain,
>>>> not to
>>>> identify which power domain it is associated with.
>>>
>>> What is the id used for? I can understand why you need to know what
>>> power domain a device is in (as power-domains identifies), but not
>>> what devices are in a power domain.
>>
>> We have a system control processor that provides power management
>> services to the OS and it responsible for handling the power state of
>> each device. This control happens over a communication interface we have
>> called TI SCI (implemented at drivers/firmware/ti-sci.c). The
>> communication protocol uses these ids to identify each device within the
>> power domain so that the control processor can do what is necessary to
>> enable that device.
>
> I think a minor detail here that Rob might be missing right now is,
> that the ti,sci-id is only controlling the PM runtime handling, and
> providing the ID per-device for this purpose only. AFAIK, it is not
> really connected to the power domain anymore as such, as we don't have
> power-domains / per device anymore as was the case in some earlier
> revision of this work.

I think this gets to the heart of things.  IMO The confusion arises
because we're throwing around the term "power domain" when there isn't
an actual hardware power domain here.

Unfortunately, the genpd bindings have used the terminology power-domain
when in fact genpd is more generic than that and can be used not just
for hardware power domains, but for arbitrary grouping of devices that
have common PM properties.  That's why genpd actually stands for generic
PM domain, not power domain.  Unfortunately, the bindings have grown
primarily out of the usage for hardware power domains.

> One could argue though that the whole usage of power-domains is now
> moot, as we basically only have implemented one genpd in the whole
> SoC, which doesn't really reflect the reality. I wonder if better
> approach would be to have this replaced with proper power domains at
> some point (if needed), and just have a runtime-pm implementation in
> place for the devices that require it.
>
> So, as an example in DT, we would only have:
>
> uart0: serial@02530c00 {
>   compatible = "xyz";
>   ...
>   ti,sci-id = <K2G_DEV_UART0>;
> };
>
> This is somewhat analogous to what OMAP family of SoCs have in place
> now, under "ti,hwmods" property. I also wonder if the "ti,sci-id"
> should be replaced with something like "ti,sci-dev-id" to make its
> purpose clearer.

Unless I'm missing something, that still begs the question of who reads
that property and takes care of the call into TI-SCI though.

Kevin

^ permalink raw reply

* Re: [PATCH v4] ARM64: dts: meson-gx: Add reserved memory zone and usable memory range
From: Andreas Färber @ 2017-01-18  0:09 UTC (permalink / raw)
  To: Neil Armstrong, khilman-rdvid1DuHRBWk0Htik3J/w,
	carlo-KA+7E9HrN00dnm+yROfE0A
  Cc: xypron.glpk-Mmb7MZpHnFY,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1484129414-23325-1-git-send-email-narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Am 11.01.2017 um 11:10 schrieb Neil Armstrong:
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index eada0b5..66677b5 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -55,6 +55,18 @@
>  	#address-cells = <2>;
>  	#size-cells = <2>;
>  
> +	reserved-memory {

Should this get a label for future gx*-level additions?

> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		/* 2MiB reserved for ARM Trusted Firmware (BL31) */

"2 MiB" please. Ditto for the to-be-refactored 16 MiB node.

> +		secmon: secmon {
> +			reg = <0x0 0x10000000 0x0 0x200000>;
> +			no-map;
> +		};
> +	};
> +
>  	cpus {
>  		#address-cells = <0x2>;
>  		#size-cells = <0x0>;

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] ARM: davinci: da850-evm: fix read access to SPI flash
From: Kevin Hilman @ 2017-01-18  0:25 UTC (permalink / raw)
  To: Fabien Parent
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, nsekhar-l0cyMroinI0,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
In-Reply-To: <20170117125742.9536-1-fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Fabien Parent <fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> writes:

> Read access to the SPI flash are broken on da850-evm, i.e. the data
> read is not what is actually programmed on the flash.
> According to the datasheet for the M25P64 part present on the da850-evm,
> if the SPI frequency is higher than 20MHz then the READ command is not
> usable anymore and only the FAST_READ command can be used to read data.
>
> This commit specifies in the DTS that we should use FAST_READ command
> instead of the READ command.
>
> Signed-off-by: Fabien Parent <fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Tested on da850-evm on top of v4.10-rc3.  This gets the DT boot
functionatliy in line with the legacy (board-file) boot.

Tested-by: Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

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

^ permalink raw reply

* Re: [PATCH v4] ARM64: dts: meson-gx: Add reserved memory zone and usable memory range
From: Andreas Färber @ 2017-01-18  0:27 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: devicetree@vger.kernel.org, Kevin Hilman,
	linux-kernel@vger.kernel.org, Olof Johansson, xypron.glpk,
	Carlo Caione, linux-amlogic, linux-arm-kernel@lists.infradead.org
In-Reply-To: <04113569-e342-77ff-f79a-2c9c4dc4c602@suse.de>

Am 18.01.2017 um 01:00 schrieb Andreas Färber:
> Am 17.01.2017 um 09:21 schrieb Neil Armstrong:
>> The stress-ng package provides this "stress" command and is used to force the kernel to map more memory
>> zones, but I also got the issue while running a fully fledged Desktop Environment thanks to the
>> recently merged DRM driver.
>> You may not be able to trigger the issue since it seems Amlogic reduces this reserved size on GXL/GXM :
>> https://github.com/khadas/linux/commit/698df2c6cfbb0d1a9359743208e83517b31da6ce
>> But it should be confirmed.
> 
> Confirming no issues on three runs on meson-gxm-rbox-pro:
> 
> boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s &
> [1] 2528
> boxer:~ # stress-ng: info:  [2528] dispatching hogs: 4 vm
> stress-ng: info:  [2528] cache allocate: default cache size: 256K
> stress-ng: info:  [2528] successful run completed in 10.07s
> 
> [1]+  Done                    stress-ng --vm 4 --vm-bytes 128M --timeout 10s
> boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s
> stress-ng: info:  [2537] dispatching hogs: 4 vm
> stress-ng: info:  [2537] cache allocate: default cache size: 256K
> stress-ng: info:  [2537] successful run completed in 10.07s
> boxer:~ # stress-ng --vm 4 --vm-bytes 128M --timeout 10s
> stress-ng: info:  [2546] dispatching hogs: 4 vm
> stress-ng: info:  [2546] cache allocate: default cache size: 256K
> stress-ng: info:  [2546] successful run completed in 10.07s
> boxer:~ #

Similar results on meson-gxbb-vega-s95-telos (except 512K cache size),
with both mainline EFI and vendor U-Boot.

I notice that I don't have CONFIG_DRM enabled - maybe related?

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

_______________________________________________
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 v2 14/14] ARM: dts: da850-lcdk: enable the SATA node
From: Kevin Hilman @ 2017-01-18  0:39 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Sekhar Nori, Patrick Titiano, Michael Turquette, Tejun Heo,
	Rob Herring, Mark Rutland, Russell King, David Lechner, linux-ide,
	devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <1484655976-25382-15-git-send-email-bgolaszewski@baylibre.com>

Bartosz Golaszewski <bgolaszewski@baylibre.com> writes:

> Enable the SATA node for da850-lcdk. We omit the pinctrl property on
> purpose - the muxed SATA pins are not hooked up to anything
> SATA-related on the lcdk.
>
> The REFCLKN/P rate on the board is 100MHz, so we need a multiplier of
> 15 for 1.5GHz PLL rate.

leftover comment from previous version?

Kevin

> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
>  arch/arm/boot/dts/da850-lcdk.dts | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
> index afcb482..fbeee3c 100644
> --- a/arch/arm/boot/dts/da850-lcdk.dts
> +++ b/arch/arm/boot/dts/da850-lcdk.dts
> @@ -105,6 +105,10 @@
>  	status = "okay";
>  };
>  
> +&sata {
> +	status = "okay";
> +};
> +
>  &mdio {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mdio_pins>;

^ permalink raw reply

* [PATCHv2 0/3] OF phandle nexus support + GPIO nexus
From: Stephen Boyd @ 2017-01-18  0:50 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand
  Cc: linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
	Pantelis Antoniou, Linus Walleij, Mark Brown

This is one small chunk of work related to DT overlays for expansion
boards. It would be good to have a way to expose #<list>-cells types of
providers through a connector in a standard way. So we introduce a way
to make "nexus" nodes for these types of properties to remap the consumer
number space to the other side of the connector's number space. It's
basically a copy of the interrupt nexus implementation, but without
the address space matching design and interrupt-parent walking.

The first patch implements a generic method to do this, and the second patch
adds a unit test for it. The third patch is more of an example than anything
else. It shows how we would modify frameworks to use the new API.

I wasn't certain what more to document, but I

Changes since v1:
 * Addition of optional pass-thru parameter
 * Reduction of strings passed to 1 instead of 3 (or 4 now)
 * Updated gpio patch for the new function signature
 * Updated test-case for new funciton signature and pass-thru parameter
 * Updated kernel-doc to be correct and highlighted difference between
   this API and of_parse_phandle_with_args()

Stephen Boyd (3):
  of: Support parsing phandle argument lists through a nexus node
  of: unittest: Add phandle remapping test
  gpio: Support gpio nexus dt bindings

 drivers/gpio/gpiolib-of.c                   |   4 +-
 drivers/of/base.c                           | 186 ++++++++++++++++++++++++++++
 drivers/of/unittest-data/testcases.dts      |  11 ++
 drivers/of/unittest-data/tests-phandle.dtsi |  25 ++++
 drivers/of/unittest.c                       | 120 ++++++++++++++++++
 include/linux/of.h                          |  12 ++
 6 files changed, 356 insertions(+), 2 deletions(-)

-- 
2.10.0.297.gf6727b0


^ permalink raw reply

* [PATCH v2 1/3] of: Support parsing phandle argument lists through a nexus node
From: Stephen Boyd @ 2017-01-18  0:50 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand
  Cc: devicetree, Linus Walleij, Pantelis Antoniou, linux-kernel,
	linux-gpio, Mark Brown, linux-arm-kernel
In-Reply-To: <20170118005038.9216-1-stephen.boyd@linaro.org>

Platforms like 96boards have a standardized connector/expansion
slot that exposes signals like GPIOs to expansion boards in an
SoC agnostic way. We'd like the DT overlays for the expansion
boards to be written once without knowledge of the SoC on the
other side of the connector. This avoids the unscalable
combinatorial explosion of a different DT overlay for each
expansion board and SoC pair.

We need a way to describe the GPIOs routed through the connector
in an SoC agnostic way. Let's introduce nexus property parsing
into the OF core to do this. This is largely based on the
interrupt nexus support we already have. This allows us to remap
a phandle list in a consumer node (e.g. reset-gpios) through a
connector in a generic way (e.g. via gpio-map). Do this in a
generic routine so that we can remap any sort of variable length
phandle list.

Taking GPIOs as an example, the connector would be a GPIO nexus,
supporting the remapping of a GPIO specifier space to multiple
GPIO providers on the SoC. DT would look as shown below, where
'soc_gpio1' and 'soc_gpio2' are inside the SoC, 'connector' is an
expansion port where boards can be plugged in, and
'expansion_device' is a device on the expansion board.

	soc {
		soc_gpio1: gpio-controller1 {
			#gpio-cells = <2>;
		};

		soc_gpio2: gpio-controller2 {
			#gpio-cells = <2>;
		};
	};

	connector: connector {
		#gpio-cells = <2>;
		gpio-map = <0 0 &soc_gpio1 1 0>,
			   <1 0 &soc_gpio2 4 0>,
			   <2 0 &soc_gpio1 3 0>,
			   <3 0 &soc_gpio2 2 0>;
		gpio-map-mask = <0xf 0x0>;
		gpio-map-pass-thru = <0x0 0x1>
	};

	expansion_device {
		reset-gpios = <&connector 2 GPIO_ACTIVE_LOW>;
	};

The GPIO core would use of_parse_phandle_with_args_map() instead
of of_parse_phandle_with_args() and arrive at the same type of
result, a phandle and argument list. The difference is that the
phandle and arguments will be remapped through the nexus node to
the underlying SoC GPIO controller node. In the example above,
we would remap 'reset-gpios' from <&connector 2 GPIO_ACTIVE_LOW>
to <&soc_gpio1 3 GPIO_ACTIVE_LOW>.

Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/of/base.c  | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of.h |  12 ++++
 2 files changed, 198 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index d4bea3c797d6..277a81ff0479 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1775,6 +1775,192 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
 EXPORT_SYMBOL(of_parse_phandle_with_args);
 
 /**
+ * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it
+ * @np:		pointer to a device tree node containing a list
+ * @list_name:	property name that contains a list
+ * @stem_name:	stem of property names that specify phandles' arguments count
+ * @index:	index of a phandle to parse out
+ * @out_args:	optional pointer to output arguments structure (will be filled)
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_args, on error returns appropriate errno
+ * value. The difference between this function and of_parse_phandle_with_args()
+ * is that this API remaps a phandle if the node the phandle points to has
+ * a <@stem_name>-map property.
+ *
+ * Caller is responsible to call of_node_put() on the returned out_args->np
+ * pointer.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *	#list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *	#list-cells = <1>;
+ * }
+ *
+ * phandle3: node3 {
+ * 	#list-cells = <1>;
+ * 	list-map = <0 &phandle2 3>,
+ * 		   <1 &phandle2 2>,
+ * 		   <2 &phandle1 5 1>;
+ *	list-map-mask = <0x3>;
+ * };
+ *
+ * node4 {
+ *	list = <&phandle1 1 2 &phandle3 0>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandle_with_args(node4, "list", "list", 1, &args);
+ */
+int of_parse_phandle_with_args_map(const struct device_node *np,
+				   const char *list_name,
+				   const char *stem_name,
+				   int index, struct of_phandle_args *out_args)
+{
+	char *cells_name, *map_name = NULL, *mask_name = NULL;
+	char *pass_name = NULL;
+	struct device_node *cur, *new = NULL;
+	const __be32 *map, *mask, *pass, *tmp;
+	const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
+	const __be32 dummy_pass[] = { [0 ... MAX_PHANDLE_ARGS] = 0 };
+	__be32 initial_match_array[MAX_PHANDLE_ARGS];
+	const __be32 *match_array = initial_match_array;
+	int i, ret, map_len, match;
+	u32 list_size, new_size;
+
+	if (index < 0)
+		return -EINVAL;
+
+	cells_name = kasprintf(GFP_KERNEL, "#%s-cells", stem_name);
+	if (!cells_name)
+		return -ENOMEM;
+
+	ret = -ENOMEM;
+	map_name = kasprintf(GFP_KERNEL, "%s-map", stem_name);
+	if (!map_name)
+		goto free;
+
+	mask_name = kasprintf(GFP_KERNEL, "%s-map-mask", stem_name);
+	if (!mask_name)
+		goto free;
+
+	pass_name = kasprintf(GFP_KERNEL, "%s-map-pass-thru", stem_name);
+	if (!pass_name)
+		goto free;
+
+	ret = __of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
+					   out_args);
+	if (ret)
+		goto free;
+
+	/* Get the #<list>-cells property */
+	cur = out_args->np;
+	ret = of_property_read_u32(cur, cells_name, &list_size);
+	if (ret < 0)
+		goto put;
+
+	/* Precalculate the match array - this simplifies match loop */
+	for (i = 0; i < list_size; i++)
+		initial_match_array[i] = cpu_to_be32(out_args->args[i]);
+
+	ret = -EINVAL;
+	while (cur) {
+		/* Get the <list>-map property */
+		map = of_get_property(cur, map_name, &map_len);
+		if (!map) {
+			ret = 0;
+			goto free;
+		}
+		map_len /= sizeof(u32);
+
+		/* Get the <list>-map-mask property (optional) */
+		mask = of_get_property(cur, mask_name, NULL);
+		if (!mask)
+			mask = dummy_mask;
+		/* Iterate through <list>-map property */
+		match = 0;
+		while (map_len > (list_size + 1) && !match) {
+			/* Compare specifiers */
+			match = 1;
+			for (i = 0; i < list_size; i++, map_len--)
+				match &= !((match_array[i] ^ *map++) & mask[i]);
+
+			of_node_put(new);
+			new = of_find_node_by_phandle(be32_to_cpup(map));
+			map++;
+			map_len--;
+
+			/* Check if not found */
+			if (!new)
+				goto put;
+
+			if (!of_device_is_available(new))
+				match = 0;
+
+			tmp = of_get_property(new, cells_name, NULL);
+			if (!tmp)
+				goto put;
+
+			new_size = be32_to_cpu(*tmp);
+
+			/* Check for malformed properties */
+			if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
+				goto put;
+			if (map_len < new_size)
+				goto put;
+
+			/* Move forward by new node's #<list>-cells amount */
+			map += new_size;
+			map_len -= new_size;
+		}
+		if (!match)
+			goto put;
+
+		/* Get the <list>-map-pass-thru property (optional) */
+		pass = of_get_property(cur, pass_name, NULL);
+		if (!pass)
+			pass = dummy_pass;
+
+		/*
+		 * Successfully parsed a <list>-map translation; copy new
+		 * specifier into the out_args structure, keeping the
+		 * bits specified in <list>-map-pass-thru.
+		 */
+		match_array = map - new_size;
+		for (i = 0; i < new_size; i++) {
+			__be32 val = *(map - new_size + i);
+
+			if (i < list_size) {
+				val &= ~pass[i];
+				val |= cpu_to_be32(out_args->args[i]) & pass[i];
+			}
+
+			out_args->args[i] = be32_to_cpu(val);
+		}
+		out_args->args_count = list_size = new_size;
+		/* Iterate again with new provider */
+		out_args->np = new;
+		of_node_put(cur);
+		cur = new;
+	}
+put:
+	of_node_put(cur);
+	of_node_put(new);
+free:
+	kfree(mask_name);
+	kfree(map_name);
+	kfree(cells_name);
+	kfree(pass_name);
+
+	return ret;
+}
+EXPORT_SYMBOL(of_parse_phandle_with_args_map);
+
+/**
  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
  * @np:		pointer to a device tree node containing a list
  * @list_name:	property name that contains a list
diff --git a/include/linux/of.h b/include/linux/of.h
index 011c4984cdf5..f22d4a83ca07 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -344,6 +344,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np,
 extern int of_parse_phandle_with_args(const struct device_node *np,
 	const char *list_name, const char *cells_name, int index,
 	struct of_phandle_args *out_args);
+extern int of_parse_phandle_with_args_map(const struct device_node *np,
+	const char *list_name, const char *stem_name, int index,
+	struct of_phandle_args *out_args);
 extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
 	const char *list_name, int cells_count, int index,
 	struct of_phandle_args *out_args);
@@ -738,6 +741,15 @@ static inline int of_parse_phandle_with_args(const struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_parse_phandle_with_args_map(const struct device_node *np,
+						 const char *list_name,
+						 const char *stem_name,
+						 int index,
+						 struct of_phandle_args *out_args)
+{
+	return -ENOSYS;
+}
+
 static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
 	const char *list_name, int cells_count, int index,
 	struct of_phandle_args *out_args)
-- 
2.10.0.297.gf6727b0

^ permalink raw reply related

* [PATCH v2 2/3] of: unittest: Add phandle remapping test
From: Stephen Boyd @ 2017-01-18  0:50 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand
  Cc: linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
	Pantelis Antoniou, Linus Walleij, Mark Brown
In-Reply-To: <20170118005038.9216-1-stephen.boyd@linaro.org>

Test the functionality of of_parse_phandle_with_args_map().

Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/of/unittest-data/testcases.dts      |  11 +++
 drivers/of/unittest-data/tests-phandle.dtsi |  25 ++++++
 drivers/of/unittest.c                       | 120 ++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)

diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts
index 12f7c3d649c8..173b96f39cd0 100644
--- a/drivers/of/unittest-data/testcases.dts
+++ b/drivers/of/unittest-data/testcases.dts
@@ -26,12 +26,23 @@
 / { __local_fixups__ {
 	testcase-data {
 		phandle-tests {
+			provider4 {
+				phandle-map = <0x00000008 0x00000018
+					       0x00000024 0x0000003c
+					       0x00000050 0x00000064>;
+			};
 			consumer-a {
 				phandle-list = <0x00000000 0x00000008
 						0x00000018 0x00000028
 						0x00000034 0x00000038>;
 				phandle-list-bad-args = <0x00000000 0x0000000c>;
 			};
+			consumer-b {
+				phandle-list = <0x00000000 0x00000008
+						0x00000018 0x00000024
+						0x00000030 0x00000034>;
+				phandle-list-bad-args = <0x00000000 0x0000000c>;
+			};
 		};
 		interrupts {
 			intmap0 {
diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi
index 5b1527e8a7fb..59e297f497d1 100644
--- a/drivers/of/unittest-data/tests-phandle.dtsi
+++ b/drivers/of/unittest-data/tests-phandle.dtsi
@@ -25,6 +25,18 @@
 				#phandle-cells = <3>;
 			};
 
+			provider4: provider4 {
+				#phandle-cells = <2>;
+				phandle-map = <0 1 &provider1 3>,
+					      <4 0 &provider0>,
+					      <16 5 &provider3 3 5 0>,
+					      <200 8 &provider2 23 6>,
+					      <19 0 &provider2 15 0>,
+					      <2 3 &provider3 2 5 3>;
+				phandle-map-mask = <0xff 0xf>;
+				phandle-map-pass-thru = <0x0 0xf0>;
+			};
+
 			consumer-a {
 				phandle-list =	<&provider1 1>,
 						<&provider2 2 0>,
@@ -43,6 +55,19 @@
 				unterminated-string = [40 41 42 43];
 				unterminated-string-list = "first", "second", [40 41 42 43];
 			};
+
+			consumer-b {
+				phandle-list =	<&provider1 1>,
+						<&provider4 2 3>,
+						<0>,
+						<&provider4 4 0x100>,
+						<&provider4 0 0x61>,
+						<&provider0>,
+						<&provider4 19 0x20>;
+				phandle-list-bad-phandle = <12345678 0 0>;
+				phandle-list-bad-args = <&provider2 1 0>,
+							<&provider4 0>;
+			};
 		};
 	};
 };
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 53c83d66eb7e..5baa40d0d83b 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -386,6 +386,125 @@ static void __init of_unittest_parse_phandle_with_args(void)
 	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
 }
 
+static void __init of_unittest_parse_phandle_with_args_map(void)
+{
+	struct device_node *np, *p0, *p1, *p2, *p3;
+	struct of_phandle_args args;
+	int i, rc;
+
+	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b");
+	if (!np) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0");
+	if (!p0) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1");
+	if (!p1) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2");
+	if (!p2) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3");
+	if (!p3) {
+		pr_err("missing testcase data\n");
+		return;
+	}
+
+	rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
+	unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
+
+	for (i = 0; i < 8; i++) {
+		bool passed = true;
+
+		rc = of_parse_phandle_with_args_map(np, "phandle-list",
+						    "phandle", i, &args);
+
+		/* Test the values from tests-phandle.dtsi */
+		switch (i) {
+		case 0:
+			passed &= !rc;
+			passed &= (args.np == p1);
+			passed &= (args.args_count == 1);
+			passed &= (args.args[0] == 1);
+			break;
+		case 1:
+			passed &= !rc;
+			passed &= (args.np == p3);
+			passed &= (args.args_count == 3);
+			passed &= (args.args[0] == 2);
+			passed &= (args.args[1] == 5);
+			passed &= (args.args[2] == 3);
+			break;
+		case 2:
+			passed &= (rc == -ENOENT);
+			break;
+		case 3:
+			passed &= !rc;
+			passed &= (args.np == p0);
+			passed &= (args.args_count == 0);
+			break;
+		case 4:
+			passed &= !rc;
+			passed &= (args.np == p1);
+			passed &= (args.args_count == 1);
+			passed &= (args.args[0] == 3);
+			break;
+		case 5:
+			passed &= !rc;
+			passed &= (args.np == p0);
+			passed &= (args.args_count == 0);
+			break;
+		case 6:
+			passed &= !rc;
+			passed &= (args.np == p2);
+			passed &= (args.args_count == 2);
+			passed &= (args.args[0] == 15);
+			passed &= (args.args[1] == 0x20);
+			break;
+		case 7:
+			passed &= (rc == -ENOENT);
+			break;
+		default:
+			passed = false;
+		}
+
+		unittest(passed, "index %i - data error on node %s rc=%i\n",
+			 i, args.np->full_name, rc);
+	}
+
+	/* Check for missing list property */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-missing",
+					    "phandle", 0, &args);
+	unittest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
+
+	/* Check for missing cells,map,mask property */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list",
+					    "phandle-missing", 0, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+
+	/* Check for bad phandle in list */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle",
+					    "phandle", 0, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+
+	/* Check for incorrectly formed argument list */
+	rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",
+					    "phandle", 1, &args);
+	unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
+}
+
 static void __init of_unittest_property_string(void)
 {
 	const char *strings[4];
@@ -1951,6 +2070,7 @@ static int __init of_unittest(void)
 	of_unittest_find_node_by_name();
 	of_unittest_dynamic();
 	of_unittest_parse_phandle_with_args();
+	of_unittest_parse_phandle_with_args_map();
 	of_unittest_property_string();
 	of_unittest_property_copy();
 	of_unittest_changeset();
-- 
2.10.0.297.gf6727b0

^ permalink raw reply related

* [PATCH v2 3/3] gpio: Support gpio nexus dt bindings
From: Stephen Boyd @ 2017-01-18  0:50 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand
  Cc: linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
	Pantelis Antoniou, Linus Walleij, Mark Brown
In-Reply-To: <20170118005038.9216-1-stephen.boyd@linaro.org>

Platforms like 96boards have a standardized connector/expansion
slot that exposes signals like GPIOs to expansion boards in an
SoC agnostic way. We'd like the DT overlays for the expansion
boards to be written once without knowledge of the SoC on the
other side of the connector. This avoids the unscalable
combinatorial explosion of a different DT overlay for each
expansion board and SoC pair.

Now that we have nexus support in the OF core let's change the
function call here that parses the phandle lists of gpios to use
the nexus variant. This allows us to remap phandles and their
arguments through any number of nexus nodes and end up with the
actual gpio provider being used.

Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/gpio/gpiolib-of.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 92b185f19232..17bca36d4ebb 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -75,8 +75,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
 	struct gpio_desc *desc;
 	int ret;
 
-	ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
-					 &gpiospec);
+	ret = of_parse_phandle_with_args_map(np, propname, "gpio", index,
+					     &gpiospec);
 	if (ret) {
 		pr_debug("%s: can't parse '%s' property of node '%s[%d]'\n",
 			__func__, propname, np->full_name, index);
-- 
2.10.0.297.gf6727b0

^ permalink raw reply related

* [PATCH] ARM: dts: sun6i: sina31s: Enable USB OTG controller in peripheral mode
From: Chen-Yu Tsai @ 2017-01-18  1:01 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

While the SinA31s does have a proper 5-pin mini USB OTG port, the ID
pin does not seem to work. The pin used in the schematics is always low,
regardless of the attached OTG cable or SoC internal pin bias settings.

The v1.5 board is missing bias resistors shown in the schematics for
earlier revisions, and the connections of the remaining one does not
match the schematics either.

In addition, VBUS for this port is disconnected from the board's 5V
power rail. The board features a pad to solder jumper pins to connect
VBUS to 5V manually.

Given the above and the fact that the board has 5 more USB host ports,
it makes more sense to have the OTG port work in peripheral mode.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index 8743aeed1275..7ff68bdd7109 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -153,6 +153,11 @@
 	regulator-name = "vcc-gmac-phy";
 };
 
+&usb_otg {
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
 &usbphy {
 	status = "okay";
 };
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH 2/2] ARM: BCM5301X: Add DT for Luxul XWR-1200
From: Florian Fainelli @ 2017-01-18  1:06 UTC (permalink / raw)
  To: Dan Haab, Florian Fainelli
  Cc: Hauke Mehrtens, Rafał Miłecki,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w, Rob Herring,
	Mark Rutland, Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1484447368-7622-2-git-send-email-dhaab-RSK6WAzFx3QAvxtiuMwx3w@public.gmane.org>

On 01/14/2017 06:29 PM, Dan Haab wrote:
> Luxul XWR-1200 in a dual-band router based on BCM47081. It uses serial
> flash (for bootloader and NVRAM) and NAND flash (for firmware).
> 
> Signed-off-by: Dan Haab <dhaab-RSK6WAzFx3QAvxtiuMwx3w@public.gmane.org>

Applied thanks
-- 
Florian
--
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


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