Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 05/10] ARM: ux500: move AB8500 USB UICC settings to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This moves the set-up of the USB UICC (InteChip USB) from the
board file to the device tree.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 19 ++++++++++++++++++-
 arch/arm/mach-ux500/board-mop500-pins.c |  9 ---------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index 3aae4ec5bcc9..9cf12d5d0923 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -34,7 +34,8 @@
 						    <&gpio35_default_mode>,
 						    <&ycbcr_default_mode>,
 						    <&pwm_default_mode>,
-						    <&adi1_default_mode>;
+						    <&adi1_default_mode>,
+						    <&usbuicc_default_mode>;
 
 					/*
 					 * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
@@ -301,6 +302,22 @@
 							};
 						};
 					};
+					/* This sets up the USB UICC pins */
+					usbuicc {
+						usbuicc_default_mode: usbuicc_default {
+							default_mux {
+								ste,function = "usbuicc";
+								ste,pins = "usbuicc_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO21_H19",
+									 "GPIO22_G20",
+									 "GPIO23_G19";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
 				};
 			};
 		};
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index d0b262242ab7..443b1f4b828a 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -57,15 +57,6 @@ static struct pinctrl_map __initdata ab8500_pinmap[] = {
 	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
 
 	/*
-	 * pins 21,22 and 23 are muxed in USB UICC
-	 * configured in INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("usbuicc_d_1", "usbuicc"),
-	AB8500_PIN_HOG("GPIO21_H19", in_pd),
-	AB8500_PIN_HOG("GPIO22_G20", in_pd),
-	AB8500_PIN_HOG("GPIO23_G19", in_pd),
-
-	/*
 	 * pins 27,28 are muxed in DMIC12
 	 * configured in INPUT PULL DOWN
 	 */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 06/10] ARM: ux500: move AB8500 DMIC settings to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This move the AB8500 DMIC (microphone) pin setup from the board
file to the device tree.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 25 ++++++++++++++++++++++++-
 arch/arm/mach-ux500/board-mop500-pins.c | 24 ------------------------
 2 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index 9cf12d5d0923..6222b8e951c2 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -35,7 +35,8 @@
 						    <&ycbcr_default_mode>,
 						    <&pwm_default_mode>,
 						    <&adi1_default_mode>,
-						    <&usbuicc_default_mode>;
+						    <&usbuicc_default_mode>,
+						    <&dmic_default_mode>;
 
 					/*
 					 * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
@@ -318,6 +319,28 @@
 							};
 						};
 					};
+					/* This sets up the microphone pins */
+					dmic {
+						dmic_default_mode: dmic_default {
+							default_mux {
+								ste,function = "dmic";
+								ste,pins = "dmic12_d_1",
+									 "dmic34_d_1",
+									 "dmic56_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO27_J6",
+									 "GPIO28_K6",
+									 "GPIO29_G6",
+									 "GPIO30_H6",
+									 "GPIO31_F5",
+									 "GPIO32_G5";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+
 				};
 			};
 		};
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index 443b1f4b828a..851f530e6e16 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -57,30 +57,6 @@ static struct pinctrl_map __initdata ab8500_pinmap[] = {
 	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
 
 	/*
-	 * pins 27,28 are muxed in DMIC12
-	 * configured in INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("dmic12_d_1", "dmic"),
-	AB8500_PIN_HOG("GPIO27_J6", in_pd),
-	AB8500_PIN_HOG("GPIO28_K6", in_pd),
-
-	/*
-	 * pins 29,30 are muxed in DMIC34
-	 * configured in INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("dmic34_d_1", "dmic"),
-	AB8500_PIN_HOG("GPIO29_G6", in_pd),
-	AB8500_PIN_HOG("GPIO30_H6", in_pd),
-
-	/*
-	 * pins 31,32 are muxed in DMIC56
-	 * configured in INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("dmic56_d_1", "dmic"),
-	AB8500_PIN_HOG("GPIO31_F5", in_pd),
-	AB8500_PIN_HOG("GPIO32_G5", in_pd),
-
-	/*
 	 * pins 34 is muxed in EXTCPENA
 	 * configured INPUT PULL DOWN
 	 */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 07/10] ARM: ux500: move AB8500 EXTCPENA from board file to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This moves the configuration of the AB8500 EXTCPENA pin
from the board file to the device tree.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 17 +++++++++++++++--
 arch/arm/mach-ux500/board-mop500-pins.c |  7 -------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index 6222b8e951c2..beb59f99eff8 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -36,7 +36,8 @@
 						    <&pwm_default_mode>,
 						    <&adi1_default_mode>,
 						    <&usbuicc_default_mode>,
-						    <&dmic_default_mode>;
+						    <&dmic_default_mode>,
+						    <&extcpena_default_mode>;
 
 					/*
 					 * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
@@ -340,7 +341,19 @@
 							};
 						};
 					};
-
+					extcpena {
+						extcpena_default_mode: extcpena_default {
+							default_mux {
+								ste,function = "extcpena";
+								ste,pins = "extcpena_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO34_R17";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
 				};
 			};
 		};
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index 851f530e6e16..bbd5bc56f7f0 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -57,13 +57,6 @@ static struct pinctrl_map __initdata ab8500_pinmap[] = {
 	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
 
 	/*
-	 * pins 34 is muxed in EXTCPENA
-	 * configured INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("extcpena_d_1", "extcpena"),
-	AB8500_PIN_HOG("GPIO34_R17", in_pd),
-
-	/*
 	 * pins 40 and 41 are muxed in MODCSLSDA
 	 * configured INPUT PULL DOWN
 	 */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 08/10] ARM: ux500: move AB8500 modem I2C settings to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This moves the pin setup of the AB8500 modem I2C pins
(SCL/SDA) from the board file to the device tree.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 18 +++++++++++++++++-
 arch/arm/mach-ux500/board-mop500-pins.c |  8 --------
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index beb59f99eff8..333b554c0bf7 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -37,7 +37,8 @@
 						    <&adi1_default_mode>,
 						    <&usbuicc_default_mode>,
 						    <&dmic_default_mode>,
-						    <&extcpena_default_mode>;
+						    <&extcpena_default_mode>,
+						    <&modsclsda_default_mode>;
 
 					/*
 					 * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
@@ -354,6 +355,21 @@
 							};
 						};
 					};
+					/* Modem I2C setup (SCL and SDA pins) */
+					modsclsda {
+						modsclsda_default_mode: modsclsda_default {
+							default_mux {
+								ste,function = "modsclsda";
+								ste,pins = "modsclsda_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO40_T19",
+									"GPIO41_U19";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
 				};
 			};
 		};
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index bbd5bc56f7f0..cbe91714f57f 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -55,14 +55,6 @@ static struct pinctrl_map __initdata ab8500_pinmap[] = {
 	/* sysclkreq4 disable, mux in gpio configured in input pulldown */
 	AB8500_MUX_STATE("gpio3_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
 	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
-
-	/*
-	 * pins 40 and 41 are muxed in MODCSLSDA
-	 * configured INPUT PULL DOWN
-	 */
-	AB8500_MUX_HOG("modsclsda_d_1", "modsclsda"),
-	AB8500_PIN_HOG("GPIO40_T19", in_pd),
-	AB8500_PIN_HOG("GPIO41_U19", in_pd),
 };
 
 static struct pinctrl_map __initdata ab8505_pinmap[] = {
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 09/10] ARM: ux500: move AB8500 clock out pins to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This moves the AB8500 pin settings for the clock out pins over
to the device tree. We can delete the special setup calls for the
platforms only using the AB8500 and not AB8505.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8500.dtsi  | 51 +++++++++++++++++++++++++++++++++
 arch/arm/mach-ux500/board-mop500-pins.c | 41 --------------------------
 arch/arm/mach-ux500/board-mop500.h      |  2 --
 arch/arm/mach-ux500/cpu-db8500.c        |  7 -----
 4 files changed, 51 insertions(+), 50 deletions(-)

diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
index 333b554c0bf7..30f8601da323 100644
--- a/arch/arm/boot/dts/ste-href-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi
@@ -370,6 +370,57 @@
 							};
 						};
 					};
+					/*
+					 * Clock output pins associated with regulators.
+					 */
+					sysclkreq2 {
+						sysclkreq2_default_mode: sysclkreq2_default {
+							default_mux {
+								ste,function = "sysclkreq";
+								ste,pins = "sysclkreq2_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO1_T10";
+								input-enable;
+								bias-disable;
+							};
+						};
+						sysclkreq2_sleep_mode: sysclkreq2_sleep {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio1_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO1_T10";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					sysclkreq4 {
+						sysclkreq4_default_mode: sysclkreq4_default {
+							default_mux {
+								ste,function = "sysclkreq";
+								ste,pins = "sysclkreq4_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO3_U9";
+								input-enable;
+								bias-disable;
+							};
+						};
+						sysclkreq4_sleep_mode: sysclkreq4_sleep {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio3_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO3_U9";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
 				};
 			};
 		};
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index cbe91714f57f..1597ff7538e3 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -21,16 +21,6 @@
 BIAS(abx500_in_pd, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 1));
 BIAS(abx500_in_nopull, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0));
 
-#define AB8500_MUX_HOG(group, func) \
-	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8500.0", group, func)
-#define AB8500_PIN_HOG(pin, conf) \
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8500.0", pin, abx500_##conf)
-
-#define AB8500_MUX_STATE(group, func, dev, state) \
-	PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8500.0", group, func)
-#define AB8500_PIN_STATE(pin, conf, dev, state) \
-	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8500.0", pin, abx500_##conf)
-
 #define AB8505_MUX_HOG(group, func) \
 	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8505.0", group, func)
 #define AB8505_PIN_HOG(pin, conf) \
@@ -41,22 +31,6 @@ BIAS(abx500_in_nopull, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0));
 #define AB8505_PIN_STATE(pin, conf, dev, state) \
 	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8505.0", pin, abx500_##conf)
 
-static struct pinctrl_map __initdata ab8500_pinmap[] = {
-	/* Sysclkreq2 */
-	AB8500_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.35", PINCTRL_STATE_DEFAULT),
-	AB8500_PIN_STATE("GPIO1_T10", in_nopull, "regulator.35", PINCTRL_STATE_DEFAULT),
-	/* sysclkreq2 disable, mux in gpio configured in input pulldown */
-	AB8500_MUX_STATE("gpio1_a_1", "gpio", "regulator.35", PINCTRL_STATE_SLEEP),
-	AB8500_PIN_STATE("GPIO1_T10", in_pd, "regulator.35", PINCTRL_STATE_SLEEP),
-
-	/* Sysclkreq4 */
-	AB8500_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
-	AB8500_PIN_STATE("GPIO3_U9", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
-	/* sysclkreq4 disable, mux in gpio configured in input pulldown */
-	AB8500_MUX_STATE("gpio3_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
-	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
-};
-
 static struct pinctrl_map __initdata ab8505_pinmap[] = {
 	/* Sysclkreq2 */
 	AB8505_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
@@ -116,19 +90,4 @@ void __init mop500_pinmaps_init(void)
 	if (machine_is_u8520())
 		pinctrl_register_mappings(ab8505_pinmap,
 					  ARRAY_SIZE(ab8505_pinmap));
-	else
-		pinctrl_register_mappings(ab8500_pinmap,
-					  ARRAY_SIZE(ab8500_pinmap));
-}
-
-void __init snowball_pinmaps_init(void)
-{
-	pinctrl_register_mappings(ab8500_pinmap,
-				  ARRAY_SIZE(ab8500_pinmap));
-}
-
-void __init hrefv60_pinmaps_init(void)
-{
-	pinctrl_register_mappings(ab8500_pinmap,
-				  ARRAY_SIZE(ab8500_pinmap));
 }
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index d48e8662c676..320517e17ac9 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -89,7 +89,5 @@ extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp3_platform_data;
 
 void __init mop500_pinmaps_init(void);
-void __init snowball_pinmaps_init(void);
-void __init hrefv60_pinmaps_init(void);
 
 #endif
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index bc8a6183560d..2e52fcba57bd 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -194,13 +194,6 @@ static void __init u8500_init_machine(void)
 	/* Pinmaps must be in place before devices register */
 	if (of_machine_is_compatible("st-ericsson,mop500"))
 		mop500_pinmaps_init();
-	else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
-		snowball_pinmaps_init();
-	} else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
-		hrefv60_pinmaps_init();
-	else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
-		/* TODO: Add pinmaps for ccu9540 board. */
-
 	/* automatically probe child nodes of dbx5x0 devices */
 	if (of_machine_is_compatible("st-ericsson,u8540"))
 		of_platform_populate(NULL, u8500_local_bus_nodes,
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 10/10] ARM: ux500: move last AB8505 set-up to DT
From: Linus Walleij @ 2014-02-04 19:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391543546-11158-1-git-send-email-linus.walleij@linaro.org>

This moves the set-up of the HREF500 with its AB8505 ASIC to
a device tree include. Since there is not yet any device tree
for this board the DTSI is currently unused. After this delete
the board file for pins for good and migration of pins to the
device tree is complete.

Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href-ab8505.dtsi  | 240 ++++++++++++++++++++++++++++++++
 arch/arm/mach-ux500/Makefile            |   1 -
 arch/arm/mach-ux500/board-mop500-pins.c |  93 -------------
 arch/arm/mach-ux500/board-mop500.h      |   2 -
 arch/arm/mach-ux500/cpu-db8500.c        |   3 -
 5 files changed, 240 insertions(+), 99 deletions(-)
 create mode 100644 arch/arm/boot/dts/ste-href-ab8505.dtsi
 delete mode 100644 arch/arm/mach-ux500/board-mop500-pins.c

diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi
new file mode 100644
index 000000000000..6006d62086a2
--- /dev/null
+++ b/arch/arm/boot/dts/ste-href-ab8505.dtsi
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+	soc {
+		prcmu at 80157000 {
+			ab8505 {
+				ab8505-gpio {
+					/* Hog a few default settings */
+					pinctrl-names = "default";
+					pinctrl-0 = <&gpio2_default_mode>,
+						    <&gpio10_default_mode>,
+						    <&gpio11_default_mode>,
+						    <&gpio13_default_mode>,
+						    <&gpio34_default_mode>,
+						    <&gpio50_default_mode>,
+						    <&pwm_default_mode>,
+						    <&adi2_default_mode>,
+						    <&modsclsda_default_mode>,
+						    <&resethw_default_mode>,
+						    <&service_default_mode>;
+
+					/*
+					 * Pins 2, 10, 11, 13, 34 and 50
+					 * are muxed in as GPIO, and configured as INPUT PULL DOWN
+					 */
+					gpio2 {
+						gpio2_default_mode: gpio2_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio2_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO2_R5";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					gpio10 {
+						gpio10_default_mode: gpio10_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio10_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO10_B16";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					gpio11 {
+						gpio11_default_mode: gpio11_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio11_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO11_B17";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					gpio13 {
+						gpio13_default_mode: gpio13_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio13_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO13_D17";
+								input-enable;
+								bias-disable;
+							};
+						};
+					};
+					gpio34 {
+						gpio34_default_mode: gpio34_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio34_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO34_H14";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					gpio50 {
+						gpio50_default_mode: gpio50_default {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio50_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO50_L4";
+								input-enable;
+								bias-disable;
+							};
+						};
+					};
+					/* This sets up the PWM pin 14 */
+					pwm {
+						pwm_default_mode: pwm_default {
+							default_mux {
+								ste,function = "pwmout";
+								ste,pins = "pwmout1_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO14_C16";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					/* This sets up audio interface 2 */
+					adi2 {
+						adi2_default_mode: adi2_default {
+							default_mux {
+								ste,function = "adi2";
+								ste,pins = "adi2_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO17_P2",
+									 "GPIO18_N3",
+									 "GPIO19_T1",
+									 "GPIO20_P3";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					/* Modem I2C setup (SCL and SDA pins) */
+					modsclsda {
+						modsclsda_default_mode: modsclsda_default {
+							default_mux {
+								ste,function = "modsclsda";
+								ste,pins = "modsclsda_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO40_J15",
+									"GPIO41_J14";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					resethw {
+						resethw_default_mode: resethw_default {
+							default_mux {
+								ste,function = "resethw";
+								ste,pins = "resethw_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO52_D16";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					service {
+						service_default_mode: service_default {
+							default_mux {
+								ste,function = "service";
+								ste,pins = "service_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO53_D15";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					/*
+					 * Clock output pins associated with regulators.
+					 */
+					sysclkreq2 {
+						sysclkreq2_default_mode: sysclkreq2_default {
+							default_mux {
+								ste,function = "sysclkreq";
+								ste,pins = "sysclkreq2_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO1_N4";
+								input-enable;
+								bias-disable;
+							};
+						};
+						sysclkreq2_sleep_mode: sysclkreq2_sleep {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio1_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO1_N4";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+					sysclkreq4 {
+						sysclkreq4_default_mode: sysclkreq4_default {
+							default_mux {
+								ste,function = "sysclkreq";
+								ste,pins = "sysclkreq4_d_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO3_P5";
+								input-enable;
+								bias-disable;
+							};
+						};
+						sysclkreq4_sleep_mode: sysclkreq4_sleep {
+							default_mux {
+								ste,function = "gpio";
+								ste,pins = "gpio3_a_1";
+							};
+							default_cfg {
+								ste,pins = "GPIO3_P5";
+								input-enable;
+								bias-pull-down;
+							};
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index d05ba759da30..de544aabf292 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o
 obj-$(CONFIG_MACH_MOP500)	+= board-mop500-sdi.o \
 				board-mop500-regulators.o \
-				board-mop500-pins.o \
 				board-mop500-audio.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
deleted file mode 100644
index 1597ff7538e3..000000000000
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/bug.h>
-#include <linux/string.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinconf-generic.h>
-
-#include <asm/mach-types.h>
-
-#include "board-mop500.h"
-
-/* These simply sets bias for pins */
-#define BIAS(a,b) static unsigned long a[] = { b }
-
-BIAS(abx500_in_pd, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 1));
-BIAS(abx500_in_nopull, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0));
-
-#define AB8505_MUX_HOG(group, func) \
-	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8505.0", group, func)
-#define AB8505_PIN_HOG(pin, conf) \
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8505.0", pin, abx500_##conf)
-
-#define AB8505_MUX_STATE(group, func, dev, state) \
-	PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8505.0", group, func)
-#define AB8505_PIN_STATE(pin, conf, dev, state) \
-	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8505.0", pin, abx500_##conf)
-
-static struct pinctrl_map __initdata ab8505_pinmap[] = {
-	/* Sysclkreq2 */
-	AB8505_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
-	AB8505_PIN_STATE("GPIO1_N4", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
-	/* sysclkreq2 disable, mux in gpio configured in input pulldown */
-	AB8505_MUX_STATE("gpio1_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
-	AB8505_PIN_STATE("GPIO1_N4", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
-
-	/* pins 2 is muxed in GPIO, configured in INPUT PULL DOWN */
-	AB8505_MUX_HOG("gpio2_a_1", "gpio"),
-	AB8505_PIN_HOG("GPIO2_R5", in_pd),
-
-	/* Sysclkreq4 */
-	AB8505_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.37", PINCTRL_STATE_DEFAULT),
-	AB8505_PIN_STATE("GPIO3_P5", in_nopull, "regulator.37", PINCTRL_STATE_DEFAULT),
-	/* sysclkreq4 disable, mux in gpio configured in input pulldown */
-	AB8505_MUX_STATE("gpio3_a_1", "gpio", "regulator.37", PINCTRL_STATE_SLEEP),
-	AB8505_PIN_STATE("GPIO3_P5", in_pd, "regulator.37", PINCTRL_STATE_SLEEP),
-
-	AB8505_MUX_HOG("gpio10_d_1", "gpio"),
-	AB8505_PIN_HOG("GPIO10_B16", in_pd),
-
-	AB8505_MUX_HOG("gpio11_d_1", "gpio"),
-	AB8505_PIN_HOG("GPIO11_B17", in_pd),
-
-	AB8505_MUX_HOG("gpio13_d_1", "gpio"),
-	AB8505_PIN_HOG("GPIO13_D17", in_nopull),
-
-	AB8505_MUX_HOG("pwmout1_d_1", "pwmout"),
-	AB8505_PIN_HOG("GPIO14_C16", in_pd),
-
-	AB8505_MUX_HOG("adi2_d_1", "adi2"),
-	AB8505_PIN_HOG("GPIO17_P2", in_pd),
-	AB8505_PIN_HOG("GPIO18_N3", in_pd),
-	AB8505_PIN_HOG("GPIO19_T1", in_pd),
-	AB8505_PIN_HOG("GPIO20_P3", in_pd),
-
-	AB8505_MUX_HOG("gpio34_a_1", "gpio"),
-	AB8505_PIN_HOG("GPIO34_H14", in_pd),
-
-	AB8505_MUX_HOG("modsclsda_d_1", "modsclsda"),
-	AB8505_PIN_HOG("GPIO40_J15", in_pd),
-	AB8505_PIN_HOG("GPIO41_J14", in_pd),
-
-	AB8505_MUX_HOG("gpio50_d_1", "gpio"),
-	AB8505_PIN_HOG("GPIO50_L4", in_nopull),
-
-	AB8505_MUX_HOG("resethw_d_1", "resethw"),
-	AB8505_PIN_HOG("GPIO52_D16", in_pd),
-
-	AB8505_MUX_HOG("service_d_1", "service"),
-	AB8505_PIN_HOG("GPIO53_D15", in_pd),
-};
-
-void __init mop500_pinmaps_init(void)
-{
-	if (machine_is_u8520())
-		pinctrl_register_mappings(ab8505_pinmap,
-					  ARRAY_SIZE(ab8505_pinmap));
-}
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index 320517e17ac9..bb408b8f48de 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -88,6 +88,4 @@ extern struct msp_i2s_platform_data msp1_platform_data;
 extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp3_platform_data;
 
-void __init mop500_pinmaps_init(void);
-
 #endif
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 2e52fcba57bd..180b3c59be36 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -191,9 +191,6 @@ static void __init u8500_init_machine(void)
 {
 	struct device *parent = db8500_soc_device_init();
 
-	/* Pinmaps must be in place before devices register */
-	if (of_machine_is_compatible("st-ericsson,mop500"))
-		mop500_pinmaps_init();
 	/* automatically probe child nodes of dbx5x0 devices */
 	if (of_machine_is_compatible("st-ericsson,u8540"))
 		of_platform_populate(NULL, u8500_local_bus_nodes,
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH v3 3/5] ASoC: tda998x: add DT documentation of the tda998x CODEC
From: Mark Brown @ 2014-02-04 19:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140204200239.1baf309b@armhf>

On Tue, Feb 04, 2014 at 08:02:39PM +0100, Jean-Francois Moine wrote:
> Mark Brown <broonie@kernel.org> wrote:

> > On Sat, Feb 01, 2014 at 05:48:49PM +0100, Jean-Francois Moine wrote:

> > > +	- compatible: must be "nxp,tda998x-codec".

> > It's not clear to me why there's a separate compatible here - as far as
> > I can see this can only appear as part of one of these devices and
> > there's no addressing or other information that'd account for chip
> > variation so I'd not expect to need to bind this independently of the
> > parent.

> If there is no 'compatible', the CODEC module is not loaded, and, when
> the module is in the core, no CODEC device can be created from the DT.

You're confusing implementation details with device tree specification
here.  We can easily handle loading a subdriver without having to put
anything in the device tree, just create a platform device like we do
with MFDs.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/3713efb2/attachment.sig>

^ permalink raw reply

* UBI leb_write_unlock NULL pointer Oops (continuation) on ARM926
From: Bill Pringlemeir @ 2014-02-04 19:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874n4e4xml.fsf@nbsps.com>

On  4 Feb 2014, bpringlemeir at nbsps.com wrote:

> http://lists.infradead.org/pipermail/linux-mtd/2013-May/046907.html
>
> at91sam9g20 - arm926, different MTD driver. Linux 3.6.9
>
> Code: e5903004 e58d2004 e1560003 0a00002a (e593200c)
>
> 0:   e5903004        ldr     r3, [r0, #4]
> 4:   e58d2004        str     r2, [sp, #4]
> 8:   e1560003        cmp     r6, r3
> c:   0a00002a        beq     0xbc
> 10:   e593200c        ldr     r2, [r3, #12]
>
> The code sequence looks identical and the Oops trace, etc is the same.
> People from Pengutronix also indicated seeing the same type of Opps; I
> think they deal with the IMX, but maybe this was on another board.

>>>> schrieb Wiedemer, Thorsten (Lawo AG):

> Ehmm, OK, OK, even with the changes in kernel, ubi_assert() in
> leb_write_unlock() wouldn't have triggered ...

Another up_read() crash,

 http://lists.infradead.org/pipermail/linux-mtd/2013-July/047512.html

 Code: e1530001 0a000016 e3e01000 e5801000 (e8930003)

 00000000 <.data>:
    0:   e1530001        cmp     r3, r1
    4:   0a000016        beq     0x64
    8:   e3e01000        mvn     r1, #0
    c:   e5801000        str     r1, [r0]
   10:   e8930003        ldm     r3, {r0, r1}

Thorsten's Oops,

 Code: e3e02000 e5842000 e59fc084 e59f0084 (e8930006)

 00000000 <.data>:
    0:   e3e02000        mvn     r2, #0
    4:   e5842000        str     r2, [r4]
    8:   e59fc084        ldr     ip, [pc, #132]  ; 0x94
    c:   e59f0084        ldr     r0, [pc, #132]  ; 0x98
   10:   e8930006        ldm     r3, {r1, r2}

The registers are different, but the instruction sequence is similar.
In my ARM926 build, the __up_read() is,

static inline int list_empty(const struct list_head *head)
{
        return head->next == head;
 250:   e1a01000        mov     r1, r0
 254:   e5b12004        ldr     r2, [r1, #4]!
 258:   e1520001        cmp     r2, r1
 25c:   0a000017        beq     2c0 <__up_read+0xb0>
__rwsem_wake_one_writer(struct rw_semaphore *sem)
{
        struct rwsem_waiter *waiter;
        struct task_struct *tsk;

        sem->activity = -1;
 260:   e3e01000        mvn     r1, #0
 264:   e5801000        str     r1, [r0]
 * in an undefined state.
 */
#ifndef CONFIG_DEBUG_LIST
static inline void list_del(struct list_head *entry)
{
        __list_del(entry->prev, entry->next);
 268:   e8920003        ldm     r2, {r0, r1}
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
        next->prev = prev;
 26c:   e5801004        str     r1, [r0, #4]
        prev->next = next;
 270:   e5810000        str     r0, [r1]


This is the same symptom,

  __rwsem_wake_one_writer(struct rw_semaphore *sem)
  {
...
	waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
	list_del(&waiter->list);

The sem->wait_list is non-NULL, but the 'sem->wait_list.next' is NULL. I
would suggest you try with 'DEBUG_LOCK_ALLOC' or something like this.
The crash points are not the failure, it is when we insert a
rw_semaphore of 'NULL' or use some memory that is already freed.

Fwiw,
Bill Pringlemeir.

^ permalink raw reply

* [PATCH] regulator: core: Make regulator object reflect configured voltage
From: Mark Brown @ 2014-02-04 20:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJAp7Ohn3ch2nK_S8j9ieRBzNeyt6OJmumEhRXXykB9RgMJsQg@mail.gmail.com>

On Tue, Feb 04, 2014 at 11:09:03AM -0800, Bjorn Andersson wrote:

> I have a regulator that's being configured from DT as:
> regulator-min-microvolt = <2950000>;
> regulator-max-microvolt = <2950000>;

> In the consumer I do regulator_set_voltage(2.95V).

> As min == max the voltage is applied by the regulator framework on registration
> of the regulator; and the regulator_set_voltage() fails as
> REGULATOR_CHANGE_VOLTAGE is not set for this regulator.

So we should be changing the code to allow a set_voltage() that sets the
voltage to the existing voltage regardless of constraints allowing a
change then - that's what the underlying issue is.  Your change wouldn't
cover the case where the hardware defualt is being used for example.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/0f13e826/attachment-0001.sig>

^ permalink raw reply

* [PATCH] ARM: ux500: disable msp2 device tree node
From: Linus Walleij @ 2014-02-04 20:06 UTC (permalink / raw)
  To: linux-arm-kernel

Commit 70b41abc151f9
"ARM: ux500: move MSP pin control to the device tree"
accidentally activated MSP2, giving rise to a boot scroll
scream as the kernel attempts to probe a driver for it and
fails to obtain DMA channel 14.

Fix this up by marking the node disabled again.

Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/ste-href.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 0c1e8d871ed1..6cb9b68e2188 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -188,7 +188,6 @@
 		msp2: msp at 80117000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&msp2_default_mode>;
-			status = "okay";
 		};
 
 		msp3: msp at 80125000 {
-- 
1.8.5.3

^ permalink raw reply related

* UBI leb_write_unlock NULL pointer Oops (continuation) on ARM926
From: Richard Weinberger @ 2014-02-04 20:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87ha8e3b34.fsf@nbsps.com>

Am 04.02.2014 20:57, schrieb Bill Pringlemeir:
> On  4 Feb 2014, bpringlemeir at nbsps.com wrote:
> 
>> http://lists.infradead.org/pipermail/linux-mtd/2013-May/046907.html
>>
>> at91sam9g20 - arm926, different MTD driver. Linux 3.6.9
>>
>> Code: e5903004 e58d2004 e1560003 0a00002a (e593200c)
>>
>> 0:   e5903004        ldr     r3, [r0, #4]
>> 4:   e58d2004        str     r2, [sp, #4]
>> 8:   e1560003        cmp     r6, r3
>> c:   0a00002a        beq     0xbc
>> 10:   e593200c        ldr     r2, [r3, #12]
>>
>> The code sequence looks identical and the Oops trace, etc is the same.
>> People from Pengutronix also indicated seeing the same type of Opps; I
>> think they deal with the IMX, but maybe this was on another board.
> 
>>>>> schrieb Wiedemer, Thorsten (Lawo AG):
> 
>> Ehmm, OK, OK, even with the changes in kernel, ubi_assert() in
>> leb_write_unlock() wouldn't have triggered ...
> 
> Another up_read() crash,
> 
>  http://lists.infradead.org/pipermail/linux-mtd/2013-July/047512.html
> 
>  Code: e1530001 0a000016 e3e01000 e5801000 (e8930003)
> 
>  00000000 <.data>:
>     0:   e1530001        cmp     r3, r1
>     4:   0a000016        beq     0x64
>     8:   e3e01000        mvn     r1, #0
>     c:   e5801000        str     r1, [r0]
>    10:   e8930003        ldm     r3, {r0, r1}
> 
> Thorsten's Oops,
> 
>  Code: e3e02000 e5842000 e59fc084 e59f0084 (e8930006)
> 
>  00000000 <.data>:
>     0:   e3e02000        mvn     r2, #0
>     4:   e5842000        str     r2, [r4]
>     8:   e59fc084        ldr     ip, [pc, #132]  ; 0x94
>     c:   e59f0084        ldr     r0, [pc, #132]  ; 0x98
>    10:   e8930006        ldm     r3, {r1, r2}
> 
> The registers are different, but the instruction sequence is similar.
> In my ARM926 build, the __up_read() is,
> 
> static inline int list_empty(const struct list_head *head)
> {
>         return head->next == head;
>  250:   e1a01000        mov     r1, r0
>  254:   e5b12004        ldr     r2, [r1, #4]!
>  258:   e1520001        cmp     r2, r1
>  25c:   0a000017        beq     2c0 <__up_read+0xb0>
> __rwsem_wake_one_writer(struct rw_semaphore *sem)
> {
>         struct rwsem_waiter *waiter;
>         struct task_struct *tsk;
> 
>         sem->activity = -1;
>  260:   e3e01000        mvn     r1, #0
>  264:   e5801000        str     r1, [r0]
>  * in an undefined state.
>  */
> #ifndef CONFIG_DEBUG_LIST
> static inline void list_del(struct list_head *entry)
> {
>         __list_del(entry->prev, entry->next);
>  268:   e8920003        ldm     r2, {r0, r1}
>  * This is only for internal list manipulation where we know
>  * the prev/next entries already!
>  */
> static inline void __list_del(struct list_head * prev, struct list_head * next)
> {
>         next->prev = prev;
>  26c:   e5801004        str     r1, [r0, #4]
>         prev->next = next;
>  270:   e5810000        str     r0, [r1]
> 
> 
> This is the same symptom,
> 
>   __rwsem_wake_one_writer(struct rw_semaphore *sem)
>   {
> ...
> 	waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
> 	list_del(&waiter->list);
> 
> The sem->wait_list is non-NULL, but the 'sem->wait_list.next' is NULL. I
> would suggest you try with 'DEBUG_LOCK_ALLOC' or something like this.
> The crash points are not the failure, it is when we insert a
> rw_semaphore of 'NULL' or use some memory that is already freed.

CONFIG_DEBUG_LIST please.

Thanks,
//richard

^ permalink raw reply

* [PATCH 0/4] clk: mvebu: fix clk init order
From: Thomas Petazzoni @ 2014-02-04 20:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F10024.4030201@free-electrons.com>

Hello,

On Tue, 04 Feb 2014 15:58:44 +0100, Gregory CLEMENT wrote:

> > @Jason, Andrew, Gregory, Thomas:
> > Now that v3.14 is out, anything against taking this in as fixes for rc1?
> 
> I am not found of this solution I still think it should be done
> at framework level. However we still have this very annoying issue,
> and this fix is better than nothing. So I am not against taking this
> for rc1 with the hope that it will be later revert with a better
> solution.

Same opinion here. I'm fine with this solution as a temporary measure,
but it would be good to solve this problem in a nicer way. Also, making
this change doesn't impact the DT in any way, there is no problem in
having a temporary not perfect solution, and improve it later on.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v5 4/6] spmi: pmic_arb: add support for interrupt handling
From: Thomas Gleixner @ 2014-02-04 20:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391468739-20987-5-git-send-email-joshc@codeaurora.org>

On Mon, 3 Feb 2014, Josh Cartwright wrote:
> +static void qpnpint_irq_ack(struct irq_data *d)
> +{
> +	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
> +	u8 irq  = d->hwirq >> 8;
> +	u8 apid = d->hwirq;
> +	unsigned long flags;
> +	u8 data;
> +
> +	spin_lock_irqsave(&pa->lock, flags);

This wants to be a raw_spinlock - think about RT!

Looks sane otherwise.

Thanks,

	tglx

^ permalink raw reply

* Extending OPP bindings
From: Mark Brown @ 2014-02-04 20:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F13F54.5060000@ti.com>

On Tue, Feb 04, 2014 at 01:28:20PM -0600, Nishanth Menon wrote:
> On 02/04/2014 12:22 PM, Mark Brown wrote:

> > You're assuming that the frequency is a unique key here.  That may not
> > be the case, for example two OPPs might have the same CPU clock
> > (assuming that's the frequency you're referring to) but different bus
> > clocking and of course the CPUs or CPU clusters might be individually
> > scalable (this is common in big.LITTLE designs I think).

> Which is why OPPs are maintained per device, bus OPPs belong to bus
> device (in TI terminology, we'd be talking of cross domain dependency
> here for maintaining asynchronous bridge timing closure constraints -
> but ofcourse, other SoCs may or maynot have such constraints). For
> scaling bus frequency, we already have infrastructure in place - clock
> notifiers - discussion of using that is much deeper topic of it's own.

> for each processor that is uniquely transitioning, we'd have it's own
> sets of OPPs - the correct representation of the device node is the
> key there.

I've seen some SoCs characterised over the whole device rather than with
individual parts of the SoC done separately.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140204/90067f8e/attachment.sig>

^ permalink raw reply

* [PATCH v4 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Thomas Gleixner @ 2014-02-04 20:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F11B5C.40407@ti.com>

On Tue, 4 Feb 2014, Ivan Khoronzhuk wrote:

Please do not top post.

> It was so in v1. But it was decided to use explicit memory barriers,
> because we're always sure the memory barriers are there and that
> they're properly documented. Also in this case I don't need to add
> keystone readl/writel relaxed function variants and to use mixed calls of
> writel/writel_relaxed functions.
> 
> See:
> http://www.spinics.net/lists/arm-kernel/msg294941.html

Fair enough, but we want a proper explanation for explicit barriers in
the code and not in some random discussion of patch version X on some
random mailing list.

Aside of that it should be iowmb(), but I might miss something ...

Thanks,

	tglx

^ permalink raw reply

* [PATCH] pinctrl: single: add low powr mode support
From: Linus Walleij @ 2014-02-04 20:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390893644-3458-1-git-send-email-chao.xie@marvell.com>

On Tue, Jan 28, 2014 at 8:20 AM, Chao Xie <chao.xie@marvell.com> wrote:

> From: Chao Xie <chao.xie@marvell.com>
>
> For some silicons, the pin configuration register can control
> the output of the pin when the pad including the pin enter
> low power mode.
> For example, the pin can be "Drive 1", "Drive 0", "Float" when
> the pad including the pin enter low power mode.
> It is very useful when you want to control the power leakeage
> when the SOC enter low power mode, and can save more power for
> the low power mode.
>
> Signed-off-by: Chao Xie <chao.xie@marvell.com>

Looks similar to the other pin config stuff, patch applied
unless Tony protests.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH] ARM: enable IRQs in user undefined instruction vector
From: Kevin Bracey @ 2014-02-04 20:19 UTC (permalink / raw)
  To: linux-arm-kernel

If an abort occurs while loading an instruction from user space in
__und_usr, the resulting do_page_fault() can output "sleeping function
called from invalid context" warnings, due to IRQs being disabled in
__und_usr, and hence in do_page_fault().

Avoid the problem by enabling IRQs in __und_usr before attempting to
load the instruction, and modify code and comments in the undefined
instruction handlers to note that IRQs are enabled on entry iff the
instruction was executed in user mode.

See http://comments.gmane.org/gmane.linux.ports.arm.omap/59256 for
an earlier report of the observed might_sleep() warning.

The proposed patch in that thread, which adds a "!irqs_disabled()" test
to do_page_fault(), has already been applied to Android, but that patch
causes an execution failure if another CPU ages the page between the
instruction execution and __und_usr; it prevents do_page_fault() from
attempting to handle the fault and __und_usr's fixup handler is called
instead, but the fixup handler just continues execution from the next
instruction, so the original instruction is silently skipped.

This patch modifies the fixup handler to attempt to re-execute the
original instruction, bringing it in line with the SWI fixup handler;
this also avoids the possibility of the instruction being skipped if
do_page_fault() doesn't handle a fault.

Signed-off-by: Kevin Bracey <kevin@bracey.fi>
---
 arch/arm/kernel/entry-armv.S       | 11 ++++++++---
 arch/arm/mach-ep93xx/crunch-bits.S |  7 ++++++-
 arch/arm/vfp/entry.S               |  2 +-
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index b3fb8c9..bed1567 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -399,6 +399,7 @@ ENDPROC(__irq_usr)
 	.align	5
 __und_usr:
 	usr_entry
+	enable_irq
 
 	mov	r2, r4
 	mov	r3, r5
@@ -478,11 +479,14 @@ __und_usr_thumb:
 ENDPROC(__und_usr)
 
 /*
- * The out of line fixup for the ldrt instructions above.
+ * The out of line fixup for the ldrt instructions above. Called when there
+ * was an unrecoverable fault accessing the instruction. Attempt to re-execute
+ * the instruction, which should trigger the user fault handling path.
  */
 	.pushsection .fixup, "ax"
 	.align	2
-4:	mov	pc, r9
+4:	str	r4, [sp, #S_PC]
+	mov	pc, r9
 	.popsection
 	.pushsection __ex_table,"a"
 	.long	1b, 4b
@@ -515,7 +519,8 @@ ENDPROC(__und_usr)
  *  r9  = normal "successful" return address
  *  r10 = this threads thread_info structure
  *  lr  = unrecognised instruction return address
- * IRQs disabled, FIQs enabled.
+ * IRQs enabled iff the instruction was executed in user mode.
+ * FIQs enabled.
  */
 	@
 	@ Fall-through from Thumb-2 __und_usr
diff --git a/arch/arm/mach-ep93xx/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S
index 0ec9bb4..413d46c 100644
--- a/arch/arm/mach-ep93xx/crunch-bits.S
+++ b/arch/arm/mach-ep93xx/crunch-bits.S
@@ -62,9 +62,14 @@
  * r9  = ret_from_exception
  * lr  = undefined instr exit
  *
- * called from prefetch exception handler with interrupts disabled
+ * Called from undefined instruction handler.
+ * Interrupts enabled iff instruction executed in user mode.
  */
 ENTRY(crunch_task_enable)
+	mrs	r1, cpsr
+	orr	r2, r1, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
 	ldr	r8, =(EP93XX_APB_VIRT_BASE + 0x00130000)	@ syscon addr
 
 	ldr	r1, [r8, #0x80]
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 46e1749..e0e3a00 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -19,7 +19,7 @@
 @  r9  = normal "successful" return address
 @  r10 = this threads thread_info structure
 @  lr  = unrecognised instruction return address
-@  IRQs disabled.
+@  IRQs enabled iff the instruction was executed in user mode.
 @
 ENTRY(do_vfp)
 #ifdef CONFIG_PREEMPT_COUNT
-- 
1.8.4.dirty

^ permalink raw reply related

* [PATCH] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Ludovic Desroches @ 2014-02-04 20:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391535767-30749-1-git-send-email-nicolas.ferre@atmel.com>

On Tue, Feb 04, 2014 at 06:42:47PM +0100, Nicolas Ferre wrote:
> Add DT file for new SAMA5D3 Xpained board.
> This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.
> 

You may also add the board to the Makefile.

Ludovic

> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
>  1 file changed, 233 insertions(+)
>  create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts
> 
> diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
> new file mode 100644
> index 000000000000..fb1349ca60a4
> --- /dev/null
> +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
> @@ -0,0 +1,233 @@
> +/*
> + * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
> + *
> + *  Copyright (C) 2014 Atmel,
> + *		  2014 Nicolas Ferre <nicolas.ferre@atmel.com>
> + *
> + * Licensed under GPLv2 or later.
> + */
> +/dts-v1/;
> +#include "sama5d36.dtsi"
> +
> +/ {
> +	model = "SAMA5D3 Xplained";
> +	compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200";
> +	};
> +
> +	memory {
> +		reg = <0x20000000 0x10000000>;
> +	};
> +
> +	ahb {
> +		apb {
> +			mmc0: mmc at f0000000 {
> +				pinctrl-names = "default";
> +				pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
> +				status = "okay";
> +				slot at 0 {
> +					reg = <0>;
> +					bus-width = <8>;
> +					cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
> +				};
> +			};
> +
> +			spi0: spi at f0004000 {
> +				cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
> +				status = "okay";
> +			};
> +
> +			can0: can at f000c000 {
> +				status = "okay";
> +			};
> +
> +			i2c0: i2c at f0014000 {
> +				status = "okay";
> +			};
> +
> +			i2c1: i2c at f0018000 {
> +				status = "okay";
> +			};
> +
> +			macb0: ethernet at f0028000 {
> +				phy-mode = "rgmii";
> +				status = "okay";
> +			};
> +
> +			usart0: serial at f001c000 {
> +				status = "okay";
> +			};
> +
> +			usart1: serial at f0020000 {
> +				pinctrl-names = "default";
> +				pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
> +				status = "okay";
> +			};
> +
> +			uart0: serial at f0024000 {
> +				status = "okay";
> +			};
> +
> +			mmc1: mmc at f8000000 {
> +				pinctrl-names = "default";
> +				pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
> +				status = "okay";
> +				slot at 0 {
> +					reg = <0>;
> +					bus-width = <4>;
> +					cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
> +				};
> +			};
> +
> +			spi1: spi at f8008000 {
> +				cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
> +				status = "okay";
> +			};
> +
> +			adc0: adc at f8018000 {
> +				pinctrl-names = "default";
> +				pinctrl-0 = <
> +					&pinctrl_adc0_adtrg
> +					&pinctrl_adc0_ad0
> +					&pinctrl_adc0_ad1
> +					&pinctrl_adc0_ad2
> +					&pinctrl_adc0_ad3
> +					&pinctrl_adc0_ad4
> +					&pinctrl_adc0_ad5
> +					&pinctrl_adc0_ad6
> +					&pinctrl_adc0_ad7
> +					&pinctrl_adc0_ad8
> +					&pinctrl_adc0_ad9
> +					>;
> +				status = "okay";
> +			};
> +
> +			i2c2: i2c at f801c000 {
> +				dmas = <0>, <0>;	/* Do not use DMA for i2c2 */
> +				status = "okay";
> +			};
> +
> +			macb1: ethernet at f802c000 {
> +				phy-mode = "rmii";
> +				status = "okay";
> +			};
> +
> +			dbgu: serial at ffffee00 {
> +				status = "okay";
> +			};
> +
> +			pinctrl at fffff200 {
> +				board {
> +					pinctrl_mmc0_cd: mmc0_cd {
> +						atmel,pins =
> +							<AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
> +					};
> +
> +					pinctrl_mmc1_cd: mmc1_cd {
> +						atmel,pins =
> +							<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
> +					};
> +
> +					pinctrl_usba_vbus: usba_vbus {
> +						atmel,pins =
> +							<AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;	/* PE9, conflicts with A9 */
> +					};
> +				};
> +			};
> +
> +			pmc: pmc at fffffc00 {
> +				main: mainck {
> +					clock-frequency = <12000000>;
> +				};
> +			};
> +		};
> +
> +		nand0: nand at 60000000 {
> +			nand-bus-width = <8>;
> +			nand-ecc-mode = "hw";
> +			atmel,has-pmecc;
> +			atmel,pmecc-cap = <4>;
> +			atmel,pmecc-sector-size = <512>;
> +			nand-on-flash-bbt;
> +			status = "okay";
> +
> +			at91bootstrap at 0 {
> +				label = "at91bootstrap";
> +				reg = <0x0 0x40000>;
> +			};
> +
> +			bootloader at 40000 {
> +				label = "bootloader";
> +				reg = <0x40000 0x80000>;
> +			};
> +
> +			bootloaderenv at c0000 {
> +				label = "bootloader env";
> +				reg = <0xc0000 0xc0000>;
> +			};
> +
> +			dtb at 180000 {
> +				label = "device tree";
> +				reg = <0x180000 0x80000>;
> +			};
> +
> +			kernel at 200000 {
> +				label = "kernel";
> +				reg = <0x200000 0x600000>;
> +			};
> +
> +			rootfs at 800000 {
> +				label = "rootfs";
> +				reg = <0x800000 0x0f800000>;
> +			};
> +		};
> +
> +		usb0: gadget at 00500000 {
> +			atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>;	/* PE9, conflicts with A9 */
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usba_vbus>;
> +			status = "okay";
> +		};
> +
> +		usb1: ohci at 00600000 {
> +			num-ports = <3>;
> +			atmel,vbus-gpio = <0
> +					   &pioE 3 GPIO_ACTIVE_LOW
> +					   &pioE 4 GPIO_ACTIVE_LOW
> +					  >;
> +			status = "okay";
> +		};
> +
> +		usb2: ehci at 00700000 {
> +			status = "okay";
> +		};
> +	};
> +
> +	gpio_keys {
> +		compatible = "gpio-keys";
> +
> +		bp3 {
> +			label = "PB_USER";
> +			gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
> +			linux,code = <0x104>;
> +			gpio-key,wakeup;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		d2 {
> +			label = "d2";
> +			gpios = <&pioE 23 GPIO_ACTIVE_LOW>;	/* PE23, conflicts with A23, CTS2 */
> +			linux,default-trigger = "heartbeat";
> +		};
> +
> +		d3 {
> +			label = "d3";
> +			gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> -- 
> 1.8.2.2
> 

^ permalink raw reply

* [PATCH] ARM: ux500: disable msp2 device tree node
From: Lee Jones @ 2014-02-04 20:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391544372-16863-1-git-send-email-linus.walleij@linaro.org>

On Tue, 04 Feb 2014, Linus Walleij wrote:

> Commit 70b41abc151f9
> "ARM: ux500: move MSP pin control to the device tree"
> accidentally activated MSP2, giving rise to a boot scroll
> scream as the kernel attempts to probe a driver for it and
> fails to obtain DMA channel 14.
> 
> Fix this up by marking the node disabled again.
> 
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  arch/arm/boot/dts/ste-href.dtsi | 1 -
>  1 file changed, 1 deletion(-)

Acked-by: Lee Jones <lee.jones@linaro.org>

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

^ permalink raw reply

* [PATCH v3 5/7] clocksource/cadence_ttc: Use only one counter
From: Thomas Gleixner @ 2014-02-04 20:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391466877-28908-6-git-send-email-soren.brinkmann@xilinx.com>

On Mon, 3 Feb 2014, Soren Brinkmann wrote:

> Currently the driver uses two of the three counters the TTC provides to
> implement a clocksource and a clockevent device. By using the TTC's
> match feature we can implement both use cases using a single counter
> only.

Are you entirely sure that this match feature is free of the infamous
HPET match feature issues?

See arch/x86/kernel/hpet.c: hpet_next_event()

If yes, please add a comment. If no ....

Thanks,

	tglx

^ permalink raw reply

* [Patch v5 0/2] Add Qualcomm BAM dmaengine driver
From: Andy Gross @ 2014-02-04 20:42 UTC (permalink / raw)
  To: linux-arm-kernel

This patch set introduces the dmaengine driver for the Qualcomm Bus Access
Manager (BAM) DMA controller present on MSM 8x74 devices.  A number of the
on-chip devices have their own BAM DMA controller and use it to move data
between system memory and peripherals or between two peripherals.

The initial version of this driver will only support slave DMA operations
between system memory and peripherals.

Changes from v4:
	- Add devm_free_irq() to .remove to avoid race condition
	- Free FIFO memory in .remove

Changes from v3:
        - Remove unused bam_channel_dir.
        - Remove incorrect write to BAM_IRQ_SRCS_EE (read only).
        - Remove dma direction from DT binding and revise driver to use
          direction from prep_slave_sg.
        - Remove unnecessary channel reset from channel_init.  This could affect
          channels controlled from other execution environments.
        - Change terminate_all to also take care of the current active
          descriptor.
        - Rework .remove function to correctly mask interrupts and clean up
          resources and tasklets.

Changes from v2:
        - Corrected Kconfig dependencies
        - Moved execution environment ID to controller DT binding.  The EE is
          a global setting across all of the channels on the controller.
        - Combined header into source file.
        - Corrected copyright date.
        - Moved channel hardware initialization to occur when channel is used
          for the first time.
        - Converted dma_alloc_coherent to dma_alloc_writecombine
        - Removed unecessary reset of channel from the dma terminate_all
        - Corrected usage of EE in irq handler and channel configuration
          functions.
        - Changed resource functions inside probe to use correct APIs.
        - Removed dma filter function and modified dma_xlate to use
          dma_get_slave_channel API
        - Fixed various nit comments

Changes from v1:
        - Converted driver to use virt-dma
        - Reworked probe function per review comments
        - tx_status function now computes and returns residuals
        - Removed proprietary slave config.  Removed associated include file.
        - Renamed files to reflect vendor name instead of specific device
        - Converted to use (readl|writel)_relaxed w/ appropriate barriers
        - Removed unions in favor of standard types.

Andy Gross (2):
  dmaengine: add Qualcomm BAM dma driver
  dmaengine: qcom_bam_dma: Add device tree binding

 .../devicetree/bindings/dma/qcom_bam_dma.txt       |   48 +
 drivers/dma/Kconfig                                |    9 +
 drivers/dma/Makefile                               |    1 +
 drivers/dma/qcom_bam_dma.c                         | 1066 ++++++++++++++++++++
 4 files changed, 1124 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
 create mode 100644 drivers/dma/qcom_bam_dma.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [Patch v5 1/2] dmaengine: add Qualcomm BAM dma driver
From: Andy Gross @ 2014-02-04 20:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391546556-27702-1-git-send-email-agross@codeaurora.org>

Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
found in the MSM 8x74 platforms.

Each BAM DMA device is associated with a specific on-chip peripheral.  Each
channel provides a uni-directional data transfer engine that is capable of
transferring data between the peripheral and system memory (System mode), or
between two peripherals (BAM2BAM).

The initial release of this driver only supports slave transfers between
peripherals and system memory.

Signed-off-by: Andy Gross <agross@codeaurora.org>
---
 drivers/dma/Kconfig        |    9 +
 drivers/dma/Makefile       |    1 +
 drivers/dma/qcom_bam_dma.c | 1066 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1076 insertions(+)
 create mode 100644 drivers/dma/qcom_bam_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index c10eb89..1b2f6cf 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -386,4 +386,13 @@ config DMATEST
 config DMA_ENGINE_RAID
 	bool
 
+config QCOM_BAM_DMA
+	tristate "QCOM BAM DMA support"
+	depends on ARCH_MSM_DT || (COMPILE_TEST && OF && ARM)
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	---help---
+	  Enable support for the QCOM BAM DMA controller.  This controller
+	  provides DMA capabilities for a variety of on-chip devices.
+
 endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 0ce2da9..7ef950a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
 obj-$(CONFIG_TI_CPPI41) += cppi41.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
+obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
new file mode 100644
index 0000000..214250c
--- /dev/null
+++ b/drivers/dma/qcom_bam_dma.c
@@ -0,0 +1,1066 @@
+/*
+ * QCOM BAM DMA engine driver
+ *
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * QCOM BAM DMA blocks are distributed amongst a number of the on-chip
+ * peripherals on the MSM 8x74.  The configuration of the channels are dependent
+ * on the way they are hard wired to that specific peripheral.  The peripheral
+ * device tree entries specify the configuration of each channel.
+ *
+ * The DMA controller requires the use of external memory for storage of the
+ * hardware descriptors for each channel.  The descriptor FIFO is accessed as a
+ * circular buffer and operations are managed according to the offset within the
+ * FIFO.  After pipe/channel reset, all of the pipe registers and internal state
+ * are back to defaults.
+ *
+ * During DMA operations, we write descriptors to the FIFO, being careful to
+ * handle wrapping and then write the last FIFO offset to that channel's
+ * P_EVNT_REG register to kick off the transaction.  The P_SW_OFSTS register
+ * indicates the current FIFO offset that is being processed, so there is some
+ * indication of where the hardware is currently working.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_dma.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+struct bam_desc_hw {
+	u32 addr;		/* Buffer physical address */
+	u16 size;		/* Buffer size in bytes */
+	u16 flags;
+};
+
+#define DESC_FLAG_INT BIT(15)
+#define DESC_FLAG_EOT BIT(14)
+#define DESC_FLAG_EOB BIT(13)
+
+struct bam_async_desc {
+	struct virt_dma_desc vd;
+
+	u32 num_desc;
+	u32 xfer_len;
+	struct bam_desc_hw *curr_desc;
+
+	enum dma_transfer_direction dir;
+	size_t length;
+	struct bam_desc_hw desc[0];
+};
+
+#define BAM_CTRL			0x0000
+#define BAM_REVISION			0x0004
+#define BAM_SW_REVISION			0x0080
+#define BAM_NUM_PIPES			0x003C
+#define BAM_TIMER			0x0040
+#define BAM_TIMER_CTRL			0x0044
+#define BAM_DESC_CNT_TRSHLD		0x0008
+#define BAM_IRQ_SRCS			0x000C
+#define BAM_IRQ_SRCS_MSK		0x0010
+#define BAM_IRQ_SRCS_UNMASKED		0x0030
+#define BAM_IRQ_STTS			0x0014
+#define BAM_IRQ_CLR			0x0018
+#define BAM_IRQ_EN			0x001C
+#define BAM_CNFG_BITS			0x007C
+#define BAM_IRQ_SRCS_EE(pipe)		(0x0800 + ((pipe) * 0x80))
+#define BAM_IRQ_SRCS_MSK_EE(pipe)	(0x0804 + ((pipe) * 0x80))
+#define BAM_P_CTRL(pipe)		(0x1000 + ((pipe) * 0x1000))
+#define BAM_P_RST(pipe)			(0x1004 + ((pipe) * 0x1000))
+#define BAM_P_HALT(pipe)		(0x1008 + ((pipe) * 0x1000))
+#define BAM_P_IRQ_STTS(pipe)		(0x1010 + ((pipe) * 0x1000))
+#define BAM_P_IRQ_CLR(pipe)		(0x1014 + ((pipe) * 0x1000))
+#define BAM_P_IRQ_EN(pipe)		(0x1018 + ((pipe) * 0x1000))
+#define BAM_P_EVNT_DEST_ADDR(pipe)	(0x182C + ((pipe) * 0x1000))
+#define BAM_P_EVNT_REG(pipe)		(0x1818 + ((pipe) * 0x1000))
+#define BAM_P_SW_OFSTS(pipe)		(0x1800 + ((pipe) * 0x1000))
+#define BAM_P_DATA_FIFO_ADDR(pipe)	(0x1824 + ((pipe) * 0x1000))
+#define BAM_P_DESC_FIFO_ADDR(pipe)	(0x181C + ((pipe) * 0x1000))
+#define BAM_P_EVNT_TRSHLD(pipe)		(0x1828 + ((pipe) * 0x1000))
+#define BAM_P_FIFO_SIZES(pipe)		(0x1820 + ((pipe) * 0x1000))
+
+/* BAM CTRL */
+#define BAM_SW_RST			BIT(0)
+#define BAM_EN				BIT(1)
+#define BAM_EN_ACCUM			BIT(4)
+#define BAM_TESTBUS_SEL_SHIFT		5
+#define BAM_TESTBUS_SEL_MASK		0x3F
+#define BAM_DESC_CACHE_SEL_SHIFT	13
+#define BAM_DESC_CACHE_SEL_MASK		0x3
+#define BAM_CACHED_DESC_STORE		BIT(15)
+#define IBC_DISABLE			BIT(16)
+
+/* BAM REVISION */
+#define REVISION_SHIFT		0
+#define REVISION_MASK		0xFF
+#define NUM_EES_SHIFT		8
+#define NUM_EES_MASK		0xF
+#define CE_BUFFER_SIZE		BIT(13)
+#define AXI_ACTIVE		BIT(14)
+#define USE_VMIDMT		BIT(15)
+#define SECURED			BIT(16)
+#define BAM_HAS_NO_BYPASS	BIT(17)
+#define HIGH_FREQUENCY_BAM	BIT(18)
+#define INACTIV_TMRS_EXST	BIT(19)
+#define NUM_INACTIV_TMRS	BIT(20)
+#define DESC_CACHE_DEPTH_SHIFT	21
+#define DESC_CACHE_DEPTH_1	(0 << DESC_CACHE_DEPTH_SHIFT)
+#define DESC_CACHE_DEPTH_2	(1 << DESC_CACHE_DEPTH_SHIFT)
+#define DESC_CACHE_DEPTH_3	(2 << DESC_CACHE_DEPTH_SHIFT)
+#define DESC_CACHE_DEPTH_4	(3 << DESC_CACHE_DEPTH_SHIFT)
+#define CMD_DESC_EN		BIT(23)
+#define INACTIV_TMR_BASE_SHIFT	24
+#define INACTIV_TMR_BASE_MASK	0xFF
+
+/* BAM NUM PIPES */
+#define BAM_NUM_PIPES_SHIFT		0
+#define BAM_NUM_PIPES_MASK		0xFF
+#define PERIPH_NON_PIPE_GRP_SHIFT	16
+#define PERIPH_NON_PIP_GRP_MASK		0xFF
+#define BAM_NON_PIPE_GRP_SHIFT		24
+#define BAM_NON_PIPE_GRP_MASK		0xFF
+
+/* BAM CNFG BITS */
+#define BAM_PIPE_CNFG		BIT(2)
+#define BAM_FULL_PIPE		BIT(11)
+#define BAM_NO_EXT_P_RST	BIT(12)
+#define BAM_IBC_DISABLE		BIT(13)
+#define BAM_SB_CLK_REQ		BIT(14)
+#define BAM_PSM_CSW_REQ		BIT(15)
+#define BAM_PSM_P_RES		BIT(16)
+#define BAM_AU_P_RES		BIT(17)
+#define BAM_SI_P_RES		BIT(18)
+#define BAM_WB_P_RES		BIT(19)
+#define BAM_WB_BLK_CSW		BIT(20)
+#define BAM_WB_CSW_ACK_IDL	BIT(21)
+#define BAM_WB_RETR_SVPNT	BIT(22)
+#define BAM_WB_DSC_AVL_P_RST	BIT(23)
+#define BAM_REG_P_EN		BIT(24)
+#define BAM_PSM_P_HD_DATA	BIT(25)
+#define BAM_AU_ACCUMED		BIT(26)
+#define BAM_CMD_ENABLE		BIT(27)
+
+#define BAM_CNFG_BITS_DEFAULT	(BAM_PIPE_CNFG |	\
+				 BAM_NO_EXT_P_RST |	\
+				 BAM_IBC_DISABLE |	\
+				 BAM_SB_CLK_REQ |	\
+				 BAM_PSM_CSW_REQ |	\
+				 BAM_PSM_P_RES |	\
+				 BAM_AU_P_RES |		\
+				 BAM_SI_P_RES |		\
+				 BAM_WB_P_RES |		\
+				 BAM_WB_BLK_CSW |	\
+				 BAM_WB_CSW_ACK_IDL |	\
+				 BAM_WB_RETR_SVPNT |	\
+				 BAM_WB_DSC_AVL_P_RST |	\
+				 BAM_REG_P_EN |		\
+				 BAM_PSM_P_HD_DATA |	\
+				 BAM_AU_ACCUMED |	\
+				 BAM_CMD_ENABLE)
+
+/* PIPE CTRL */
+#define	P_EN			BIT(1)
+#define P_DIRECTION		BIT(3)
+#define P_SYS_STRM		BIT(4)
+#define P_SYS_MODE		BIT(5)
+#define P_AUTO_EOB		BIT(6)
+#define P_AUTO_EOB_SEL_SHIFT	7
+#define P_AUTO_EOB_SEL_512	(0 << P_AUTO_EOB_SEL_SHIFT)
+#define P_AUTO_EOB_SEL_256	(1 << P_AUTO_EOB_SEL_SHIFT)
+#define P_AUTO_EOB_SEL_128	(2 << P_AUTO_EOB_SEL_SHIFT)
+#define P_AUTO_EOB_SEL_64	(3 << P_AUTO_EOB_SEL_SHIFT)
+#define P_PREFETCH_LIMIT_SHIFT	9
+#define P_PREFETCH_LIMIT_32	(0 << P_PREFETCH_LIMIT_SHIFT)
+#define P_PREFETCH_LIMIT_16	(1 << P_PREFETCH_LIMIT_SHIFT)
+#define P_PREFETCH_LIMIT_4	(2 << P_PREFETCH_LIMIT_SHIFT)
+#define P_WRITE_NWD		BIT(11)
+#define P_LOCK_GROUP_SHIFT	16
+#define P_LOCK_GROUP_MASK	0x1F
+
+/* BAM_DESC_CNT_TRSHLD */
+#define CNT_TRSHLD		0xffff
+#define DEFAULT_CNT_THRSHLD	0x4
+
+/* BAM_IRQ_SRCS */
+#define BAM_IRQ			BIT(31)
+#define P_IRQ			0x7fffffff
+
+/* BAM_IRQ_SRCS_MSK */
+#define BAM_IRQ_MSK		BAM_IRQ
+#define P_IRQ_MSK		P_IRQ
+
+/* BAM_IRQ_STTS */
+#define BAM_TIMER_IRQ		BIT(4)
+#define BAM_EMPTY_IRQ		BIT(3)
+#define BAM_ERROR_IRQ		BIT(2)
+#define BAM_HRESP_ERR_IRQ	BIT(1)
+
+/* BAM_IRQ_CLR */
+#define BAM_TIMER_CLR		BIT(4)
+#define BAM_EMPTY_CLR		BIT(3)
+#define BAM_ERROR_CLR		BIT(2)
+#define BAM_HRESP_ERR_CLR	BIT(1)
+
+/* BAM_IRQ_EN */
+#define BAM_TIMER_EN		BIT(4)
+#define BAM_EMPTY_EN		BIT(3)
+#define BAM_ERROR_EN		BIT(2)
+#define BAM_HRESP_ERR_EN	BIT(1)
+
+/* BAM_P_IRQ_EN */
+#define P_PRCSD_DESC_EN		BIT(0)
+#define P_TIMER_EN		BIT(1)
+#define P_WAKE_EN		BIT(2)
+#define P_OUT_OF_DESC_EN	BIT(3)
+#define P_ERR_EN		BIT(4)
+#define P_TRNSFR_END_EN		BIT(5)
+#define P_DEFAULT_IRQS_EN	(P_PRCSD_DESC_EN | P_ERR_EN | P_TRNSFR_END_EN)
+
+/* BAM_P_SW_OFSTS */
+#define P_SW_OFSTS_MASK		0xffff
+
+#define BAM_DESC_FIFO_SIZE	SZ_32K
+#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1)
+#define BAM_MAX_DATA_SIZE	(SZ_32K - 8)
+
+struct bam_chan {
+	struct virt_dma_chan vc;
+
+	struct bam_device *bdev;
+
+	/* configuration from device tree */
+	u32 id;
+	u32 ee;
+
+	struct bam_async_desc *curr_txd;	/* current running dma */
+
+	/* runtime configuration */
+	struct dma_slave_config slave;
+
+	/* fifo storage */
+	struct bam_desc_hw *fifo_virt;
+	dma_addr_t fifo_phys;
+
+	/* fifo markers */
+	unsigned short head;		/* start of active descriptor entries */
+	unsigned short tail;		/* end of active descriptor entries */
+
+	unsigned int initialized;	/* is the channel hw initialized? */
+	unsigned int paused;		/* is the channel paused? */
+
+	struct list_head node;
+};
+
+static inline struct bam_chan *to_bam_chan(struct dma_chan *common)
+{
+	return container_of(common, struct bam_chan, vc.chan);
+}
+
+struct bam_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct device_dma_parameters dma_parms;
+	struct bam_chan *channels;
+	u32 num_channels;
+
+	/* execution environment ID, from DT */
+	u32 ee;
+
+	struct clk *bamclk;
+	int irq;
+
+	/* dma start transaction tasklet */
+	struct tasklet_struct task;
+};
+
+/**
+ * bam_reset_channel - Reset individual BAM DMA channel
+ * @bchan: bam channel
+ *
+ * This function resets a specific BAM channel
+ */
+static void bam_reset_channel(struct bam_chan *bchan)
+{
+	struct bam_device *bdev = bchan->bdev;
+
+	/* reset channel */
+	writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id));
+	writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id));
+
+	/* don't allow reorder of the channel reset */
+	wmb();
+
+	/* make sure hw is initialized when channel is used the first time  */
+	bchan->initialized = 0;
+}
+
+/**
+ * bam_chan_init_hw - Initialize channel hardware
+ * @bchan: bam channel
+ *
+ * This function resets and initializes the BAM channel
+ */
+static void bam_chan_init_hw(struct bam_chan *bchan,
+	enum dma_transfer_direction dir)
+{
+	struct bam_device *bdev = bchan->bdev;
+	u32 val;
+
+	/* Reset the channel to clear internal state of the FIFO */
+	bam_reset_channel(bchan);
+
+	/*
+	 * write out 8 byte aligned address.  We have enough space for this
+	 * because we allocated 1 more descriptor (8 bytes) than we can use
+	 */
+	writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
+			bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id));
+	writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs +
+			BAM_P_FIFO_SIZES(bchan->id));
+
+	/* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
+	writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id));
+
+	/* unmask the specific pipe and EE combo */
+	val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
+	val |= BIT(bchan->id);
+	writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
+
+	/* set fixed direction and mode, then enable channel */
+	val = P_EN | P_SYS_MODE;
+	if (dir == DMA_DEV_TO_MEM)
+		val |= P_DIRECTION;
+
+	/* make sure the other stores occur before enabling channel */
+	wmb();
+	writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id));
+
+	bchan->initialized = 1;
+
+	/* init FIFO pointers */
+	bchan->head = 0;
+	bchan->tail = 0;
+}
+
+/**
+ * bam_alloc_chan - Allocate channel resources for DMA channel.
+ * @chan: specified channel
+ *
+ * This function allocates the FIFO descriptor memory
+ */
+static int bam_alloc_chan(struct dma_chan *chan)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	struct bam_device *bdev = bchan->bdev;
+
+	/* allocate FIFO descriptor space, but only if necessary */
+	if (!bchan->fifo_virt) {
+		bchan->fifo_virt = dma_alloc_writecombine(bdev->dev,
+					BAM_DESC_FIFO_SIZE, &bchan->fifo_phys,
+					GFP_KERNEL);
+
+		if (!bchan->fifo_virt) {
+			dev_err(bdev->dev, "Failed to allocate desc fifo\n");
+			return -ENOMEM;
+		}
+	}
+
+	return BAM_DESC_FIFO_SIZE;
+}
+
+/**
+ * bam_free_chan - Frees dma resources associated with specific channel
+ * @chan: specified channel
+ *
+ * Free the allocated fifo descriptor memory and channel resources
+ *
+ */
+static void bam_free_chan(struct dma_chan *chan)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	struct bam_device *bdev = bchan->bdev;
+	u32 val;
+
+	vchan_free_chan_resources(to_virt_chan(chan));
+
+	if (bchan->curr_txd) {
+		dev_err(bchan->bdev->dev, "Cannot free busy channel\n");
+		return;
+	}
+
+	bam_reset_channel(bchan);
+
+	dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt,
+				bchan->fifo_phys);
+	bchan->fifo_virt = NULL;
+
+	/* mask irq for pipe/channel */
+	val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
+	val &= ~BIT(bchan->id);
+	writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
+
+	/* disable irq */
+	writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id));
+}
+
+/**
+ * bam_slave_config - set slave configuration for channel
+ * @chan: dma channel
+ * @cfg: slave configuration
+ *
+ * Sets slave configuration for channel
+ *
+ */
+static void bam_slave_config(struct bam_chan *bchan,
+		struct dma_slave_config *cfg)
+{
+	struct bam_device *bdev = bchan->bdev;
+	u32 maxburst;
+
+	if (bchan->slave.direction == DMA_DEV_TO_MEM)
+		maxburst = bchan->slave.src_maxburst = cfg->src_maxburst;
+	else
+		maxburst = bchan->slave.dst_maxburst = cfg->dst_maxburst;
+
+	/* set desc threshold */
+	writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD);
+}
+
+/**
+ * bam_prep_slave_sg - Prep slave sg transaction
+ *
+ * @chan: dma channel
+ * @sgl: scatter gather list
+ * @sg_len: length of sg
+ * @direction: DMA transfer direction
+ * @flags: DMA flags
+ * @context: transfer context (unused)
+ */
+static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
+	struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction, unsigned long flags,
+	void *context)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	struct bam_device *bdev = bchan->bdev;
+	struct bam_async_desc *async_desc;
+	struct scatterlist *sg;
+	u32 i;
+	struct bam_desc_hw *desc;
+
+
+	if (!is_slave_direction(direction)) {
+		dev_err(bdev->dev, "invalid dma direction\n");
+		return NULL;
+	}
+
+
+	/* allocate enough room to accomodate the number of entries */
+	async_desc = kzalloc(sizeof(*async_desc) +
+			(sg_len * sizeof(struct bam_desc_hw)), GFP_NOWAIT);
+
+	if (!async_desc) {
+		dev_err(bdev->dev, "failed to allocate async descriptor\n");
+		goto err_out;
+	}
+
+	async_desc->num_desc = sg_len;
+	async_desc->curr_desc = async_desc->desc;
+	async_desc->dir = direction;
+
+	/* fill in descriptors, align hw descriptor to 8 bytes */
+	desc = async_desc->desc;
+	for_each_sg(sgl, sg, sg_len, i) {
+		if (sg_dma_len(sg) > BAM_MAX_DATA_SIZE) {
+			dev_err(bdev->dev, "segment exceeds max size\n");
+			goto err_out;
+		}
+
+		desc->addr = sg_dma_address(sg);
+		desc->size = sg_dma_len(sg);
+		async_desc->length += sg_dma_len(sg);
+		desc++;
+	}
+
+	return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags);
+
+err_out:
+	kfree(async_desc);
+	return NULL;
+}
+
+/**
+ * bam_dma_terminate_all - terminate all transactions on a channel
+ * @bchan: bam dma channel
+ *
+ * Dequeues and frees all transactions
+ * No callbacks are done
+ *
+ */
+static void bam_dma_terminate_all(struct bam_chan *bchan)
+{
+	unsigned long flag;
+	LIST_HEAD(head);
+
+	/* remove all transactions, including active transaction */
+	spin_lock_irqsave(&bchan->vc.lock, flag);
+	if (bchan->curr_txd) {
+		list_add(&bchan->curr_txd->vd.node, &bchan->vc.desc_issued);
+		bchan->curr_txd = NULL;
+	}
+
+	vchan_get_all_descriptors(&bchan->vc, &head);
+	spin_unlock_irqrestore(&bchan->vc.lock, flag);
+
+	vchan_dma_desc_free_list(&bchan->vc, &head);
+}
+
+/**
+ * bam_control - DMA device control
+ * @chan: dma channel
+ * @cmd: control cmd
+ * @arg: cmd argument
+ *
+ * Perform DMA control command
+ *
+ */
+static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+	unsigned long arg)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	struct bam_device *bdev = bchan->bdev;
+	int ret = 0;
+	unsigned long flag;
+
+	switch (cmd) {
+	case DMA_PAUSE:
+		spin_lock_irqsave(&bchan->vc.lock, flag);
+		writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id));
+		bchan->paused = 1;
+		spin_unlock_irqrestore(&bchan->vc.lock, flag);
+		break;
+	case DMA_RESUME:
+		spin_lock_irqsave(&bchan->vc.lock, flag);
+		writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id));
+		bchan->paused = 0;
+		spin_unlock_irqrestore(&bchan->vc.lock, flag);
+		break;
+	case DMA_TERMINATE_ALL:
+		bam_dma_terminate_all(bchan);
+		break;
+	case DMA_SLAVE_CONFIG:
+		bam_slave_config(bchan, (struct dma_slave_config *)arg);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * process_channel_irqs - processes the channel interrupts
+ * @bdev: bam controller
+ *
+ * This function processes the channel interrupts
+ *
+ */
+static u32 process_channel_irqs(struct bam_device *bdev)
+{
+	u32 i, srcs, pipe_stts;
+	unsigned long flags;
+	struct bam_async_desc *async_desc;
+
+	srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(bdev->ee));
+
+	/* return early if no pipe/channel interrupts are present */
+	if (!(srcs & P_IRQ))
+		return srcs;
+
+	for (i = 0; i < bdev->num_channels; i++) {
+		struct bam_chan *bchan = &bdev->channels[i];
+		if (srcs & BIT(i)) {
+			/* clear pipe irq */
+			pipe_stts = readl_relaxed(bdev->regs +
+				BAM_P_IRQ_STTS(i));
+
+			writel_relaxed(pipe_stts, bdev->regs +
+					BAM_P_IRQ_CLR(i));
+
+			spin_lock_irqsave(&bchan->vc.lock, flags);
+			async_desc = bchan->curr_txd;
+
+			if (async_desc) {
+				async_desc->num_desc -= async_desc->xfer_len;
+				async_desc->curr_desc += async_desc->xfer_len;
+				bchan->curr_txd = NULL;
+
+				/* manage FIFO */
+				bchan->head += async_desc->xfer_len;
+				bchan->head %= MAX_DESCRIPTORS;
+
+				/*
+				 * if complete, process cookie.  Otherwise
+				 * push back to front of desc_issued so that
+				 * it gets restarted by the tasklet
+				 */
+				if (!async_desc->num_desc)
+					vchan_cookie_complete(&async_desc->vd);
+				else
+					list_add(&async_desc->vd.node,
+						&bchan->vc.desc_issued);
+			}
+
+			spin_unlock_irqrestore(&bchan->vc.lock, flags);
+		}
+	}
+
+	return srcs;
+}
+
+/**
+ * bam_dma_irq - irq handler for bam controller
+ * @irq: IRQ of interrupt
+ * @data: callback data
+ *
+ * IRQ handler for the bam controller
+ */
+static irqreturn_t bam_dma_irq(int irq, void *data)
+{
+	struct bam_device *bdev = data;
+	u32 clr_mask = 0, srcs = 0;
+
+	srcs |= process_channel_irqs(bdev);
+
+	/* kick off tasklet to start next dma transfer */
+	if (srcs & P_IRQ)
+		tasklet_schedule(&bdev->task);
+
+	if (srcs & BAM_IRQ)
+		clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS);
+
+	/* don't allow reorder of the various accesses to the BAM registers */
+	mb();
+
+	writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * bam_tx_status - returns status of transaction
+ * @chan: dma channel
+ * @cookie: transaction cookie
+ * @txstate: DMA transaction state
+ *
+ * Return status of dma transaction
+ */
+static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+		struct dma_tx_state *txstate)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	struct virt_dma_desc *vd;
+	int ret;
+	size_t residue = 0;
+	unsigned int i;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE)
+		return ret;
+
+	if (!txstate)
+		return bchan->paused ? DMA_PAUSED : ret;
+
+	spin_lock_irqsave(&bchan->vc.lock, flags);
+	vd = vchan_find_desc(&bchan->vc, cookie);
+	if (vd)
+		residue = container_of(vd, struct bam_async_desc, vd)->length;
+	else if (bchan->curr_txd && bchan->curr_txd->vd.tx.cookie == cookie)
+		for (i = 0; i < bchan->curr_txd->num_desc; i++)
+			residue += bchan->curr_txd->curr_desc[i].size;
+
+	spin_unlock_irqrestore(&bchan->vc.lock, flags);
+
+	dma_set_residue(txstate, residue);
+
+	if (ret == DMA_IN_PROGRESS && bchan->paused)
+		ret = DMA_PAUSED;
+
+	return ret;
+}
+
+/**
+ * bam_start_dma - start next transaction
+ * @bchan - bam dma channel
+ *
+ * Note: must hold bam dma channel vc.lock
+ */
+static void bam_start_dma(struct bam_chan *bchan)
+{
+	struct virt_dma_desc *vd = vchan_next_desc(&bchan->vc);
+	struct bam_device *bdev = bchan->bdev;
+	struct bam_async_desc *async_desc;
+	struct bam_desc_hw *desc;
+	struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
+					sizeof(struct bam_desc_hw));
+
+	if (!vd)
+		return;
+
+	list_del(&vd->node);
+
+	async_desc = container_of(vd, struct bam_async_desc, vd);
+	bchan->curr_txd = async_desc;
+
+	/* on first use, initialize the channel hardware */
+	if (!bchan->initialized)
+		bam_chan_init_hw(bchan, async_desc->dir);
+
+
+	desc = bchan->curr_txd->curr_desc;
+
+	if (async_desc->num_desc > MAX_DESCRIPTORS)
+		async_desc->xfer_len = MAX_DESCRIPTORS;
+	else
+		async_desc->xfer_len = async_desc->num_desc;
+
+	/* set INT on last descriptor */
+	desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT;
+
+	if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) {
+		u32 partial = MAX_DESCRIPTORS - bchan->tail;
+
+		memcpy(&fifo[bchan->tail], desc,
+				partial * sizeof(struct bam_desc_hw));
+		memcpy(fifo, &desc[partial], (async_desc->xfer_len - partial) *
+				sizeof(struct bam_desc_hw));
+	} else {
+		memcpy(&fifo[bchan->tail], desc,
+			async_desc->xfer_len * sizeof(struct bam_desc_hw));
+	}
+
+	bchan->tail += async_desc->xfer_len;
+	bchan->tail %= MAX_DESCRIPTORS;
+
+	/* ensure descriptor writes and dma start not reordered */
+	wmb();
+	writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
+			bdev->regs + BAM_P_EVNT_REG(bchan->id));
+}
+
+/**
+ * dma_tasklet - DMA IRQ tasklet
+ * @data: tasklet argument (bam controller structure)
+ *
+ * Sets up next DMA operation and then processes all completed transactions
+ */
+static void dma_tasklet(unsigned long data)
+{
+	struct bam_device *bdev = (struct bam_device *)data;
+	struct bam_chan *bchan;
+	unsigned long flags;
+	unsigned int i;
+
+	/* go through the channels and kick off transactions */
+	for (i = 0; i < bdev->num_channels; i++) {
+		bchan = &bdev->channels[i];
+		spin_lock_irqsave(&bchan->vc.lock, flags);
+
+		if (!list_empty(&bchan->vc.desc_issued) && !bchan->curr_txd)
+			bam_start_dma(bchan);
+		spin_unlock_irqrestore(&bchan->vc.lock, flags);
+	}
+}
+
+/**
+ * bam_issue_pending - starts pending transactions
+ * @chan: dma channel
+ *
+ * Calls tasklet directly which in turn starts any pending transactions
+ */
+static void bam_issue_pending(struct dma_chan *chan)
+{
+	struct bam_chan *bchan = to_bam_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bchan->vc.lock, flags);
+
+	/* if work pending and idle, start a transaction */
+	if (vchan_issue_pending(&bchan->vc) && !bchan->curr_txd)
+		bam_start_dma(bchan);
+
+	spin_unlock_irqrestore(&bchan->vc.lock, flags);
+}
+
+/**
+ * bam_dma_free_desc - free descriptor memory
+ * @vd: virtual descriptor
+ *
+ */
+static void bam_dma_free_desc(struct virt_dma_desc *vd)
+{
+	struct bam_async_desc *async_desc = container_of(vd,
+			struct bam_async_desc, vd);
+
+	kfree(async_desc);
+}
+
+static struct dma_chan *bam_dma_xlate(struct of_phandle_args *dma_spec,
+		struct of_dma *of)
+{
+	struct bam_device *bdev = container_of(of->of_dma_data,
+					struct bam_device, common);
+	unsigned int request;
+
+	if (dma_spec->args_count != 1)
+		return NULL;
+
+	request = dma_spec->args[0];
+	if (request >= bdev->num_channels)
+		return NULL;
+
+	return dma_get_slave_channel(&(bdev->channels[request].vc.chan));
+}
+
+/**
+ * bam_init
+ * @bdev: bam device
+ *
+ * Initialization helper for global bam registers
+ */
+static int bam_init(struct bam_device *bdev)
+{
+	u32 val;
+
+	/* read revision and configuration information */
+	val = readl_relaxed(bdev->regs + BAM_REVISION) & NUM_EES_MASK;
+
+	/* check that configured EE is within range */
+	if (bdev->ee >= val)
+		return -EINVAL;
+
+	val = readl_relaxed(bdev->regs + BAM_NUM_PIPES);
+	bdev->num_channels = val & BAM_NUM_PIPES_MASK;
+
+	/* s/w reset bam */
+	/* after reset all pipes are disabled and idle */
+	val = readl_relaxed(bdev->regs + BAM_CTRL);
+	val |= BAM_SW_RST;
+	writel_relaxed(val, bdev->regs + BAM_CTRL);
+	val &= ~BAM_SW_RST;
+	writel_relaxed(val, bdev->regs + BAM_CTRL);
+
+	/* make sure previous stores are visible before enabling BAM */
+	wmb();
+
+	/* enable bam */
+	val |= BAM_EN;
+	writel_relaxed(val, bdev->regs + BAM_CTRL);
+
+	/* set descriptor threshhold, start with 4 bytes */
+	writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD);
+
+	/* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */
+	writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS);
+
+	/* enable irqs for errors */
+	writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN,
+				bdev->regs + BAM_IRQ_EN);
+
+	return 0;
+}
+
+static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan,
+	u32 index)
+{
+	bchan->id = index;
+	bchan->bdev = bdev;
+
+	vchan_init(&bchan->vc, &bdev->common);
+	bchan->vc.desc_free = bam_dma_free_desc;
+}
+
+static int bam_dma_probe(struct platform_device *pdev)
+{
+	struct bam_device *bdev;
+	struct resource *iores;
+	int ret, i;
+
+	bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
+	if (!bdev)
+		return -ENOMEM;
+
+	bdev->dev = &pdev->dev;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	bdev->regs = devm_ioremap_resource(&pdev->dev, iores);
+	if (IS_ERR(bdev->regs))
+		return PTR_ERR(bdev->regs);
+
+	bdev->irq = platform_get_irq(pdev, 0);
+	if (bdev->irq < 0)
+		return bdev->irq;
+
+	bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk");
+	if (IS_ERR(bdev->bamclk))
+		return PTR_ERR(bdev->bamclk);
+
+	ret = clk_prepare_enable(bdev->bamclk);
+	if (ret) {
+		dev_err(bdev->dev, "failed to prepare/enable clock");
+		return ret;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &bdev->ee);
+	if (ret) {
+		dev_err(bdev->dev, "EE unspecified\n");
+		return ret;
+	}
+
+	ret = bam_init(bdev);
+	if (ret)
+		return ret;
+
+	tasklet_init(&bdev->task, dma_tasklet, (unsigned long)bdev);
+
+	bdev->channels = devm_kcalloc(bdev->dev, bdev->num_channels,
+				sizeof(*bdev->channels), GFP_KERNEL);
+
+	if (!bdev->channels) {
+		ret = -ENOMEM;
+		goto err_disable_clk;
+	}
+
+	/* allocate and initialize channels */
+	INIT_LIST_HEAD(&bdev->common.channels);
+
+	for (i = 0; i < bdev->num_channels; i++)
+		bam_channel_init(bdev, &bdev->channels[i], i);
+
+	ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
+			IRQF_TRIGGER_HIGH, "bam_dma", bdev);
+	if (ret)
+		goto err_disable_clk;
+
+	/* set max dma segment size */
+	bdev->common.dev = bdev->dev;
+	bdev->common.dev->dma_parms = &bdev->dma_parms;
+	ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
+	if (ret) {
+		dev_err(bdev->dev, "cannot set maximum segment size\n");
+		goto err_disable_clk;
+	}
+
+	platform_set_drvdata(pdev, bdev);
+
+	/* set capabilities */
+	dma_cap_zero(bdev->common.cap_mask);
+	dma_cap_set(DMA_SLAVE, bdev->common.cap_mask);
+
+	/* initialize dmaengine apis */
+	bdev->common.device_alloc_chan_resources = bam_alloc_chan;
+	bdev->common.device_free_chan_resources = bam_free_chan;
+	bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
+	bdev->common.device_control = bam_control;
+	bdev->common.device_issue_pending = bam_issue_pending;
+	bdev->common.device_tx_status = bam_tx_status;
+	bdev->common.dev = bdev->dev;
+
+	ret = dma_async_device_register(&bdev->common);
+	if (ret) {
+		dev_err(bdev->dev, "failed to register dma async device\n");
+		goto err_disable_clk;
+	}
+
+	ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
+					&bdev->common);
+	if (ret)
+		goto err_unregister_dma;
+
+	return 0;
+
+err_unregister_dma:
+	dma_async_device_unregister(&bdev->common);
+err_disable_clk:
+	clk_disable_unprepare(bdev->bamclk);
+	return ret;
+}
+
+static int bam_dma_remove(struct platform_device *pdev)
+{
+	struct bam_device *bdev = platform_get_drvdata(pdev);
+	u32 i;
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&bdev->common);
+
+	/* mask all interrupts for this execution environment */
+	writel_relaxed(0, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
+
+	devm_free_irq(bdev->dev, bdev->irq, bdev);
+
+	for (i = 0; i < bdev->num_channels; i++) {
+		bam_dma_terminate_all(&bdev->channels[i]);
+		tasklet_kill(&bdev->channels[i].vc.task);
+
+		dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
+			bdev->channels[i].fifo_virt,
+			bdev->channels[i].fifo_phys);
+	}
+
+	tasklet_kill(&bdev->task);
+
+	clk_disable_unprepare(bdev->bamclk);
+
+	return 0;
+}
+
+static const struct of_device_id bam_of_match[] = {
+	{ .compatible = "qcom,bam-v1.4.0", },
+	{ .compatible = "qcom,bam-v1.4.1", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, bam_of_match);
+
+static struct platform_driver bam_dma_driver = {
+	.probe = bam_dma_probe,
+	.remove = bam_dma_remove,
+	.driver = {
+		.name = "bam-dma-engine",
+		.owner = THIS_MODULE,
+		.of_match_table = bam_of_match,
+	},
+};
+
+module_platform_driver(bam_dma_driver);
+
+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
+MODULE_DESCRIPTION("QCOM BAM DMA engine driver");
+MODULE_LICENSE("GPL v2");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [Patch v5 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Andy Gross @ 2014-02-04 20:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391546556-27702-1-git-send-email-agross@codeaurora.org>

Add device tree binding support for the QCOM BAM DMA driver.

Signed-off-by: Andy Gross <agross@codeaurora.org>
---
 .../devicetree/bindings/dma/qcom_bam_dma.txt       |   48 ++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/qcom_bam_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
new file mode 100644
index 0000000..86344f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
@@ -0,0 +1,48 @@
+QCOM BAM DMA controller
+
+Required properties:
+- compatible:	Must be "qcom,bam-v1.4.0" for MSM8974 V1
+		Must be "qcom,bam-v1.4.1" for MSM8974 V2
+- reg: Address range for DMA registers
+- interrupts: single interrupt for this controller
+- #dma-cells: must be <1>
+- clocks: required clock
+- clock-names: name of clock
+- qcom,ee : indicates the active Execution Environment identifier (0-7)
+
+Example:
+
+	uart-bam: dma at f9984000 = {
+		compatible = "qcom,bam-v1.4.1";
+		reg = <0xf9984000 0x15000>;
+		interrupts = <0 94 0>;
+		clocks = <&gcc GCC_BAM_DMA_AHB_CLK>;
+		clock-names = "bam_clk";
+		#dma-cells = <1>;
+		qcom,ee = <0>;
+	};
+
+Client:
+Required properties:
+- dmas: List of dma channel requests
+- dma-names: Names of aforementioned requested channels
+
+Clients must use the format described in the dma.txt file, using a two cell
+specifier for each channel.
+
+The three cells in order are:
+  1. A phandle pointing to the DMA controller
+  2. The channel number
+
+Example:
+	serial at f991e000 {
+		compatible = "qcom,msm-uart";
+		reg = <0xf991e000 0x1000>
+			<0xf9944000 0x19000>;
+		interrupts = <0 108 0>;
+		clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+		clock-names = "core", "iface";
+
+		dmas = <&uart-bam 0>, <&uart-bam 1>;
+		dma-names = "rx", "tx";
+	};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* Weird sched_clock behaviour during boot with -rc1
From: John Stultz @ 2014-02-04 20:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140204183641.GA25127@mudshark.cambridge.arm.com>

On 02/04/2014 10:36 AM, Will Deacon wrote:
> Hi guys,
>
> Booting -rc1 on my TC2 gives the following strange entries in the dmesg:
>
>
>   Uncompressing Linux... done, booting the kernel.
>   [    0.000000] Booting Linux on physical CPU 0x0
>
>   [...]
>
>   [    0.000000]   HighMem zone: 329728 pages, LIFO batch:31
>   [    7.789662] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns
>   [    0.000129] PERCPU: Embedded 9 pages/cpu @ee7bd000 s12800 r8192 d15872 u36864
>
>   [...]
>
>   [    0.868297] NR_IRQS:16 nr_irqs:16 16
>   [    0.886350] Architected cp15 timer(s) running at 24.00MHz (phys).
>   [ 2915.164998] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 2863311519744ns
>   [    0.000002] Switching to timer-based delay loop
>   [    0.014249] Console: colour dummy device 80x30
>
>
> so it looks like something whacky goes on during sched_clock registration.
> Sure enough, we're doing a pr_info in-between updating cs.* and calling
> update_sched_clock(), so moving the print sorts things out (diff below).

Yea... we have to be particularly careful with sched_clock to avoid
locks since we don't want to deadlock, but in this case
sched_clock_register is a little too relaxed here.

Stephen: Would it make sense to set cd.suspended = true at the top of
the registration? That should block any sched_clock calls from getting
half-updated data, but still allow the sched_clock_update function to work.


> What I can't figure out is why this has suddenly started happening with
> 3.14. Any ideas?

No clue. I'm guessing something like timing changes in the printk paths
that call sched_clock?

I suspect your patch to move the print down will also be a good idea
along with the suspending sched_clock while we register new ones.

thanks
-john

^ permalink raw reply

* [PATCH 1/2] pinctrl: sirf: add pin group for USP0 with only RX or TX frame sync for atlas6
From: Linus Walleij @ 2014-02-04 20:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391061264-2162-1-git-send-email-21cnbao@gmail.com>

On Thu, Jan 30, 2014 at 6:54 AM, Barry Song <21cnbao@gmail.com> wrote:

> From: Rongjun Ying <rongjun.ying@csr.com>
>
> USP0 has multiple functions, and has RX and TX frame sync signals, for some scenarios
> like audio PCM, we don't need both of them. so here we add two possibilities for USP0
> only holding one of TX and RX frame sync.
>
> commit 8385af02bad only added this group for prima2, and missed atlas6. her this patch
> fixes it.
>
> Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>

Patch applied. Altered the commit message a bit.

Yours,
Linus Walleij

^ 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