Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] ARM: dts: Add support of STid127 Soc.
From: Patrice CHOTARD @ 2014-01-30 14:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391093744-19905-1-git-send-email-patrice.chotard@st.com>

From: Alexandre TORGUE <alexandre.torgue@st.com>

The STid127 integrates all harware components to function as a cable modem
or, in combination with a back end device, as a Gateway set top boxe.

Supported devices:
	-UART0
	-UART2

Signed-off-by: alexandre torgue <alexandre.torgue@st.com>
---
 arch/arm/boot/dts/stid127-clock.dtsi   |   31 ++++
 arch/arm/boot/dts/stid127-pinctrl.dtsi |  245 ++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/stid127.dtsi         |  130 +++++++++++++++++
 3 files changed, 406 insertions(+)
 create mode 100644 arch/arm/boot/dts/stid127-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stid127-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stid127.dtsi

diff --git a/arch/arm/boot/dts/stid127-clock.dtsi b/arch/arm/boot/dts/stid127-clock.dtsi
new file mode 100644
index 0000000..c6cafa9
--- /dev/null
+++ b/arch/arm/boot/dts/stid127-clock.dtsi
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
+ *	      Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLK_IC_LP_HD: clockgenA0 at 29 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+			clock-output-names = "CLK_IC_LP_HD";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stid127-pinctrl.dtsi b/arch/arm/boot/dts/stid127-pinctrl.dtsi
new file mode 100644
index 0000000..3fa66f3
--- /dev/null
+++ b/arch/arm/boot/dts/stid127-pinctrl.dtsi
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2012 STMicroelectronics Limited.
+ * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
+ *	      Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "st-pincfg.h"
+/ {
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO5;
+		gpio6	= &PIO6;
+		gpio7	= &PIO7;
+		gpio8	= &PIO8;
+		gpio9	= &PIO9;
+		gpio10	= &PIO10;
+		gpio11	= &PIO11;
+		gpio12	= &PIO12;
+		gpio13	= &PIO13;
+		gpio14	= &PIO14;
+		gpio15	= &PIO15;
+		gpio16	= &PIO16;
+		gpio17	= &PIO17;
+		gpio18	= &PIO18;
+		gpio19	= &PIO19;
+		gpio20	= &PIO20;
+		gpio21	= &PIO21;
+		gpio22	= &PIO22;
+
+	};
+
+	soc {
+		pin-controller-pwest {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stid127-pwest-pinctrl";
+			st,syscfg	= <&syscfg_pwest>;
+			ranges		= <0 0xfebe0000 0x8000>;
+
+			PIO0: gpio at febe0000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0 0x100>;
+				interrupts =  <0 149 0>;
+				st,bank-name  = "PIO0";
+			};
+			PIO1: gpio at febe1000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x1000 0x100>;
+				interrupts =  <0 150 0>;
+				st,bank-name  = "PIO1";
+			};
+			PIO2: gpio at febe2000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x2000 0x100>;
+				interrupts =  <0 151 0>;
+				st,bank-name  = "PIO2";
+			};
+			PIO3: gpio at febe3000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x3000 0x100>;
+				interrupts =  <0 152 0>;
+				st,bank-name  = "PIO3";
+			};
+			PIO4: gpio at febe4000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x4000 0x100>;
+				interrupts =  <0 153 0>;
+				st,bank-name  = "PIO4";
+			};
+			PIO5: gpio at febe5000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x5000 0x100>;
+				interrupts =  <0 154 0>;
+				st,bank-name  = "PIO5";
+			};
+			PIO6: gpio at febe6000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x6000 0x100>;
+				interrupts =  <0 155 0>;
+				st,bank-name  = "PIO6";
+			};
+			PIO7: gpio at febe7000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x7000 0x100>;
+				interrupts =  <0 156 0>;
+				st,bank-name  = "PIO7";
+			};
+			uart0 {
+				pinctrl_uart0: uart0 {
+					st,pins {
+						tx	= <&PIO3 2 ALT2	OUT>;
+						rx	= <&PIO3 0 ALT2	IN>;
+					};
+				};
+			};
+
+		};
+
+		pin-controller-psouth {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stid127-psouth-pinctrl";
+			st,syscfg	= <&syscfg_psouth>;
+			ranges		= <0 0xfef70000 0x7000>;
+
+			PIO8: gpio at fef70000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0 0x100>;
+				interrupts =  <0 157 0>;
+				st,bank-name  = "PIO8";
+			};
+			PIO9: gpio at fef71000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x1000 0x100>;
+				interrupts =  <0 158 0>;
+				st,bank-name  = "PIO9";
+			};
+			PIO10: gpio at fef72000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x2000 0x100>;
+				interrupts =  <0 159 0>;
+				st,bank-name  = "PIO10";
+			};
+			PIO11: gpio at fef73000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x3000 0x100>;
+				interrupts =  <0 160 0>;
+				st,bank-name  = "PIO11";
+			};
+			PIO12: gpio at fef74000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x4000 0x100>;
+				interrupts =  <0 161 0>;
+				st,bank-name  = "PIO12";
+			};
+			PIO13: gpio at fef75000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x5000 0x100>;
+				interrupts =  <0 162 0>;
+				st,bank-name  = "PIO13";
+			};
+			PIO14: gpio at fef76000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x6000 0x100>;
+				interrupts =  <0 163 0>;
+				st,bank-name  = "PIO14";
+			};
+		};
+
+		pin-controller-peast {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stid127-peast-pinctrl";
+			st,syscfg	= <&syscfg_peast>;
+			ranges		= <0 0xfebc0000 0x8000>;
+
+			PIO15: gpio at febc0000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = < 0 0x100>;
+				interrupts =  <0 164 0>;
+				st,bank-name  = "PIO15";
+			};
+			PIO16: gpio at febc1000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x1000 0x100>;
+				interrupts =  <0 165 0>;
+				st,bank-name  = "PIO16";
+			};
+			PIO17: gpio at febc2000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x2000 0x100>;
+				interrupts =  <0 166 0>;
+				st,bank-name  = "PIO17";
+			};
+			PIO18: gpio at febc3000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x3000 0x100>;
+				interrupts =  <0 167 0>;
+				st,bank-name  = "PIO18";
+			};
+			PIO19: gpio at febc4000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x4000 0x100>;
+				interrupts =  <0 168 0>;
+				st,bank-name  = "PIO19";
+			};
+			PIO20: gpio at febc5000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x5000 0x100>;
+				interrupts =  <0 169 0>;
+				st,bank-name  = "PIO20";
+			};
+			PIO21: gpio at febc6000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x6000 0x100>;
+				interrupts =  <0 170 0>;
+				st,bank-name  = "PIO21";
+			};
+			PIO22: gpio at febc7000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg = <0x7000 0x100>;
+				interrupts =  <0 171 0>;
+				st,bank-name  = "PIO22";
+			};
+			uart2 {
+				pinctrl_uart2: uart2-0 {
+					st,pins {
+						tx	= <&PIO20 1 ALT3 OUT>;
+						rx	= <&PIO20 2 ALT3 IN>;
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stid127.dtsi b/arch/arm/boot/dts/stid127.dtsi
new file mode 100644
index 0000000..a6f0b8fe
--- /dev/null
+++ b/arch/arm/boot/dts/stid127.dtsi
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author(s): Giuseppe Cavallaro <peppe.cavallaro@st.com>
+ *	      Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stid127-pinctrl.dtsi"
+#include "stid127-clock.dtsi"
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	intc: interrupt-controller at fffe1000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xfffe1000 0x1000>,
+		      <0xfffe0100 0x100>;
+	};
+
+	scu at fffe0000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0xfffe0000 0x1000>;
+	};
+
+	timer at fffe0200 {
+			interrupt-parent = <&intc>;
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0xfffe0200 0x100>;
+			interrupts = <1 11 0x04>;
+			clocks = <&arm_periph_clk>;
+	};
+
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 2 2>;
+		arm,tag-latency = <1 1 1>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_west:west-syscfg at febf0000{
+			compatible	= "st,stid127-west-syscfg", "syscon";
+			reg		= <0xfebf0000 0x1000>;
+		};
+
+		syscfg_south:south-syscfg at fefa0000{
+			compatible	= "st,stid127-south-syscfg", "syscon";
+			reg		= <0xfefa0000 0x1000>;
+		};
+
+		syscfg_docsis:docsis-syscfg at fef90000{
+			compatible	= "st,stid127-docsys-syscfg", "syscon";
+			reg		= <0xfef90000 0x1000>;
+		};
+
+		syscfg_cpu:cpu-syscfg at fe9a0000{
+			compatible	= "st,stid127-cpu-syscfg", "syscon";
+			reg		= <0xfe9a0000 0x1000>;
+		};
+
+		syscfg_hd:hd-syscfg at fe930000{
+			compatible	= "st,stid127-hd-syscfg", "syscon";
+			reg		= <0xfe930000 0x1000>;
+		};
+
+		syscfg_pwest:pwest-syscfg at fec00000{
+			compatible	= "st,stid127-pwest-syscfg", "syscon";
+			reg		= <0xfec00000 0x1000>;
+		};
+
+		syscfg_psouth:psouth-syscfg at fefd0000{
+			compatible	= "st,stid127-psouth-syscfg", "syscon";
+			reg		= <0xfefd0000 0x1000>;
+		};
+
+		syscfg_peast:peast-syscfg at febd0000{
+			compatible	= "st,stid127-peast-syscfg", "syscon";
+			reg		= <0xfebd0000 0x1000>;
+		};
+
+		/* Comms block ASCs in SASG2 */
+		uart0: serial at fe530000{
+			compatible	= "st,asc";
+			status = "disabled";
+			reg		= <0xfe530000 0x2c>;
+			interrupts	=  <0 25 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_uart0>;
+			clocks		= <&CLK_IC_LP_HD>;
+		};
+
+		uart2: serial at fe532000{
+			compatible	= "st,asc";
+			status = "disabled";
+			reg		= <0xfe532000 0x2c>;
+			interrupts	=  <0 27 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_uart2>;
+			clocks		= <&CLK_IC_LP_HD>;
+		};
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 4/4] ARM: dts: add B2112 board support
From: Patrice CHOTARD @ 2014-01-30 14:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391093744-19905-1-git-send-email-patrice.chotard@st.com>

From: Alexandre TORGUE <alexandre.torgue@st.com>

Add support for B2112  board based on STiD127 SoC.

Signed-off-by: Alexandre Torgue <alexandre.torgue@st.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@st.com>
---
 arch/arm/boot/dts/Makefile          |    3 ++-
 arch/arm/boot/dts/stid127-b2112.dts |   35 +++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/stid127-b2112.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d57c1a6..7173dca 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -247,7 +247,8 @@ dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
 dtb-$(CONFIG_ARCH_STI)+= stih415-b2000.dtb \
 	stih416-b2000.dtb \
 	stih415-b2020.dtb \
-	stih416-b2020.dtb
+	stih416-b2020.dtb \
+	stid127-b2112.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-a1000.dtb \
 	sun4i-a10-cubieboard.dtb \
diff --git a/arch/arm/boot/dts/stid127-b2112.dts b/arch/arm/boot/dts/stid127-b2112.dts
new file mode 100644
index 0000000..b4507e3
--- /dev/null
+++ b/arch/arm/boot/dts/stid127-b2112.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stid127.dtsi"
+
+/ {
+	model = "STiD127 B2112 Board";
+	compatible = "st,stid127", "st,stid127-b2112";
+
+	memory{
+		device_type = "memory";
+		reg = <0x40000000 0x10000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &uart2;
+	};
+
+	aliases {
+		ttyAS0 = &uart2;
+	};
+
+	soc {
+		uart2: serial at fe532000{
+			status = "okay";
+		};
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/2] ARM: imx_v4_v5_defconfig: Select CONFIG_MMC_UNSAFE_RESUME
From: Fabio Estevam @ 2014-01-30 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

PM subsystem treats mmc card as removed during suspend.
    
If MMC is used to store the root file system, it is better to tell the kernel
not to treat it as a removable media, so select CONFIG_MMC_UNSAFE_RESUME for
such purpose.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
 arch/arm/configs/imx_v4_v5_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 6309ee5..f1aeb7d 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -154,6 +154,7 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
 CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 2/2] ARM: imx_v6_v7_defconfig: Select CONFIG_MMC_UNSAFE_RESUME
From: Fabio Estevam @ 2014-01-30 15:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391094252-10599-1-git-send-email-fabio.estevam@freescale.com>

PM subsystem treats mmc card as removed during suspend.
    
If MMC is used to store the root file system, it is better to tell the kernel
not to treat it as a removable media, so select CONFIG_MMC_UNSAFE_RESUME for
such purpose.

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 82ab3cc..7b76794 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -215,6 +215,7 @@ CONFIG_USB_GADGET=y
 CONFIG_USB_ETH=m
 CONFIG_USB_MASS_STORAGE=m
 CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
-- 
1.8.1.2

^ permalink raw reply related

* [RFC PATCH pre-v3 08/14] mtd: nand: add sunxi NAND flash controller support
From: Boris BREZILLON @ 2014-01-30 15:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140130143641.GZ15937@n2100.arm.linux.org.uk>

Hello Russel,

On 30/01/2014 15:36, Russell King - ARM Linux wrote:
> Boris,
>
> Can you please explain to me why you mail all your patches _To:_ me?
> As in, why do I appear in the To: line of all the patches you seem to
> mail out, whether or not they're relevant to me.  I see this very
> regularly from you - virtually all patches I see on the LAKML mailing
> list from you are always sent To: me as well.
>
> Take for instance this one.  It doesn't match up with anything in
> MAINTAINERS for me.  It doesn't even touch a file that I've touched.
> Yet somehow you think that I should be in the To: header.
>
> Being in the To: header means that you expect the recipient to do
> something with your email.  The Cc: header is to circulate copies of
> your email to people who may be interested.
>
> I'm neither for this stuff.  Please stop this.

Sorry for the inconvenience.

I'm using get_maintainer.pl script to retrieve the list of concerned
people, and you appears in that list for patches 10,11,12 and 14 of this
series.
Moreover I was told to send the whole series (not just specific patches
to people who might be concerned).

I obviously misuse this script, so please tell me how I should know which
patch I should send to whom.

Thanks.

Best Regards,

Boris

>
> Thanks.
>
> On Thu, Jan 30, 2014 at 02:39:36PM +0100, Boris BREZILLON wrote:
>> Add support for the sunxi NAND Flash Controller (NFC).
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
>> ---
>> Hello,
>>
>> This version fixes a bug in the R/B GPIO config block.
>> The timing config order is now respected, but I'll wait for Jason work
>> regarding timing config in NAND core code before posting the 3rd version
>> of this series.
>>
>> Best Regards,
>>
>> Boris
>>
>> Changes since v2:
>>   - fix R/B GPIO retrieval/config bug
>>   - fix timings configuration order (set mode 0 -> scan -> set best supported
>>     mode)
>>
>>   drivers/mtd/nand/Kconfig      |    6 +
>>   drivers/mtd/nand/Makefile     |    1 +
>>   drivers/mtd/nand/sunxi_nand.c |  758 +++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 765 insertions(+)
>>   create mode 100644 drivers/mtd/nand/sunxi_nand.c
>>
>> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
>> index 93ae6a6..784dd42 100644
>> --- a/drivers/mtd/nand/Kconfig
>> +++ b/drivers/mtd/nand/Kconfig
>> @@ -510,4 +510,10 @@ config MTD_NAND_XWAY
>>   	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
>>   	  to the External Bus Unit (EBU).
>>   
>> +config MTD_NAND_SUNXI
>> +	tristate "Support for NAND on Allwinner SoCs"
>> +	depends on ARCH_SUNXI
>> +	help
>> +	  Enables support for NAND Flash chips on Allwinner SoCs.
>> +
>>   endif # MTD_NAND
>> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
>> index bbea7a6..e3b4a34 100644
>> --- a/drivers/mtd/nand/Makefile
>> +++ b/drivers/mtd/nand/Makefile
>> @@ -49,5 +49,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
>>   obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
>>   obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
>>   obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
>> +obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
>>   
>>   nand-objs := nand_base.o nand_bbt.o
>> diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
>> new file mode 100644
>> index 0000000..1014b2a
>> --- /dev/null
>> +++ b/drivers/mtd/nand/sunxi_nand.c
>> @@ -0,0 +1,758 @@
>> +/*
>> + * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com>
>> + *
>> + * Derived from:
>> + *	https://github.com/yuq/sunxi-nfc-mtd
>> + *	Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
>> + *
>> + *	https://github.com/hno/Allwinner-Info
>> + *	Copyright (C) 2013 Henrik Nordstr?m <Henrik Nordstr?m>
>> + *
>> + *	Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com>
>> + *	Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/dma-mapping.h>
>> +#include <linux/slab.h>
>> +#include <linux/module.h>
>> +#include <linux/moduleparam.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/of_mtd.h>
>> +#include <linux/mtd/mtd.h>
>> +#include <linux/mtd/nand.h>
>> +#include <linux/mtd/partitions.h>
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/dmaengine.h>
>> +#include <linux/gpio.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +
>> +#define NFC_REG_CTL		0x0000
>> +#define NFC_REG_ST		0x0004
>> +#define NFC_REG_INT		0x0008
>> +#define NFC_REG_TIMING_CTL	0x000C
>> +#define NFC_REG_TIMING_CFG	0x0010
>> +#define NFC_REG_ADDR_LOW	0x0014
>> +#define NFC_REG_ADDR_HIGH	0x0018
>> +#define NFC_REG_SECTOR_NUM	0x001C
>> +#define NFC_REG_CNT		0x0020
>> +#define NFC_REG_CMD		0x0024
>> +#define NFC_REG_RCMD_SET	0x0028
>> +#define NFC_REG_WCMD_SET	0x002C
>> +#define NFC_REG_IO_DATA		0x0030
>> +#define NFC_REG_ECC_CTL		0x0034
>> +#define NFC_REG_ECC_ST		0x0038
>> +#define NFC_REG_DEBUG		0x003C
>> +#define NFC_REG_ECC_CNT0	0x0040
>> +#define NFC_REG_ECC_CNT1	0x0044
>> +#define NFC_REG_ECC_CNT2	0x0048
>> +#define NFC_REG_ECC_CNT3	0x004c
>> +#define NFC_REG_USER_DATA_BASE	0x0050
>> +#define NFC_REG_SPARE_AREA	0x00A0
>> +#define NFC_RAM0_BASE		0x0400
>> +#define NFC_RAM1_BASE		0x0800
>> +
>> +/*define bit use in NFC_CTL*/
>> +#define NFC_EN				(1 << 0)
>> +#define NFC_RESET			(1 << 1)
>> +#define NFC_BUS_WIDYH			(1 << 2)
>> +#define NFC_RB_SEL			(1 << 3)
>> +#define NFC_CE_SEL			(7 << 24)
>> +#define NFC_CE_CTL			(1 << 6)
>> +#define NFC_CE_CTL1			(1 << 7)
>> +#define NFC_PAGE_SIZE			(0xf << 8)
>> +#define NFC_SAM				(1 << 12)
>> +#define NFC_RAM_METHOD			(1 << 14)
>> +#define NFC_DEBUG_CTL			(1 << 31)
>> +
>> +/*define bit use in NFC_ST*/
>> +#define NFC_RB_B2R			(1 << 0)
>> +#define NFC_CMD_INT_FLAG		(1 << 1)
>> +#define NFC_DMA_INT_FLAG		(1 << 2)
>> +#define NFC_CMD_FIFO_STATUS		(1 << 3)
>> +#define NFC_STA				(1 << 4)
>> +#define NFC_NATCH_INT_FLAG		(1 << 5)
>> +#define NFC_RB_STATE0			(1 << 8)
>> +#define NFC_RB_STATE1			(1 << 9)
>> +#define NFC_RB_STATE2			(1 << 10)
>> +#define NFC_RB_STATE3			(1 << 11)
>> +
>> +/*define bit use in NFC_INT*/
>> +#define NFC_B2R_INT_ENABLE		(1 << 0)
>> +#define NFC_CMD_INT_ENABLE		(1 << 1)
>> +#define NFC_DMA_INT_ENABLE		(1 << 2)
>> +#define NFC_INT_MASK			(NFC_B2R_INT_ENABLE | \
>> +					 NFC_CMD_INT_ENABLE | \
>> +					 NFC_DMA_INT_ENABLE)
>> +
>> +
>> +/*define bit use in NFC_CMD*/
>> +#define NFC_CMD_LOW_BYTE		(0xff << 0)
>> +#define NFC_CMD_HIGH_BYTE		(0xff << 8)
>> +#define NFC_ADR_NUM			(0x7 << 16)
>> +#define NFC_SEND_ADR			(1 << 19)
>> +#define NFC_ACCESS_DIR			(1 << 20)
>> +#define NFC_DATA_TRANS			(1 << 21)
>> +#define NFC_SEND_CMD1			(1 << 22)
>> +#define NFC_WAIT_FLAG			(1 << 23)
>> +#define NFC_SEND_CMD2			(1 << 24)
>> +#define NFC_SEQ				(1 << 25)
>> +#define NFC_DATA_SWAP_METHOD		(1 << 26)
>> +#define NFC_ROW_AUTO_INC		(1 << 27)
>> +#define NFC_SEND_CMD3			(1 << 28)
>> +#define NFC_SEND_CMD4			(1 << 29)
>> +#define NFC_CMD_TYPE			(3 << 30)
>> +
>> +/* define bit use in NFC_RCMD_SET*/
>> +#define NFC_READ_CMD			(0xff << 0)
>> +#define NFC_RANDOM_READ_CMD0		(0xff << 8)
>> +#define NFC_RANDOM_READ_CMD1		(0xff << 16)
>> +
>> +/*define bit use in NFC_WCMD_SET*/
>> +#define NFC_PROGRAM_CMD			(0xff << 0)
>> +#define NFC_RANDOM_WRITE_CMD		(0xff << 8)
>> +#define NFC_READ_CMD0			(0xff << 16)
>> +#define NFC_READ_CMD1			(0xff << 24)
>> +
>> +/*define bit use in NFC_ECC_CTL*/
>> +#define NFC_ECC_EN			(1 << 0)
>> +#define NFC_ECC_PIPELINE		(1 << 3)
>> +#define NFC_ECC_EXCEPTION		(1 << 4)
>> +#define NFC_ECC_BLOCK_SIZE		(1 << 5)
>> +#define NFC_RANDOM_EN			(1 << 9)
>> +#define NFC_RANDOM_DIRECTION		(1 << 10)
>> +#define NFC_ECC_MODE_SHIFT		12
>> +#define NFC_ECC_MODE			(0xf << NFC_ECC_MODE_SHIFT)
>> +#define NFC_RANDOM_SEED			(0x7fff << 16)
>> +
>> +
>> +
>> +enum sunxi_nand_rb_type {
>> +	RB_NONE,
>> +	RB_NATIVE,
>> +	RB_GPIO,
>> +};
>> +
>> +struct sunxi_nand_rb {
>> +	enum sunxi_nand_rb_type type;
>> +	union {
>> +		int gpio;
>> +		int nativeid;
>> +	} info;
>> +};
>> +
>> +struct sunxi_nand_chip_sel {
>> +	u8 cs;
>> +	struct sunxi_nand_rb rb;
>> +};
>> +
>> +#define DEFAULT_NAME_FORMAT	"nand@%d"
>> +#define MAX_NAME_SIZE		(sizeof("nand@") + 2)
>> +
>> +struct sunxi_nand_chip {
>> +	struct list_head node;
>> +	struct nand_chip nand;
>> +	struct mtd_info mtd;
>> +	char default_name[MAX_NAME_SIZE];
>> +	unsigned long clk_rate;
>> +	int selected;
>> +	int nsels;
>> +	struct sunxi_nand_chip_sel sels[0];
>> +};
>> +
>> +static inline struct sunxi_nand_chip *to_sunxi_nand(struct mtd_info *mtd)
>> +{
>> +	return container_of(mtd, struct sunxi_nand_chip, mtd);
>> +}
>> +
>> +struct sunxi_nfc {
>> +	struct nand_hw_control controller;
>> +	void __iomem *regs;
>> +	int irq;
>> +	struct clk *ahb_clk;
>> +	struct clk *sclk;
>> +	unsigned long assigned_cs;
>> +	unsigned long clk_rate;
>> +	struct list_head chips;
>> +	struct completion complete;
>> +};
>> +
>> +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
>> +{
>> +	return container_of(ctrl, struct sunxi_nfc, controller);
>> +}
>> +
>> +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id)
>> +{
>> +	struct sunxi_nfc *nfc = dev_id;
>> +	u32 st = readl(nfc->regs + NFC_REG_ST);
>> +	u32 ien = readl(nfc->regs + NFC_REG_INT);
>> +
>> +	if (!(ien & st))
>> +		return IRQ_NONE;
>> +
>> +	if ((ien & st) == ien)
>> +		complete(&nfc->complete);
>> +
>> +	writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST);
>> +	writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
>> +			      unsigned int timeout_ms)
>> +{
>> +	init_completion(&nfc->complete);
>> +
>> +	writel(flags, nfc->regs + NFC_REG_INT);
>> +	if (!timeout_ms)
>> +		wait_for_completion(&nfc->complete);
>> +	else if (!wait_for_completion_timeout(&nfc->complete,
>> +					      msecs_to_jiffies(timeout_ms)))
>> +		return -ETIMEDOUT;
>> +
>> +	return 0;
>> +}
>> +
>> +static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
>> +{
>> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
>> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
>> +	struct sunxi_nand_rb *rb;
>> +	unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
>> +	int ret;
>> +
>> +	if (sunxi_nand->selected < 0)
>> +		return 0;
>> +
>> +	rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
>> +
>> +	switch (rb->type) {
>> +	case RB_NATIVE:
>> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
>> +			 (NFC_RB_STATE0 << rb->info.nativeid));
>> +		if (ret)
>> +			break;
>> +
>> +		sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
>> +		ret = !!(readl(nfc->regs + NFC_REG_ST) &
>> +			 (NFC_RB_STATE0 << rb->info.nativeid));
>> +		break;
>> +	case RB_GPIO:
>> +		ret = gpio_get_value(rb->info.gpio);
>> +		break;
>> +	case RB_NONE:
>> +	default:
>> +		ret = 0;
>> +		dev_err(&mtd->dev, "cannot check R/B NAND status!");
>> +		break;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
>> +{
>> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
>> +	struct nand_chip *nand = &sunxi_nand->nand;
>> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
>> +	struct sunxi_nand_chip_sel *sel;
>> +	u32 ctl;
>> +
>> +	if (chip > 0 && chip >= sunxi_nand->nsels)
>> +		return;
>> +
>> +	if (chip == sunxi_nand->selected)
>> +		return;
>> +
>> +	ctl = readl(nfc->regs + NFC_REG_CTL) &
>> +	      ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN);
>> +
>> +	if (chip >= 0) {
>> +		sel = &sunxi_nand->sels[chip];
>> +
>> +		ctl |= (sel->cs << 24) | NFC_EN |
>> +		       (((nand->page_shift - 10) & 0xf) << 8);
>> +		if (sel->rb.type == RB_NONE) {
>> +			nand->dev_ready = NULL;
>> +		} else {
>> +			nand->dev_ready = sunxi_nfc_dev_ready;
>> +			if (sel->rb.type == RB_NATIVE)
>> +				ctl |= (sel->rb.info.nativeid << 3);
>> +		}
>> +
>> +		writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
>> +
>> +		if (nfc->clk_rate != sunxi_nand->clk_rate) {
>> +			clk_set_rate(nfc->sclk, sunxi_nand->clk_rate);
>> +			nfc->clk_rate = sunxi_nand->clk_rate;
>> +		}
>> +	}
>> +
>> +	writel(ctl, nfc->regs + NFC_REG_CTL);
>> +
>> +	sunxi_nand->selected = chip;
>> +}
>> +
>> +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
>> +{
>> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
>> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
>> +	int cnt;
>> +	int offs = 0;
>> +	u32 tmp;
>> +
>> +	while (len > offs) {
>> +		cnt = len - offs;
>> +		if (cnt > 1024)
>> +			cnt = 1024;
>> +
>> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
>> +			;
>> +		writel(cnt, nfc->regs + NFC_REG_CNT);
>> +		tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
>> +		writel(tmp, nfc->regs + NFC_REG_CMD);
>> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
>> +		if (buf)
>> +			memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
>> +				      cnt);
>> +		offs += cnt;
>> +	}
>> +}
>> +
>> +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
>> +				int len)
>> +{
>> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
>> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
>> +	int cnt;
>> +	int offs = 0;
>> +	u32 tmp;
>> +
>> +	while (len > offs) {
>> +		cnt = len - offs;
>> +		if (cnt > 1024)
>> +			cnt = 1024;
>> +
>> +		while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
>> +			;
>> +		writel(cnt, nfc->regs + NFC_REG_CNT);
>> +		memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
>> +		tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
>> +		      NFC_ACCESS_DIR;
>> +		writel(tmp, nfc->regs + NFC_REG_CMD);
>> +		sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
>> +		offs += cnt;
>> +	}
>> +}
>> +
>> +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
>> +{
>> +	uint8_t ret;
>> +
>> +	sunxi_nfc_read_buf(mtd, &ret, 1);
>> +
>> +	return ret;
>> +}
>> +
>> +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
>> +			       unsigned int ctrl)
>> +{
>> +	struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(mtd);
>> +	struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
>> +	u32 tmp;
>> +
>> +	while ((readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
>> +		;
>> +
>> +	if (ctrl & NAND_CTRL_CHANGE) {
>> +		tmp = readl(nfc->regs + NFC_REG_CTL);
>> +		if (ctrl & NAND_NCE)
>> +			tmp |= NFC_CE_CTL;
>> +		else
>> +			tmp &= ~NFC_CE_CTL;
>> +		writel(tmp, nfc->regs + NFC_REG_CTL);
>> +	}
>> +
>> +	if (dat == NAND_CMD_NONE)
>> +		return;
>> +
>> +	if (ctrl & NAND_CLE) {
>> +		writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD);
>> +	} else {
>> +		writel(dat, nfc->regs + NFC_REG_ADDR_LOW);
>> +		writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD);
>> +	}
>> +
>> +	sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
>> +}
>> +
>> +static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
>> +				       const struct nand_sdr_timings *timings)
>> +{
>> +	u32 min_clk_period = 0;
>> +
>> +	/* T1 <=> tCLS */
>> +	if (timings->tCLS_min > min_clk_period)
>> +		min_clk_period = timings->tCLS_min;
>> +
>> +	/* T2 <=> tCLH */
>> +	if (timings->tCLH_min > min_clk_period)
>> +		min_clk_period = timings->tCLH_min;
>> +
>> +	/* T3 <=> tCS */
>> +	if (timings->tCS_min > min_clk_period)
>> +		min_clk_period = timings->tCS_min;
>> +
>> +	/* T4 <=> tCH */
>> +	if (timings->tCH_min > min_clk_period)
>> +		min_clk_period = timings->tCH_min;
>> +
>> +	/* T5 <=> tWP */
>> +	if (timings->tWP_min > min_clk_period)
>> +		min_clk_period = timings->tWP_min;
>> +
>> +	/* T6 <=> tWH */
>> +	if (timings->tWH_min > min_clk_period)
>> +		min_clk_period = timings->tWH_min;
>> +
>> +	/* T7 <=> tALS */
>> +	if (timings->tALS_min > min_clk_period)
>> +		min_clk_period = timings->tALS_min;
>> +
>> +	/* T8 <=> tDS */
>> +	if (timings->tDS_min > min_clk_period)
>> +		min_clk_period = timings->tDS_min;
>> +
>> +	/* T9 <=> tDH */
>> +	if (timings->tDH_min > min_clk_period)
>> +		min_clk_period = timings->tDH_min;
>> +
>> +	/* T10 <=> tRR */
>> +	if (timings->tRR_min > (min_clk_period * 3))
>> +		min_clk_period = (timings->tRR_min + 2) / 3;
>> +
>> +	/* T11 <=> tALH */
>> +	if (timings->tALH_min > min_clk_period)
>> +		min_clk_period = timings->tALH_min;
>> +
>> +	/* T12 <=> tRP */
>> +	if (timings->tRP_min > min_clk_period)
>> +		min_clk_period = timings->tRP_min;
>> +
>> +	/* T13 <=> tREH */
>> +	if (timings->tREH_min > min_clk_period)
>> +		min_clk_period = timings->tREH_min;
>> +
>> +	/* T14 <=> tRC */
>> +	if (timings->tRC_min > (min_clk_period * 2))
>> +		min_clk_period = (timings->tRC_min + 1) / 2;
>> +
>> +	/* T15 <=> tWC */
>> +	if (timings->tWC_min > (min_clk_period * 2))
>> +		min_clk_period = (timings->tWC_min + 1) / 2;
>> +
>> +
>> +	/* min_clk_period = (NAND-clk-period * 2) */
>> +	if (min_clk_period < 1000)
>> +		min_clk_period = 1000;
>> +
>> +	min_clk_period /= 1000;
>> +	chip->clk_rate = (2 * 1000000000) / min_clk_period;
>> +
>> +	/* TODO: configure T16-T19 */
>> +
>> +	return 0;
>> +}
>> +
>> +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip,
>> +					struct device_node *np)
>> +{
>> +	const struct nand_sdr_timings *timings;
>> +	int ret;
>> +
>> +	ret = onfi_get_async_timing_mode(&chip->nand);
>> +	if (ret == ONFI_TIMING_MODE_UNKNOWN) {
>> +		ret = of_get_nand_onfi_timing_mode(np);
>> +		if (ret < 0)
>> +			return ret;
>> +	}
>> +
>> +	ret = fls(ret);
>> +	if (!ret)
>> +		return -EINVAL;
>> +
>> +	timings = onfi_async_timing_mode_to_sdr_timings(ret - 1);
>> +	if (IS_ERR(timings))
>> +		return PTR_ERR(timings);
>> +
>> +	return sunxi_nand_chip_set_timings(chip, timings);
>> +}
>> +
>> +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
>> +				struct device_node *np)
>> +{
>> +	const struct nand_sdr_timings *timings;
>> +	struct sunxi_nand_chip *chip;
>> +	struct mtd_part_parser_data ppdata;
>> +	struct mtd_info *mtd;
>> +	struct nand_chip *nand;
>> +	u32 strength;
>> +	u32 blk_size;
>> +	int nsels;
>> +	int ret;
>> +	int i;
>> +	u32 tmp;
>> +
>> +	if (!of_get_property(np, "reg", &nsels))
>> +		return -EINVAL;
>> +
>> +	nsels /= sizeof(u32);
>> +	if (!nsels)
>> +		return -EINVAL;
>> +
>> +	chip = devm_kzalloc(dev,
>> +			    sizeof(*chip) +
>> +			    (nsels * sizeof(struct sunxi_nand_chip_sel)),
>> +			    GFP_KERNEL);
>> +	if (!chip)
>> +		return -ENOMEM;
>> +
>> +	chip->nsels = nsels;
>> +	chip->selected = -1;
>> +
>> +	for (i = 0; i < nsels; i++) {
>> +		ret = of_property_read_u32_index(np, "reg", i, &tmp);
>> +		if (ret)
>> +			return ret;
>> +
>> +		if (tmp > 7)
>> +			return -EINVAL;
>> +
>> +		if (test_and_set_bit(tmp, &nfc->assigned_cs))
>> +			return -EINVAL;
>> +
>> +		chip->sels[i].cs = tmp;
>> +
>> +		if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) &&
>> +		    tmp < 2) {
>> +			chip->sels[i].rb.type = RB_NATIVE;
>> +			chip->sels[i].rb.info.nativeid = tmp;
>> +		} else {
>> +			ret = of_get_named_gpio(np, "rb-gpios", i);
>> +			if (ret >= 0) {
>> +				tmp = ret;
>> +				chip->sels[i].rb.type = RB_GPIO;
>> +				chip->sels[i].rb.info.gpio = tmp;
>> +				ret = devm_gpio_request(dev, tmp, "nand-rb");
>> +				if (ret)
>> +					return ret;
>> +
>> +				ret = gpio_direction_input(tmp);
>> +				if (ret)
>> +					return ret;
>> +			} else {
>> +				chip->sels[i].rb.type = RB_NONE;
>> +			}
>> +		}
>> +	}
>> +
>> +	timings = onfi_async_timing_mode_to_sdr_timings(0);
>> +	if (IS_ERR(timings))
>> +		return PTR_ERR(timings);
>> +
>> +	ret = sunxi_nand_chip_set_timings(chip, timings);
>> +
>> +	nand = &chip->nand;
>> +	nand->controller = &nfc->controller;
>> +	nand->select_chip = sunxi_nfc_select_chip;
>> +	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
>> +	nand->read_buf = sunxi_nfc_read_buf;
>> +	nand->write_buf = sunxi_nfc_write_buf;
>> +	nand->read_byte = sunxi_nfc_read_byte;
>> +
>> +	nand->ecc.mode = of_get_nand_ecc_mode(np);
>> +	if (of_get_nand_on_flash_bbt(np))
>> +		nand->bbt_options |= NAND_BBT_USE_FLASH;
>> +
>> +	mtd = &chip->mtd;
>> +	mtd->priv = nand;
>> +	mtd->owner = THIS_MODULE;
>> +
>> +	ret = nand_scan_ident(mtd, nsels, NULL);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = sunxi_nand_chip_init_timings(chip, np);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
>> +		if (!of_get_nand_ecc_level(np, &strength, &blk_size)) {
>> +			nand->ecc_step_ds = blk_size;
>> +			nand->ecc_strength_ds = strength;
>> +		}
>> +
>> +		nand->ecc.size = nand->ecc_step_ds;
>> +		nand->ecc.bytes = (((nand->ecc_strength_ds *
>> +				     fls(8 * nand->ecc_step_ds)) + 7) / 8);
>> +	}
>> +
>> +	ret = nand_scan_tail(mtd);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (of_property_read_string(np, "nand-name", &mtd->name)) {
>> +		snprintf(chip->default_name, MAX_NAME_SIZE,
>> +			 DEFAULT_NAME_FORMAT, chip->sels[i].cs);
>> +		mtd->name = chip->default_name;
>> +	}
>> +
>> +	ppdata.of_node = np;
>> +	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
>> +	if (!ret)
>> +		return ret;
>> +
>> +	list_add_tail(&chip->node, &nfc->chips);
>> +
>> +	return 0;
>> +}
>> +
>> +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc)
>> +{
>> +	struct device_node *np = dev->of_node;
>> +	struct device_node *nand_np;
>> +	int nchips = of_get_child_count(np);
>> +	int ret;
>> +
>> +	if (nchips > 8)
>> +		return -EINVAL;
>> +
>> +	for_each_child_of_node(np, nand_np) {
>> +		ret = sunxi_nand_chip_init(dev, nfc, nand_np);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int sunxi_nfc_probe(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct resource *r;
>> +	struct sunxi_nfc *nfc;
>> +	int ret;
>> +
>> +	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>> +	if (!nfc) {
>> +		dev_err(dev, "failed to allocate NFC struct\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	spin_lock_init(&nfc->controller.lock);
>> +	init_waitqueue_head(&nfc->controller.wq);
>> +	INIT_LIST_HEAD(&nfc->chips);
>> +
>> +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	nfc->regs = devm_ioremap_resource(dev, r);
>> +	if (IS_ERR(nfc->regs)) {
>> +		dev_err(dev, "failed to remap iomem\n");
>> +		return PTR_ERR(nfc->regs);
>> +	}
>> +
>> +	nfc->irq = platform_get_irq(pdev, 0);
>> +	if (nfc->irq < 0) {
>> +		dev_err(dev, "failed to retrieve irq\n");
>> +		return nfc->irq;
>> +	}
>> +
>> +	nfc->ahb_clk = devm_clk_get(dev, "ahb_clk");
>> +	if (IS_ERR(nfc->ahb_clk)) {
>> +		dev_err(dev, "failed to retrieve ahb_clk\n");
>> +		return PTR_ERR(nfc->ahb_clk);
>> +	}
>> +
>> +	ret = clk_prepare_enable(nfc->ahb_clk);
>> +	if (ret)
>> +		return ret;
>> +
>> +	nfc->sclk = devm_clk_get(dev, "sclk");
>> +	if (IS_ERR(nfc->sclk)) {
>> +		dev_err(dev, "failed to retrieve nand_clk\n");
>> +		ret = PTR_ERR(nfc->sclk);
>> +		goto out_ahb_clk_unprepare;
>> +	}
>> +
>> +	ret = clk_prepare_enable(nfc->sclk);
>> +	if (ret)
>> +		goto out_ahb_clk_unprepare;
>> +
>> +	/* Reset NFC */
>> +	writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RESET,
>> +	       nfc->regs + NFC_REG_CTL);
>> +	while (readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)
>> +		;
>> +
>> +	writel(0, nfc->regs + NFC_REG_INT);
>> +	ret = devm_request_irq(dev, nfc->irq, sunxi_nfc_interrupt,
>> +			       0, "sunxi-nand", nfc);
>> +	if (ret)
>> +		goto out_sclk_unprepare;
>> +
>> +	platform_set_drvdata(pdev, nfc);
>> +
>> +	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
>> +	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
>> +
>> +	ret = sunxi_nand_chips_init(dev, nfc);
>> +	if (ret) {
>> +		dev_err(dev, "failed to init nand chips\n");
>> +		goto out_sclk_unprepare;
>> +	}
>> +
>> +	return 0;
>> +
>> +out_sclk_unprepare:
>> +	clk_disable_unprepare(nfc->sclk);
>> +out_ahb_clk_unprepare:
>> +	clk_disable_unprepare(nfc->ahb_clk);
>> +
>> +	return ret;
>> +}
>> +
>> +static const struct of_device_id sunxi_nfc_ids[] = {
>> +	{ .compatible = "allwinner,sun4i-nand" },
>> +	{ /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);
>> +
>> +static struct platform_driver sunxi_nfc_driver = {
>> +	.driver = {
>> +		.name = "sunxi_nand",
>> +		.owner = THIS_MODULE,
>> +		.of_match_table = of_match_ptr(sunxi_nfc_ids),
>> +	},
>> +	.probe = sunxi_nfc_probe,
>> +};
>> +module_platform_driver(sunxi_nfc_driver);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("Boris BREZILLON");
>> +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
>> +MODULE_ALIAS("platform:sunxi_nfc");
>> -- 
>> 1.7.9.5
>>

^ permalink raw reply

* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Heiko Stübner @ 2014-01-30 15:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJuA9ajLUPtsReomPuuzMpshTEiUz81sc4584DEVQnG=iwGb-g@mail.gmail.com>

On Thursday, 30. January 2014 18:23:44 Thomas Abraham wrote:
> Hi Mike,
> 
> On Wed, Jan 29, 2014 at 12:17 AM, Mike Turquette <mturquette@linaro.org> 
wrote:
> > On Mon, Jan 27, 2014 at 9:30 PM, Thomas Abraham <ta.omasab@gmail.com> 
wrote:
> >> Hi Mike,
> >> 
> >> On Tue, Jan 28, 2014 at 1:55 AM, Mike Turquette <mturquette@linaro.org> 
wrote:
> >>> Quoting Thomas Abraham (2014-01-18 04:10:51)
> >>> 
> > As far as I can tell
> > the remux does not happen because it is necessary to generate the
> > required clock rate, but because we don't want to run the ARM core out
> > of spec for a short time while the PLL relocks. Assuming I have that
> > part of it right, I prefer for the parent mux operation to be a part
> > of the CPUfreq driver's .target callback instead of hidden away in the
> > clock driver.
> 
> The re-parenting is mostly done to keep the ARM CPU clocked while the
> PLL is stopped, reprogrammed and restarted. One of the side effects of
> that is, the clock speed of the temporary parent could be higher then
> what is allowed due to the ARM voltage at the time of re-parenting.
> That is the reason to use the safe voltage.

The Rockchip-SoCs use something similar, so I'm following quite closely what 
Thomas is trying to do here, as similar solution would also solve this issue 
for me.

On some Rockchip-SoCs even stuff like pclk and hclk seems to be sourced from 
the divided armclk, creating additional constraints.

But on the RKs (at least in the upstream sources) the armclk is simply equal 
to the pll output. A divider exists, but is only used to make sure that the 
armclk stays below the original rate when sourced from the temp-parent, like

	if (clk_get_rate(temp_parent) > clk_get_rate(main_parent)
		set_divider(something so that rate(temp) <= rate(main)
	clk_set_parent(...)

Isn't there a similar possiblity on your platform, as it would remove the need 
for the safe-voltage?


In general I also like the approach of hiding the rate-change logic inside 
this composite clock, as the depending clocks can be easily kept in sync. As 
with the Rockchips the depending clocks are different for each of the three 
Cortex-A9 SoCs I looked at, it would be "interesting" if all of this would 
need to be done in a cpufreq driver.


Heiko

^ permalink raw reply

* Root NFS panicing on Linus' tip (Re: NFS client broken in Linus' tip)
From: Ezequiel Garcia @ 2014-01-30 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140130140834.GW15937@n2100.arm.linux.org.uk>

Hi Russell, Trond:

On Thu, Jan 30, 2014 at 02:08:34PM +0000, Russell King - ARM Linux wrote:
> I just booted Linus' tip (plus a few other patches to imx-drm and imx
> code), and stumbled into this interesting scenario:
> 
[..]

> CONFIG_NFS_FS=y
> CONFIG_NFS_V2=y
> CONFIG_NFS_V3=y
> CONFIG_NFS_V3_ACL=y

Just came across another issue, but a bit more problematic, as my
kernel (Linus' tip as well) panics, after mounting the rootfs:

IP-Config: Complete:
     device=eth0, hwaddr=00:50:43:50:1c:15, ipaddr=192.168.0.159, mask=255.255.255.0, gw=192.168.0.1
     host=develboard, domain=, nis-domain=(none)
     bootserver=192.168.0.45, rootserver=192.168.0.45, rootpath=
VFS: Mounted root (nfs filesystem) on device 0:11.
devtmpfs: mounted
Freeing unused kernel memory: 136K (c0465000 - c0487000)
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 5 [#1] ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Tainted: G        W    3.13.0-10094-g9b0cd30 #276
task: ed839a40 ti: ed83a000 task.ti: ed83a000
PC is at xattr_resolve_name+0x14/0x94
LR is at generic_getxattr+0x2c/0x64
pc : [<c00a7ab0>]    lr : [<c00a7b5c>]    psr: a0000113
sp : ed83be5c  ip : ed83be74  fp : ed10ebc0
r10: ed83a000  r9 : ed43d980  r8 : ed81b800
r7 : c034dad8  r6 : 00000000  r5 : c03f3dcc  r4 : ed43d980
r3 : 00000014  r2 : ed83be8c  r1 : ed83be74  r0 : 00000000
Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c53c7d  Table: 00004059  DAC: 00000015
Process swapper (pid: 1, stack limit = 0xed83a238)
Stack: (0xed83be5c to 0xed83c000)
be40:                                                                ed43d980
be60: 00000014 ed83be8c 00000000 00000000 c04bc22c c03f3dcc ed83bf14 ed43f340
be80: ed43d980 c01115cc 00000000 00000041 c04bba6c 00000000 00000000 002040d0
bea0: ed81bc00 ed10ebc0 ed81bc30 c01116f8 00000000 000004d0 ed8172d0 ed43d980
bec0: 45878fd4 00000007 bfe01007 ef7f8fc0 c04bba6c ed43d6d8 c04bba6c 00000101
bee0: 00000000 ed809fd0 ed809fc0 ed809f50 ed809f40 00000000 edb045d8 c0078bcc
bf00: ed0e5dc0 edb045d8 00000000 bf000000 ed0e5dc0 00000000 00000000 00000000
bf20: 00000000 00000000 bf000000 ed10ebc0 ed0e5dc0 00000001 edb045d8 c04926d0
bf40: ed83a000 c0492758 ed10ebc0 c008fc54 00000001 ed0e5dc0 00000002 c0090cec
bf60: c03ec85c ed0e5df4 00000000 ed839c00 c0487000 c04bcec0 c03e4f08 00000000
bf80: 00000000 00000000 00000000 00000000 00000000 c00086a8 00000000 c04bcec0
bfa0: c0344f5c c0345004 00000000 c000e398 00000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[<c00a7ab0>] (xattr_resolve_name) from [<00000000>] (  (null))
Code: e1a06000 e5915000 e3550000 0a00001d (e5900000) 
---[ end trace 15c15b4afa9eff90 ]---
swapper (1) used greatest stack depth: 5104 bytes left
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Adding a little hack, and could produce a better strack trace.
See the diff and the stack trace below:

diff --git a/fs/xattr.c b/fs/xattr.c
index 3377dff..bd2b173 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -740,6 +740,10 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
 
 	if (!*name)
 		return NULL;
+	if(!handlers) {
+		dump_stack();
+		panic("ouch");
+	}
 
 	for_each_xattr_handler(handlers, handler) {
 		const char *n = strcmp_prefix(*name, handler->prefix);

CPU: 0 PID: 1 Comm: swapper Tainted: G        W    3.13.0-10094-g9b0cd30-dirty #279
[<c0012f40>] (unwind_backtrace) from [<c00107b8>] (show_stack+0x10/0x14)
[<c00107b8>] (show_stack) from [<c00a8160>] (xattr_resolve_name+0x9c/0xa8)
[<c00a8160>] (xattr_resolve_name) from [<c00a8274>] (generic_getxattr+0x2c/0x64)
[<c00a8274>] (generic_getxattr) from [<c01115e0>] (get_vfs_caps_from_disk+0x4c/0xf4)
[<c01115e0>] (get_vfs_caps_from_disk) from [<c011170c>] (cap_bprm_set_creds+0x84/0x408)
[<c011170c>] (cap_bprm_set_creds) from [<c008fc54>] (prepare_binprm+0x80/0x11c)
[<c008fc54>] (prepare_binprm) from [<c0090cec>] (do_execve+0x33c/0x46c)
[<c0090cec>] (do_execve) from [<c00086a8>] (try_to_run_init_process+0x1c/0x50)
[<c00086a8>] (try_to_run_init_process) from [<c0345024>] (kernel_init+0xa8/0x110)
[<c0345024>] (kernel_init) from [<c000e398>] (ret_from_fork+0x14/0x3c)
Kernel panic - not syncing: ouch

FWIW, here's my piece of NFS config:

CONFIG_NFS_FS=y
CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_SWAP is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y

> I think it's down to this:
> 
> commit 013cdf1088d7235da9477a2375654921d9b9ba9f
> Author: Christoph Hellwig <hch@infradead.org>
> Date:   Fri Dec 20 05:16:53 2013 -0800
> 
>     nfs: use generic posix ACL infrastructure for v3 Posix ACLs
> 
>     This causes a small behaviour change in that we don't bother to set
>     ACLs on file creation if the mode bit can express the access permissions
>     fully, and thus behaving identical to local filesystems.
> 
>     Signed-off-by: Christoph Hellwig <hch@lst.de>
>     Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

And also here, reverting the above seem to fix the panic.

Ideas?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

^ permalink raw reply related

* [PATCH v2 1/2] drivers/media: v4l2: Add settings for Horizontal and Vertical MV Search Range
From: Kamil Debski @ 2014-01-30 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52EA00E5.10303@xs4all.nl>

Hi Hans, Amit,

> From: Hans Verkuil [mailto:hverkuil at xs4all.nl]
> Sent: Thursday, January 30, 2014 8:36 AM
> 
> On 01/30/2014 06:42 AM, Amit Grover wrote:
> > Adding V4L2 controls for horizontal and vertical search range in
> > pixels for motion estimation module in video encoder.
> >
> > Signed-off-by: Swami Nathan <swaminath.p@samsung.com>
> > Signed-off-by: Amit Grover <amit.grover@samsung.com>
> > ---
> >  Documentation/DocBook/media/v4l/controls.xml |   20
> ++++++++++++++++++++
> >  drivers/media/v4l2-core/v4l2-ctrls.c         |   14 ++++++++++++++
> >  include/uapi/linux/v4l2-controls.h           |    2 ++
> >  3 files changed, 36 insertions(+)
> >
> > diff --git a/Documentation/DocBook/media/v4l/controls.xml
> > b/Documentation/DocBook/media/v4l/controls.xml
> > index 7a3b49b..be04d18 100644
> > --- a/Documentation/DocBook/media/v4l/controls.xml
> > +++ b/Documentation/DocBook/media/v4l/controls.xml
> > @@ -2258,6 +2258,26 @@ Applicable to the MPEG1, MPEG2, MPEG4
> > encoders.</entry>  VBV buffer control.</entry>
> >  	      </row>
> >
> > +		  <row><entry></entry></row>
> > +	      <row id=""v4l2-mpeg-video-hor-search-range">
> > +		<entry
> spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE</constant
> >&nbsp;</entry>
> > +		<entry>integer</entry>
> > +	      </row>
> > +		<row><entry spanname="descr">Horizontal search range
> defines
> > +maximum horizontal search area in pixels to search and match for the
> > +present Macroblock (MB) in the reference picture. This V4L2 control
> macro is used to set horizontal search range for motion estimation
> module in video encoder.</entry>
> > +	      </row>
> > +
> > +		 <row><entry></entry></row>
> > +	      <row id="v4l2-mpeg-video-vert-search-range">
> > +		<entry
> spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE</constant
> >&nbsp;</entry>
> > +		<entry>integer</entry>
> 
> These two controls sound very mfc specific as opposed to being part of
> the standard.
> If so, then they should be named V4L2_CID_MPEG_MFC51_*. 

mencoder has an option to set motion vector search radius.

>From man mencoder:
       me_range=<4-64>
              radius  of  exhaustive  or multi-hexagon motion search
(default:
              16)

So I think it could be applicable to other hardware codecs as well.

> Also, for which codecs are these controls applicable?

Isn't the choice of motion estimation algorithm (and its parameters)
codec agnostic, as long as the restrictions of the standard are honoured?

> 
> > +	      </row>
> > +		<row><entry spanname="descr">Vertical search range defines
> maximum
> > +vertical search area in pixels to search and match for the present
> > +Macroblock (MB) in the reference picture. This V4L2 control macro is
> used to set vertical search range for motion estimation module in video
> encoder.</entry>
> > +	      </row>
> > +
> >  	      <row><entry></entry></row>
> >  	      <row>
> >  		<entry
> >
> spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE</constant>&n
> > bsp;</entry> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c
> > b/drivers/media/v4l2-core/v4l2-ctrls.c
> > index fb46790..e775388 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> > @@ -735,6 +735,8 @@ const char *v4l2_ctrl_get_name(u32 id)
> >  	case V4L2_CID_MPEG_VIDEO_DEC_PTS:			return
"Video
> Decoder PTS";
> >  	case V4L2_CID_MPEG_VIDEO_DEC_FRAME:			return
"Video
> Decoder Frame Count";
> >  	case V4L2_CID_MPEG_VIDEO_VBV_DELAY:			return
"Initial
> Delay for VBV Control";
> > +	case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:		return
> "Horizontal MV Search Range";
> > +	case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:		return
> "Vertical MV Search Range";
> >  	case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:		return
> "Repeat Sequence Header";
> >
> >  	/* VPX controls */
> > @@ -905,6 +907,18 @@ void v4l2_ctrl_fill(u32 id, const char **name,
> enum v4l2_ctrl_type *type,
> >  		*min = 0;
> >  		*max = *step = 1;
> >  		break;
> > +	case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
> > +		*type = V4L2_CTRL_TYPE_INTEGER;
> > +		*min = 16;
> > +		*max = 128;
> > +		*step = 16;
> 
> Weird range, why not use range 1-8?

If the search range is represented in pixels, then pixels should be used.
It the control is also used in other hardware, then I think it the values
should not be limited in this way here. For example mencoder accepts the
value between 4 and 64. The range and step could be limited in the
s5p_mfc_enc.c.

> 
> > +		break;
> > +	case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
> > +		*type = V4L2_CTRL_TYPE_INTEGER;
> > +		*min = 16;
> > +		*max = 128;
> > +		*step = 16;
> > +		break;
> >  	case V4L2_CID_PAN_RESET:
> >  	case V4L2_CID_TILT_RESET:
> >  	case V4L2_CID_FLASH_STROBE:
> > diff --git a/include/uapi/linux/v4l2-controls.h
> > b/include/uapi/linux/v4l2-controls.h
> > index 1666aab..80e1def 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -372,6 +372,8 @@ enum v4l2_mpeg_video_multi_slice_mode {
> >  #define V4L2_CID_MPEG_VIDEO_DEC_FRAME
> 	(V4L2_CID_MPEG_BASE+224)
> >  #define V4L2_CID_MPEG_VIDEO_VBV_DELAY
> 	(V4L2_CID_MPEG_BASE+225)
> >  #define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER
> 	(V4L2_CID_MPEG_BASE+226)
> > +#define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE
> 	(V4L2_CID_MPEG_BASE+227)
> > +#define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE
> 	(V4L2_CID_MPEG_BASE+228)
> >
> >  #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP
> 	(V4L2_CID_MPEG_BASE+300)
> >  #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP
> 	(V4L2_CID_MPEG_BASE+301)
> >
> 
> Regards,
> 
> 	Hans

Best wishes,
-- 
Kamil Debski
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH v2 6/6] cpu/idle.c: move to sched/idle.c
From: Peter Zijlstra @ 2014-01-30 15:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391017513-12995-7-git-send-email-nicolas.pitre@linaro.org>

On Wed, Jan 29, 2014 at 12:45:13PM -0500, Nicolas Pitre wrote:
> Integration of cpuidle with the scheduler requires that the idle loop be
> closely integrated with the scheduler proper. Moving cpu/idle.c into the
> sched directory will allow for a smoother integration, and eliminate a
> subdirectory which contained only one source file.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  kernel/Makefile              | 1 -
>  kernel/cpu/Makefile          | 1 -
>  kernel/sched/Makefile        | 2 +-
>  kernel/{cpu => sched}/idle.c | 0
>  4 files changed, 1 insertion(+), 3 deletions(-)
>  delete mode 100644 kernel/cpu/Makefile
>  rename kernel/{cpu => sched}/idle.c (100%)

> --- a/kernel/sched/Makefile
> +++ b/kernel/sched/Makefile
> @@ -11,7 +11,7 @@ ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
>  CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer
>  endif
>  
> -obj-y += core.o proc.o clock.o cputime.o idle_task.o fair.o rt.o stop_task.o
> +obj-y += core.o proc.o clock.o cputime.o idle_task.o idle.o fair.o rt.o stop_task.o
>  obj-y += wait.o completion.o
>  obj-$(CONFIG_SMP) += cpupri.o
>  obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
> diff --git a/kernel/cpu/idle.c b/kernel/sched/idle.c
> similarity index 100%
> rename from kernel/cpu/idle.c
> rename to kernel/sched/idle.c

This is not a valid patch for PATCH(1). Please try again.

^ permalink raw reply

* [PATCH v3 0/2] Qualcomm Universal Peripheral (QUP) I2C controller
From: Ivan T. Ivanov @ 2014-01-30 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJAp7Oj_D1QvG9nBWTVrW1QVEpqi2cTTc9c6Um25DDzidCjW1w@mail.gmail.com>


Hi Bjorn,

On Wed, 2014-01-29 at 08:32 -0800, Bjorn Andersson wrote: 
> On Wed, Jan 29, 2014 at 12:14 AM, Ivan T. Ivanov <iivanov@mm-sol.com> wrote:
> >
> > Hi Bjorn,
> >
> > On Fri, 2014-01-17 at 15:03 -0800, Bjorn Andersson wrote:
> >> Continuing on Ivans i2c-qup series.
> >>
> >
> > Do you plan to send v4 of this driver? I would like to address
> > the remaining errors and suggestions and send a new version.
> >
> Hi Ivan,
> 
> Yes I'm planning to send out a new revision of the patch set.
> 
> I've incorporated fixes from the review comments here and my colleague
> concluded through some testing that block read did not work, so we've
> fixed that as well.

Busted. I have not test it.

> 
> What have been holding me from submitting a new patchset is the 3
> functions that does polling of state and status updates;
> * qup_i2c_poll_state() reads the state register up to 1000 times,
> hoping we reach the expected state, will delay 100uS and then continue
> with 1000 more retries.
>   According to the data sheet a state transition is supposed to take
> up to 2 bus cycles. Only time I can see that this would take longer
> time are all error states, but the data sheet is not very clear
> regarding this.
> 
> * qup_i2c_wait_idle() reads the status register up to 1000 times,
> hoping the fifo gets drained and the bus go idle, if that fails it
> sleeps for the time we expect it to take to drain a full fifo and then
> loops another 1000 times. This waits for the fifo to have drained and
> the bus to go idle. On a read we get to this state if we issue the
> write and then hit the error state, so we would reset the entire
> block. On write we will only wait for the buffer not to be full before
> returning.
> 
> * qup_i2c_wait_clock_ready() waits up to 300 bus-clocks for the i2c
> bus to go idle or forced low, I don't know why it retries 300 times.
> This is called at the end of a write, possibly to wait for the fifo to
> drain.
> 
> 
> All three loops are in line with how it's been in codeaurora since the
> beginning of time, but I at least need to figure out some good names
> for those "magic numbers".


Sure. I have keep them this way, just because I don't have information
for internal trickery of the block.

Thanks, 
Ivan


> 
> Regards,
> Bjorn

^ permalink raw reply

* NFS client broken in Linus' tip
From: Russell King - ARM Linux @ 2014-01-30 15:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140130143208.GB9573@infradead.org>

On Thu, Jan 30, 2014 at 06:32:08AM -0800, Christoph Hellwig wrote:
> On Thu, Jan 30, 2014 at 02:27:52PM +0000, Russell King - ARM Linux wrote:
> > Yes and no.  I still end up with an empty /etc/mtab, but the file now
> > exists.  However, I can create and echo data into /etc/mtab, but it seems
> > that can't happen at boot time.
> 
> Odd.  Can you disable CONFIG_NFSD_V3_ACL for now to isolate the issue?

Unfortunately, that results in some problem at boot time, which
ultimately ends up with the other three CPUs being stopped, and
hence the original reason scrolls off the screen before it can be
read... even at 1920p.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH v3 2/8] clk: sunxi: update clock-output-names dt binding documentation
From: Maxime Ripard @ 2014-01-30 15:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGb2v66+N9tgOO4X093WdiR4J+7Sk2TDVsMffDGo46iTezPQwA@mail.gmail.com>

Hi Chen-Yu,

On Wed, Jan 29, 2014 at 09:52:57AM +0800, Chen-Yu Tsai wrote:
> Hi Maxime,
> 
> On Fri, Jan 17, 2014 at 10:55 AM, Emilio L?pez <emilio@elopez.com.ar> wrote:
> > Hi,
> >
> > El 09/01/14 05:52, Chen-Yu Tsai escribi?:
> >
> >> clock-output-names is now required for most of sunxi clock nodes, to
> >> provide the name of the corresponding clock. Add the new requirements,
> >> exceptions, as well as examples.
> >>
> >> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> >> ---
> >>   Documentation/devicetree/bindings/clock/sunxi.txt | 36
> >> +++++++++++++++++++----
> >>   1 file changed, 31 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt
> >> b/Documentation/devicetree/bindings/clock/sunxi.txt
> >> index 0c127cd..8a9147d 100644
> >> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> >> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> >> @@ -44,10 +44,18 @@ Required properties for all clocks:
> >>         multiplexed clocks, the list order must match the hardware
> >>         programming order.
> >>   - #clock-cells : from common clock binding; shall be set to 0 except for
> >> -       "allwinner,*-gates-clk" where it shall be set to 1
> >> +       "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and
> >> +       "allwinner,sun4i-pll6-clk" where it shall be set to 1
> >>
> >> -Additionally, "allwinner,*-gates-clk" clocks require:
> >> -- clock-output-names : the corresponding gate names that the clock
> >> controls
> >> +Additionally, most clocks require "clock-output-names":
> >> +- "allwinner,*-gates-clk" : the corresponding gate names that the clock
> >> controls
> >> +- "allwinner,sun4i-pll5-clk" : "pll5_ddr", "pll5_mbus"
> >> +- "allwinner,sun4i-pll6-clk" : "pll6_sata", "pll6_other"
> >> +- "allwinner,sun4i-cpu-clk", "allwinner,sun4i-axi-clk",
> >> +  "allwinner,sun4i-ahb-clk", "allwinner,sun4i-ahb-clk",
> >> +  "allwinner,sun4i-apb1-mux-clk", "allwinner,sun4i-apb1-clk"
> >> +  do not need "clock-output-names"
> >> +- all others clocks : the corresponding module name of that clock
> >
> >
> > As we discussed on IRC, I wonder if such verbosity is actually needed. Maybe
> > we should dictate that all clocks must list their corresponding outputs on
> > clock-output-names (with it being the module name if it only has one
> > output).
> 
> Maxime, could we get your input on this?

I didn't get it was a question for me. But I'm fine with both. If
making clock-output-names mandatory makes our life easier, let's do
it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- 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/20140130/f0d18584/attachment.sig>

^ permalink raw reply

* 'unannotated irqs-on' lockdep warning
From: Russell King - ARM Linux @ 2014-01-30 15:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAH9NwWcVrjV1=rFnHJhDH0yoEkTwUTcq-Tn=R0aaiTr70Fs3hA@mail.gmail.com>

On Thu, Jan 30, 2014 at 03:31:46PM +0100, Christian Gmeiner wrote:
> [   19.859234] CPU: 0 PID: 1848 Comm: mkdir Not tainted 3.12.4 #44
> [   19.865190] [<c0013900>] (unwind_backtrace+0x0/0xe0) from
> [<c00113b8>] (show_stack+0x10/0x14)
> [   19.873739] [<c00113b8>] (show_stack+0x10/0x14) from [<c044e040>]
> (dump_stack+0x64/0xa4)
> [   19.881851] [<c044e040>] (dump_stack+0x64/0xa4) from [<c0022718>]
> (warn_slowpath_common+0x64/0x84)
> [   19.890828] [<c0022718>] (warn_slowpath_common+0x64/0x84) from
> [<c00227b8>] (warn_slowpath_fmt+0x2c/0x3c)
> [   19.900413] [<c00227b8>] (warn_slowpath_fmt+0x2c/0x3c) from
> [<c0076c84>] (check_flags.part.26+0xb4/0x1e4)
> [   19.910001] [<c0076c84>] (check_flags.part.26+0xb4/0x1e4) from
> [<c0079654>] (lock_release+0x3c/0x100)
> [   19.919243] [<c0079654>] (lock_release+0x3c/0x100) from
> [<c00485b4>] (lg_local_unlock+0x18/0x6c)
> [   19.928055] [<c00485b4>] (lg_local_unlock+0x18/0x6c) from
> [<c012a2cc>] (free_fs_struct+0x18/0x30)
> [   19.936947] [<c012a2cc>] (free_fs_struct+0x18/0x30) from
> [<c0024e24>] (do_exit+0x2ac/0x3f0)
> [   19.945316] [<c0024e24>] (do_exit+0x2ac/0x3f0) from [<c002501c>]
> (do_group_exit+0x88/0xb4)
> [   19.953596] [<c002501c>] (do_group_exit+0x88/0xb4) from
> [<c0025058>] (__wake_up_parent+0x0/0x18)
> [   19.962391] ---[ end trace 98a70b5cdc7b49fe ]---
> [   19.967017] possible reason: unannotated irqs-on.
> [   19.971729] irq event stamp: 2910
> [   19.975050] hardirqs last  enabled at (2909): [<c044a160>]
> __slab_free+0x1c0/0x390
> [   19.982661] hardirqs last disabled at (2910): [<c0456d14>]
> __dabt_svc+0x34/0x60

So, I wonder how we got from __dabt_svc to __wake_up_parent.  It looks
like the unwinder has failed to do a proper job of unwinding, which
makes this undebuggable.

Can you rebuild in ARM mode with frame pointers enabled please?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH v2 6/6] cpu/idle.c: move to sched/idle.c
From: Nicolas Pitre @ 2014-01-30 16:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140130152500.GB5002@laptop.programming.kicks-ass.net>

On Thu, 30 Jan 2014, Peter Zijlstra wrote:

> On Wed, Jan 29, 2014 at 12:45:13PM -0500, Nicolas Pitre wrote:
> > Integration of cpuidle with the scheduler requires that the idle loop be
> > closely integrated with the scheduler proper. Moving cpu/idle.c into the
> > sched directory will allow for a smoother integration, and eliminate a
> > subdirectory which contained only one source file.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> >  kernel/Makefile              | 1 -
> >  kernel/cpu/Makefile          | 1 -
> >  kernel/sched/Makefile        | 2 +-
> >  kernel/{cpu => sched}/idle.c | 0
> >  4 files changed, 1 insertion(+), 3 deletions(-)
> >  delete mode 100644 kernel/cpu/Makefile
> >  rename kernel/{cpu => sched}/idle.c (100%)
> 
> > --- a/kernel/sched/Makefile
> > +++ b/kernel/sched/Makefile
> > @@ -11,7 +11,7 @@ ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
> >  CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer
> >  endif
> >  
> > -obj-y += core.o proc.o clock.o cputime.o idle_task.o fair.o rt.o stop_task.o
> > +obj-y += core.o proc.o clock.o cputime.o idle_task.o idle.o fair.o rt.o stop_task.o
> >  obj-y += wait.o completion.o
> >  obj-$(CONFIG_SMP) += cpupri.o
> >  obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
> > diff --git a/kernel/cpu/idle.c b/kernel/sched/idle.c
> > similarity index 100%
> > rename from kernel/cpu/idle.c
> > rename to kernel/sched/idle.c
> 
> This is not a valid patch for PATCH(1). Please try again.

Don't you use git?  ;-)

Here's a plain patch:

----- >8

>From 1bf40eb80a44633094e94986a74bd5ffa222f9d4 Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nicolas.pitre@linaro.org>
Date: Sun, 26 Jan 2014 23:42:01 -0500
Subject: [PATCH] cpu/idle.c: move to sched/idle.c

Integration of cpuidle with the scheduler requires that the idle loop be
closely integrated with the scheduler proper. Moving cpu/idle.c into the
sched directory will allow for a smoother integration, and eliminate a
subdirectory which contained only one source file.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 kernel/Makefile       |   1 -
 kernel/cpu/Makefile   |   1 -
 kernel/cpu/idle.c     | 144 --------------------------------------------------
 kernel/sched/Makefile |   2 +-
 kernel/sched/idle.c   | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 145 insertions(+), 147 deletions(-)
 delete mode 100644 kernel/cpu/Makefile
 delete mode 100644 kernel/cpu/idle.c
 create mode 100644 kernel/sched/idle.c

diff --git a/kernel/Makefile b/kernel/Makefile
index bc010ee272..6f1c7e5cfc 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -22,7 +22,6 @@ obj-y += sched/
 obj-y += locking/
 obj-y += power/
 obj-y += printk/
-obj-y += cpu/
 obj-y += irq/
 obj-y += rcu/
 
diff --git a/kernel/cpu/Makefile b/kernel/cpu/Makefile
deleted file mode 100644
index 59ab052ef7..0000000000
--- a/kernel/cpu/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y	= idle.o
diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c
deleted file mode 100644
index 14ca43430a..0000000000
--- a/kernel/cpu/idle.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Generic entry point for the idle threads
- */
-#include <linux/sched.h>
-#include <linux/cpu.h>
-#include <linux/cpuidle.h>
-#include <linux/tick.h>
-#include <linux/mm.h>
-#include <linux/stackprotector.h>
-
-#include <asm/tlb.h>
-
-#include <trace/events/power.h>
-
-static int __read_mostly cpu_idle_force_poll;
-
-void cpu_idle_poll_ctrl(bool enable)
-{
-	if (enable) {
-		cpu_idle_force_poll++;
-	} else {
-		cpu_idle_force_poll--;
-		WARN_ON_ONCE(cpu_idle_force_poll < 0);
-	}
-}
-
-#ifdef CONFIG_GENERIC_IDLE_POLL_SETUP
-static int __init cpu_idle_poll_setup(char *__unused)
-{
-	cpu_idle_force_poll = 1;
-	return 1;
-}
-__setup("nohlt", cpu_idle_poll_setup);
-
-static int __init cpu_idle_nopoll_setup(char *__unused)
-{
-	cpu_idle_force_poll = 0;
-	return 1;
-}
-__setup("hlt", cpu_idle_nopoll_setup);
-#endif
-
-static inline int cpu_idle_poll(void)
-{
-	rcu_idle_enter();
-	trace_cpu_idle_rcuidle(0, smp_processor_id());
-	local_irq_enable();
-	while (!tif_need_resched())
-		cpu_relax();
-	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
-	rcu_idle_exit();
-	return 1;
-}
-
-/* Weak implementations for optional arch specific functions */
-void __weak arch_cpu_idle_prepare(void) { }
-void __weak arch_cpu_idle_enter(void) { }
-void __weak arch_cpu_idle_exit(void) { }
-void __weak arch_cpu_idle_dead(void) { }
-void __weak arch_cpu_idle(void)
-{
-	cpu_idle_force_poll = 1;
-	local_irq_enable();
-}
-
-/*
- * Generic idle loop implementation
- */
-static void cpu_idle_loop(void)
-{
-	while (1) {
-		tick_nohz_idle_enter();
-
-		while (!need_resched()) {
-			check_pgt_cache();
-			rmb();
-
-			if (cpu_is_offline(smp_processor_id()))
-				arch_cpu_idle_dead();
-
-			local_irq_disable();
-			arch_cpu_idle_enter();
-
-			/*
-			 * In poll mode we reenable interrupts and spin.
-			 *
-			 * Also if we detected in the wakeup from idle
-			 * path that the tick broadcast device expired
-			 * for us, we don't want to go deep idle as we
-			 * know that the IPI is going to arrive right
-			 * away
-			 */
-			if (cpu_idle_force_poll || tick_check_broadcast_expired()) {
-				cpu_idle_poll();
-			} else {
-				if (!current_clr_polling_and_test()) {
-					stop_critical_timings();
-					rcu_idle_enter();
-					if (cpuidle_idle_call())
-						arch_cpu_idle();
-					if (WARN_ON_ONCE(irqs_disabled()))
-						local_irq_enable();
-					rcu_idle_exit();
-					start_critical_timings();
-				} else {
-					local_irq_enable();
-				}
-				__current_set_polling();
-			}
-			arch_cpu_idle_exit();
-			/*
-			 * We need to test and propagate the TIF_NEED_RESCHED
-			 * bit here because we might not have send the
-			 * reschedule IPI to idle tasks.
-			 */
-			if (tif_need_resched())
-				set_preempt_need_resched();
-		}
-		tick_nohz_idle_exit();
-		schedule_preempt_disabled();
-	}
-}
-
-void cpu_startup_entry(enum cpuhp_state state)
-{
-	/*
-	 * This #ifdef needs to die, but it's too late in the cycle to
-	 * make this generic (arm and sh have never invoked the canary
-	 * init for the non boot cpus!). Will be fixed in 3.11
-	 */
-#ifdef CONFIG_X86
-	/*
-	 * If we're the non-boot CPU, nothing set the stack canary up
-	 * for us. The boot CPU already has it initialized but no harm
-	 * in doing it again. This is a good place for updating it, as
-	 * we wont ever return from this function (so the invalid
-	 * canaries already on the stack wont ever trigger).
-	 */
-	boot_init_stack_canary();
-#endif
-	__current_set_polling();
-	arch_cpu_idle_prepare();
-	cpu_idle_loop();
-}
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
index 7b621409cf..ac3e0ea68f 100644
--- a/kernel/sched/Makefile
+++ b/kernel/sched/Makefile
@@ -11,7 +11,7 @@ ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer
 endif
 
-obj-y += core.o proc.o clock.o cputime.o idle_task.o fair.o rt.o stop_task.o
+obj-y += core.o proc.o clock.o cputime.o idle_task.o idle.o fair.o rt.o stop_task.o
 obj-y += wait.o completion.o
 obj-$(CONFIG_SMP) += cpupri.o
 obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
new file mode 100644
index 0000000000..14ca43430a
--- /dev/null
+++ b/kernel/sched/idle.c
@@ -0,0 +1,144 @@
+/*
+ * Generic entry point for the idle threads
+ */
+#include <linux/sched.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/tick.h>
+#include <linux/mm.h>
+#include <linux/stackprotector.h>
+
+#include <asm/tlb.h>
+
+#include <trace/events/power.h>
+
+static int __read_mostly cpu_idle_force_poll;
+
+void cpu_idle_poll_ctrl(bool enable)
+{
+	if (enable) {
+		cpu_idle_force_poll++;
+	} else {
+		cpu_idle_force_poll--;
+		WARN_ON_ONCE(cpu_idle_force_poll < 0);
+	}
+}
+
+#ifdef CONFIG_GENERIC_IDLE_POLL_SETUP
+static int __init cpu_idle_poll_setup(char *__unused)
+{
+	cpu_idle_force_poll = 1;
+	return 1;
+}
+__setup("nohlt", cpu_idle_poll_setup);
+
+static int __init cpu_idle_nopoll_setup(char *__unused)
+{
+	cpu_idle_force_poll = 0;
+	return 1;
+}
+__setup("hlt", cpu_idle_nopoll_setup);
+#endif
+
+static inline int cpu_idle_poll(void)
+{
+	rcu_idle_enter();
+	trace_cpu_idle_rcuidle(0, smp_processor_id());
+	local_irq_enable();
+	while (!tif_need_resched())
+		cpu_relax();
+	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
+	rcu_idle_exit();
+	return 1;
+}
+
+/* Weak implementations for optional arch specific functions */
+void __weak arch_cpu_idle_prepare(void) { }
+void __weak arch_cpu_idle_enter(void) { }
+void __weak arch_cpu_idle_exit(void) { }
+void __weak arch_cpu_idle_dead(void) { }
+void __weak arch_cpu_idle(void)
+{
+	cpu_idle_force_poll = 1;
+	local_irq_enable();
+}
+
+/*
+ * Generic idle loop implementation
+ */
+static void cpu_idle_loop(void)
+{
+	while (1) {
+		tick_nohz_idle_enter();
+
+		while (!need_resched()) {
+			check_pgt_cache();
+			rmb();
+
+			if (cpu_is_offline(smp_processor_id()))
+				arch_cpu_idle_dead();
+
+			local_irq_disable();
+			arch_cpu_idle_enter();
+
+			/*
+			 * In poll mode we reenable interrupts and spin.
+			 *
+			 * Also if we detected in the wakeup from idle
+			 * path that the tick broadcast device expired
+			 * for us, we don't want to go deep idle as we
+			 * know that the IPI is going to arrive right
+			 * away
+			 */
+			if (cpu_idle_force_poll || tick_check_broadcast_expired()) {
+				cpu_idle_poll();
+			} else {
+				if (!current_clr_polling_and_test()) {
+					stop_critical_timings();
+					rcu_idle_enter();
+					if (cpuidle_idle_call())
+						arch_cpu_idle();
+					if (WARN_ON_ONCE(irqs_disabled()))
+						local_irq_enable();
+					rcu_idle_exit();
+					start_critical_timings();
+				} else {
+					local_irq_enable();
+				}
+				__current_set_polling();
+			}
+			arch_cpu_idle_exit();
+			/*
+			 * We need to test and propagate the TIF_NEED_RESCHED
+			 * bit here because we might not have send the
+			 * reschedule IPI to idle tasks.
+			 */
+			if (tif_need_resched())
+				set_preempt_need_resched();
+		}
+		tick_nohz_idle_exit();
+		schedule_preempt_disabled();
+	}
+}
+
+void cpu_startup_entry(enum cpuhp_state state)
+{
+	/*
+	 * This #ifdef needs to die, but it's too late in the cycle to
+	 * make this generic (arm and sh have never invoked the canary
+	 * init for the non boot cpus!). Will be fixed in 3.11
+	 */
+#ifdef CONFIG_X86
+	/*
+	 * If we're the non-boot CPU, nothing set the stack canary up
+	 * for us. The boot CPU already has it initialized but no harm
+	 * in doing it again. This is a good place for updating it, as
+	 * we wont ever return from this function (so the invalid
+	 * canaries already on the stack wont ever trigger).
+	 */
+	boot_init_stack_canary();
+#endif
+	__current_set_polling();
+	arch_cpu_idle_prepare();
+	cpu_idle_loop();
+}
-- 
1.8.4.108.g55ea5f6

^ permalink raw reply related

* [PATCH v2 1/6] idle: move the cpuidle entry point to the generic idle loop
From: Nicolas Pitre @ 2014-01-30 16:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52EA5720.8010000@linaro.org>

On Thu, 30 Jan 2014, Daniel Lezcano wrote:

> On 01/30/2014 06:28 AM, Nicolas Pitre wrote:
> > On Thu, 30 Jan 2014, Preeti U Murthy wrote:
> >
> > > Hi Nicolas,
> > >
> > > On 01/30/2014 02:01 AM, Nicolas Pitre wrote:
> > > > On Wed, 29 Jan 2014, Nicolas Pitre wrote:
> > > >
> > > > > In order to integrate cpuidle with the scheduler, we must have a
> > > > > better
> > > > > proximity in the core code with what cpuidle is doing and not delegate
> > > > > such interaction to arch code.
> > > > >
> > > > > Architectures implementing arch_cpu_idle() should simply enter
> > > > > a cheap idle mode in the absence of a proper cpuidle driver.
> > > > >
> > > > > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > > > > Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > > >
> > > > As mentioned in my reply to Olof's comment on patch #5/6, here's a new
> > > > version of this patch adding the safety local_irq_enable() to the core
> > > > code.
> > > >
> > > > ----- >8
> > > >
> > > > From: Nicolas Pitre <nicolas.pitre@linaro.org>
> > > > Subject: idle: move the cpuidle entry point to the generic idle loop
> > > >
> > > > In order to integrate cpuidle with the scheduler, we must have a better
> > > > proximity in the core code with what cpuidle is doing and not delegate
> > > > such interaction to arch code.
> > > >
> > > > Architectures implementing arch_cpu_idle() should simply enter
> > > > a cheap idle mode in the absence of a proper cpuidle driver.
> > > >
> > > > In both cases i.e. whether it is a cpuidle driver or the default
> > > > arch_cpu_idle(), the calling convention expects IRQs to be disabled
> > > > on entry and enabled on exit. There is a warning in place already but
> > > > let's add a forced IRQ enable here as well.  This will allow for
> > > > removing the forced IRQ enable some implementations do locally and
> > >
> > > Why would this patch allow for removing the forced IRQ enable that are
> > > being done on some archs in arch_cpu_idle()? Isn't this patch expecting
> > > the default arch_cpu_idle() to have re-enabled the interrupts after
> > > exiting from the default idle state? Its supposed to only catch faulty
> > > cpuidle drivers that haven't enabled IRQs on exit from idle state but
> > > are expected to have done so, isn't it?
> >
> > Exact.  However x86 currently does this:
> >
> >  if (cpuidle_idle_call())
> >          x86_idle();
> >  else
> >          local_irq_enable();
> >
> > So whenever cpuidle_idle_call() is successful then IRQs are
> > unconditionally enabled whether or not the underlying cpuidle driver has
> > properly done it or not.  And the reason is that some of the x86 cpuidle
> > do fail to enable IRQs before returning.
> >
> > So the idea is to get rid of this unconditional IRQ enabling and let the
> > core issue a warning instead (as well as enabling IRQs to allow the
> > system to run).
> 
> But what I don't get with your comment is the local_irq_enable is done from
> the cpuidle common framework in 'cpuidle_enter_state' it is not done from the
> arch specific backend cpuidle driver.

Oh well... This certainly means we'll have to clean this mess as some 
drivers do it on their own while some others don't.  Some drivers also 
loop on !need_resched() while some others simply return on the first 
interrupt.

> So the code above could be:
> 
> 	if (cpuidle_idle_call())
> 		x86_idle();
> 
> without the else section, this local_irq_enable is pointless. Or may be I
> missed something ?

A later patch removes it anyway.  But if it is really necessary to 
enable interrupts then the core will do it but with a warning now.


Nicolas

^ permalink raw reply

* Root NFS panicing on Linus' tip (Re: NFS client broken in Linus' tip)
From: Russell King - ARM Linux @ 2014-01-30 16:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140130151703.GA20594@localhost>

On Thu, Jan 30, 2014 at 12:17:04PM -0300, Ezequiel Garcia wrote:
> Hi Russell, Trond:
> 
> On Thu, Jan 30, 2014 at 02:08:34PM +0000, Russell King - ARM Linux wrote:
> > I just booted Linus' tip (plus a few other patches to imx-drm and imx
> > code), and stumbled into this interesting scenario:
> > 
> [..]
> 
> > CONFIG_NFS_FS=y
> > CONFIG_NFS_V2=y
> > CONFIG_NFS_V3=y
> > CONFIG_NFS_V3_ACL=y
> 
> Just came across another issue, but a bit more problematic, as my
> kernel (Linus' tip as well) panics, after mounting the rootfs:
> 
> IP-Config: Complete:
>      device=eth0, hwaddr=00:50:43:50:1c:15, ipaddr=192.168.0.159, mask=255.255.255.0, gw=192.168.0.1
>      host=develboard, domain=, nis-domain=(none)
>      bootserver=192.168.0.45, rootserver=192.168.0.45, rootpath=
> VFS: Mounted root (nfs filesystem) on device 0:11.
> devtmpfs: mounted
> Freeing unused kernel memory: 136K (c0465000 - c0487000)
> Unable to handle kernel NULL pointer dereference at virtual address 00000000
> pgd = c0004000
> [00000000] *pgd=00000000
> Internal error: Oops: 5 [#1] ARM
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper Tainted: G        W    3.13.0-10094-g9b0cd30 #276
> task: ed839a40 ti: ed83a000 task.ti: ed83a000
> PC is at xattr_resolve_name+0x14/0x94
> LR is at generic_getxattr+0x2c/0x64
> pc : [<c00a7ab0>]    lr : [<c00a7b5c>]    psr: a0000113
> sp : ed83be5c  ip : ed83be74  fp : ed10ebc0
> r10: ed83a000  r9 : ed43d980  r8 : ed81b800
> r7 : c034dad8  r6 : 00000000  r5 : c03f3dcc  r4 : ed43d980
> r3 : 00000014  r2 : ed83be8c  r1 : ed83be74  r0 : 00000000
> Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
> Control: 10c53c7d  Table: 00004059  DAC: 00000015
> Process swapper (pid: 1, stack limit = 0xed83a238)
> Stack: (0xed83be5c to 0xed83c000)
> be40:                                                                ed43d980
> be60: 00000014 ed83be8c 00000000 00000000 c04bc22c c03f3dcc ed83bf14 ed43f340
> be80: ed43d980 c01115cc 00000000 00000041 c04bba6c 00000000 00000000 002040d0
> bea0: ed81bc00 ed10ebc0 ed81bc30 c01116f8 00000000 000004d0 ed8172d0 ed43d980
> bec0: 45878fd4 00000007 bfe01007 ef7f8fc0 c04bba6c ed43d6d8 c04bba6c 00000101
> bee0: 00000000 ed809fd0 ed809fc0 ed809f50 ed809f40 00000000 edb045d8 c0078bcc
> bf00: ed0e5dc0 edb045d8 00000000 bf000000 ed0e5dc0 00000000 00000000 00000000
> bf20: 00000000 00000000 bf000000 ed10ebc0 ed0e5dc0 00000001 edb045d8 c04926d0
> bf40: ed83a000 c0492758 ed10ebc0 c008fc54 00000001 ed0e5dc0 00000002 c0090cec
> bf60: c03ec85c ed0e5df4 00000000 ed839c00 c0487000 c04bcec0 c03e4f08 00000000
> bf80: 00000000 00000000 00000000 00000000 00000000 c00086a8 00000000 c04bcec0
> bfa0: c0344f5c c0345004 00000000 c000e398 00000000 00000000 00000000 00000000
> bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [<c00a7ab0>] (xattr_resolve_name) from [<00000000>] (  (null))
> Code: e1a06000 e5915000 e3550000 0a00001d (e5900000) 
> ---[ end trace 15c15b4afa9eff90 ]---
> swapper (1) used greatest stack depth: 5104 bytes left
> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> Adding a little hack, and could produce a better strack trace.
> See the diff and the stack trace below:
> 
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 3377dff..bd2b173 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -740,6 +740,10 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
>  
>  	if (!*name)
>  		return NULL;
> +	if(!handlers) {
> +		dump_stack();
> +		panic("ouch");
> +	}
>  
>  	for_each_xattr_handler(handlers, handler) {
>  		const char *n = strcmp_prefix(*name, handler->prefix);
> 
> CPU: 0 PID: 1 Comm: swapper Tainted: G        W    3.13.0-10094-g9b0cd30-dirty #279
> [<c0012f40>] (unwind_backtrace) from [<c00107b8>] (show_stack+0x10/0x14)
> [<c00107b8>] (show_stack) from [<c00a8160>] (xattr_resolve_name+0x9c/0xa8)
> [<c00a8160>] (xattr_resolve_name) from [<c00a8274>] (generic_getxattr+0x2c/0x64)
> [<c00a8274>] (generic_getxattr) from [<c01115e0>] (get_vfs_caps_from_disk+0x4c/0xf4)
> [<c01115e0>] (get_vfs_caps_from_disk) from [<c011170c>] (cap_bprm_set_creds+0x84/0x408)
> [<c011170c>] (cap_bprm_set_creds) from [<c008fc54>] (prepare_binprm+0x80/0x11c)
> [<c008fc54>] (prepare_binprm) from [<c0090cec>] (do_execve+0x33c/0x46c)
> [<c0090cec>] (do_execve) from [<c00086a8>] (try_to_run_init_process+0x1c/0x50)
> [<c00086a8>] (try_to_run_init_process) from [<c0345024>] (kernel_init+0xa8/0x110)
> [<c0345024>] (kernel_init) from [<c000e398>] (ret_from_fork+0x14/0x3c)
> Kernel panic - not syncing: ouch
> 
> FWIW, here's my piece of NFS config:
> 
> CONFIG_NFS_FS=y
> CONFIG_NFS_V2=y
> CONFIG_NFS_V3=y
> # CONFIG_NFS_V3_ACL is not set
> # CONFIG_NFS_V4 is not set
> # CONFIG_NFS_SWAP is not set
> CONFIG_ROOT_NFS=y
> # CONFIG_NFSD is not set
> CONFIG_LOCKD=y
> CONFIG_LOCKD_V4=y
> CONFIG_NFS_COMMON=y
> CONFIG_SUNRPC=y
> 
> > I think it's down to this:
> > 
> > commit 013cdf1088d7235da9477a2375654921d9b9ba9f
> > Author: Christoph Hellwig <hch@infradead.org>
> > Date:   Fri Dec 20 05:16:53 2013 -0800
> > 
> >     nfs: use generic posix ACL infrastructure for v3 Posix ACLs
> > 
> >     This causes a small behaviour change in that we don't bother to set
> >     ACLs on file creation if the mode bit can express the access permissions
> >     fully, and thus behaving identical to local filesystems.
> > 
> >     Signed-off-by: Christoph Hellwig <hch@lst.de>
> >     Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> 
> And also here, reverting the above seem to fix the panic.

Reverting this commit with NFS3 ACLs enabled also fixes the problems I
reported.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [GIT PULL] Xilinx Zynq dt fixes for v3.14
From: Michal Simek @ 2014-01-30 16:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi guys,

please consider to queue this patch to 3.14 because it enables Arasan
SDHCI driver which has been merged to the tree. It took for a while
to get it to the mainline that's why I didn't push this patch
in regular arm-soc merge window. I was talking about it
with Kevin some weeks ago.

There will be one more patch which I have discussed with Russell but
I will send it out for reviewed first.
https://lkml.org/lkml/2014/1/27/212

Thanks,
Michal


The following changes since commit 9b0cd304f26b9fca140de15deeac2bf357d1f388:

  Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux (2014-01-29 20:49:12 -0800)

are available in the git repository at:


  git://git.xilinx.com/linux-xlnx.git tags/zynq-dt-fixes-for-3.14

for you to fetch changes up to b1d30fb5b8618e69195fb074b89c204cb1bb2262:

  arm: dt: zynq: Add SDHCI nodes (2014-01-30 12:28:03 +0100)

----------------------------------------------------------------
arm: Xilinx Zynq DT fixes for v3.14

- Enable Arasan SDHCI driver

----------------------------------------------------------------
Soren Brinkmann (1):
      arm: dt: zynq: Add SDHCI nodes

 arch/arm/boot/dts/zynq-7000.dtsi | 20 ++++++++++++++++++++
 arch/arm/boot/dts/zynq-zc702.dts |  4 ++++
 arch/arm/boot/dts/zynq-zc706.dts |  4 ++++
 arch/arm/boot/dts/zynq-zed.dts   |  4 ++++
 4 files changed, 32 insertions(+)


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140130/e3b3b418/attachment.sig>

^ permalink raw reply

* [PATCH] arm: document "mach-virt" platform.
From: Ian Campbell @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

mach-virt has existed for a while but it is not written down what it actually
consists of. Although it seems a bit unusual to document a binding for an
entire platform since mach-virt is entirely virtual it is helpful to have
something to refer to in the absence of a single concrete implementation.

I've done my best to capture the requirements based on the git log and my
memory/understanding.

While here remove the xenvm dts example, the Xen tools will now build a
suitable mach-virt compatible dts when launching the guest.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: Olof Johansson <olof@lixom.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
I'm not sure which tree this sort of thing should go though, sorry for the
huge Cc.
---
 .../devicetree/bindings/arm/mach-virt.txt          |   32 ++++++++
 arch/arm/boot/dts/xenvm-4.2.dts                    |   81 --------------------
 2 files changed, 32 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mach-virt.txt
 delete mode 100644 arch/arm/boot/dts/xenvm-4.2.dts

diff --git a/Documentation/devicetree/bindings/arm/mach-virt.txt b/Documentation/devicetree/bindings/arm/mach-virt.txt
new file mode 100644
index 0000000..562bcda
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mach-virt.txt
@@ -0,0 +1,32 @@
+* Mach-virt "Dummy Virtual Machine" platform
+
+"mach-virt" is the smallest, dumbest platform possible, to be used as
+a guest for Xen, KVM and other hypervisors. It has no
+properties/functionality of its own and is driven entirely by device
+tree.
+
+This document defines the requirements for such a platform.
+
+* Required properties:
+
+- compatible: should be one of:
+	"linux,dummy-virt"
+	"xen,xenvm"
+
+In addition to the standard nodes (chosen, cpus, memory etc) the
+platform is required to provide certain other basic functionality
+which must be described in the device tree:
+
+    The platform must provide an ARM Generic Interrupt Controller
+    (GIC), defined in Documentation/devicetree/bindings/arm/gic.txt.
+
+    The platform must provide ARM architected timer, defined in
+    Documentation/devicetree/bindings/arm/arch_timer.txt.
+
+    If the platform is SMP then it must provide the Power State
+    Coordination Interface (PSCI) described in
+    Documentation/devicetree/bindings/arm/psci.txt.
+
+The platform may also provide hypervisor specific functionality
+(e.g. PV I/O), if it does so then this functionality must be
+discoverable (directly or indirectly) via device tree.
diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts
deleted file mode 100644
index 3369151..0000000
--- a/arch/arm/boot/dts/xenvm-4.2.dts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Xen Virtual Machine for unprivileged guests
- *
- * Based on ARM Ltd. Versatile Express CoreTile Express (single CPU)
- * Cortex-A15 MPCore (V2P-CA15)
- *
- */
-
-/dts-v1/;
-
-/ {
-	model = "XENVM-4.2";
-	compatible = "xen,xenvm-4.2", "xen,xenvm";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	chosen {
-		/* this field is going to be adjusted by the hypervisor */
-		bootargs = "console=hvc0 root=/dev/xvda";
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu at 0 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <0>;
-		};
-
-		cpu at 1 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a15";
-			reg = <1>;
-		};
-	};
-
-	psci {
-		compatible      = "arm,psci";
-		method          = "hvc";
-		cpu_off         = <1>;
-		cpu_on          = <2>;
-	};
-
-	memory at 80000000 {
-		device_type = "memory";
-		/* this field is going to be adjusted by the hypervisor */
-		reg = <0 0x80000000 0 0x08000000>;
-	};
-
-	gic: interrupt-controller at 2c001000 {
-		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0 0x2c001000 0 0x1000>,
-		      <0 0x2c002000 0 0x100>;
-	};
-
-	timer {
-		compatible = "arm,armv7-timer";
-		interrupts = <1 13 0xf08>,
-			     <1 14 0xf08>,
-			     <1 11 0xf08>,
-			     <1 10 0xf08>;
-	};
-
-	hypervisor {
-		compatible = "xen,xen-4.2", "xen,xen";
-		/* this field is going to be adjusted by the hypervisor */
-		reg = <0 0xb0000000 0 0x20000>;
-		/* this field is going to be adjusted by the hypervisor */
-		interrupts = <1 15 0xf08>;
-	};
-
-	motherboard {
-		arm,v2m-memory-map = "rs1";
-	};
-};
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH V3 0/5] ARM CoreSight: ETM: Fix a vmalloc/vfree failure and enhance tracing control
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

Different ARM users have shown their interest in this patch, so I made
a third version that is compatible with PID namespaces.

Mainly:
- It fixes a "vmalloc: allocation failure: 0 bytes" when reading an
  ETB buffer that is empty.
- It extends current support of CoreSight ETM, that is currently
  very limited.

ETM is a dedicated hardware that provides program tracing, a
cycle-precise and low-overhead solution that software tools such as
'perf record' cannot provide.

Usage of ETM tracing facility is presently limited to start and stop
tracing.  This set of patches enables management of address combinations
and PIDs that trigger tracing, thus allowing to trace specific
functions and processes.  ETM management was done via sysfs entries
(trace_info, trace_running...), this code adds trace_addrrange and
trace_pid to let the user read/write custom values.

Changes in V2:
- Fix a vmalloc/vfree failure when ETB is empty
- Use device attributes rather than raw kobjects
- Make PID_IN_CONTEXTIDR incompatible with PID_NS in Kconfig
- Use pid_t instead of long

Changes in V3:
- Support tracing processes by their PID in PID namespaces
- Reset PID_IN_CONTEXTIDR and PID_NS independent

This series of patches applies to v3.13.

Adrien Verg? (5):
  ARM CoreSight: ETM: Fix a memory allocation failure
  ARM CoreSight: ETM: Use device attributes
  ARM CoreSight: ETM: Rename 'comparator' to 'address comparator'
  ARM CoreSight: ETM: Add address control support
  ARM CoreSight: ETM: Add PID control support

 arch/arm/include/asm/hardware/coresight.h |   9 +-
 arch/arm/kernel/etm.c                     | 257 ++++++++++++++++++++++++------
 2 files changed, 216 insertions(+), 50 deletions(-)

-- 
1.8.5.3

^ permalink raw reply

* [PATCH V3 1/5] ARM CoreSight: ETM: Fix a memory allocation failure
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391098270-8867-1-git-send-email-adrienverge@gmail.com>

When an application reads the ETB buffer too often, it can be empty.
In this case, it results in a "vmalloc: allocation failure: 0 bytes",
a backtrace in dmesg and a vfree on an incorrect address.

This patch allocates and frees the trace buffer only when necessary.

Signed-off-by: Adrien Verg? <adrienverge@gmail.com>
---
 arch/arm/kernel/etm.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 8ff0ecd..5192693 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -275,7 +275,7 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	long length;
 	struct tracectx *t = file->private_data;
 	u32 first = 0;
-	u32 *buf;
+	u32 *buf = NULL;
 
 	mutex_lock(&t->mutex);
 
@@ -293,12 +293,14 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	etb_writel(t, first, ETBR_READADDR);
 
 	length = min(total * 4, (int)len);
-	buf = vmalloc(length);
+	if (length != 0)
+		buf = vmalloc(length);
 
 	dev_dbg(t->dev, "ETB buffer length: %d\n", total);
 	dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
-	for (i = 0; i < length / 4; i++)
-		buf[i] = etb_readl(t, ETBR_READMEM);
+	if (buf)
+		for (i = 0; i < length / 4; i++)
+			buf[i] = etb_readl(t, ETBR_READMEM);
 
 	/* the only way to deassert overflow bit in ETB status is this */
 	etb_writel(t, 1, ETBR_CTRL);
@@ -311,7 +313,8 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	etb_lock(t);
 
 	length -= copy_to_user(data, buf, length);
-	vfree(buf);
+	if (buf)
+		vfree(buf);
 
 out:
 	mutex_unlock(&t->mutex);
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH V3 2/5] ARM CoreSight: ETM: Use device attributes
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391098270-8867-1-git-send-email-adrienverge@gmail.com>

Replace all kobjects attributes with device attributes.
User experience isn't changed since the same files are created in sysfs.

Signed-off-by: Adrien Verg? <adrienverge@gmail.com>
---
 arch/arm/kernel/etm.c | 48 +++++++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 5192693..7a3ee66 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -433,15 +433,14 @@ static struct amba_driver etb_driver = {
 };
 
 /* use a sysfs file "trace_running" to start/stop tracing */
-static ssize_t trace_running_show(struct kobject *kobj,
-				  struct kobj_attribute *attr,
-				  char *buf)
+static ssize_t trace_running_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%x\n", trace_isrunning(&tracer));
 }
 
-static ssize_t trace_running_store(struct kobject *kobj,
-				   struct kobj_attribute *attr,
+static ssize_t trace_running_store(struct device *dev,
+				   struct device_attribute *attr,
 				   const char *buf, size_t n)
 {
 	unsigned int value;
@@ -457,12 +456,11 @@ static ssize_t trace_running_store(struct kobject *kobj,
 	return ret ? : n;
 }
 
-static struct kobj_attribute trace_running_attr =
-	__ATTR(trace_running, 0644, trace_running_show, trace_running_store);
+DEVICE_ATTR(trace_running, S_IRUGO|S_IWUSR,
+	    trace_running_show, trace_running_store);
 
-static ssize_t trace_info_show(struct kobject *kobj,
-				  struct kobj_attribute *attr,
-				  char *buf)
+static ssize_t trace_info_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
 	int datalen;
@@ -498,21 +496,19 @@ static ssize_t trace_info_show(struct kobject *kobj,
 			);
 }
 
-static struct kobj_attribute trace_info_attr =
-	__ATTR(trace_info, 0444, trace_info_show, NULL);
+DEVICE_ATTR(trace_info, S_IRUGO, trace_info_show, NULL);
 
-static ssize_t trace_mode_show(struct kobject *kobj,
-				  struct kobj_attribute *attr,
-				  char *buf)
+static ssize_t trace_mode_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%d %d\n",
 			!!(tracer.flags & TRACER_CYCLE_ACC),
 			tracer.etm_portsz);
 }
 
-static ssize_t trace_mode_store(struct kobject *kobj,
-				   struct kobj_attribute *attr,
-				   const char *buf, size_t n)
+static ssize_t trace_mode_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t n)
 {
 	unsigned int cycacc, portsz;
 
@@ -531,8 +527,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
 	return n;
 }
 
-static struct kobj_attribute trace_mode_attr =
-	__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+DEVICE_ATTR(trace_mode, S_IRUGO|S_IWUSR, trace_mode_show, trace_mode_store);
 
 static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
@@ -571,17 +566,16 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	etm_writel(t, 0x440, ETMR_CTRL);
 	etm_lock(t);
 
-	ret = sysfs_create_file(&dev->dev.kobj,
-			&trace_running_attr.attr);
+	ret = device_create_file(&dev->dev, &dev_attr_trace_running);
 	if (ret)
 		goto out_unmap;
 
 	/* failing to create any of these two is not fatal */
-	ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
+	ret = device_create_file(&dev->dev, &dev_attr_trace_info);
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
 
-	ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
+	ret = device_create_file(&dev->dev, &dev_attr_trace_mode);
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
 
@@ -611,9 +605,9 @@ static int etm_remove(struct amba_device *dev)
 
 	amba_release_regions(dev);
 
-	sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
-	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
-	sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+	device_remove_file(&dev->dev, &dev_attr_trace_running);
+	device_remove_file(&dev->dev, &dev_attr_trace_info);
+	device_remove_file(&dev->dev, &dev_attr_trace_mode);
 
 	return 0;
 }
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH V3 3/5] ARM CoreSight: ETM: Rename 'comparator' to 'address comparator'
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391098270-8867-1-git-send-email-adrienverge@gmail.com>

Since there are different types of comparators, and other kinds will
be used (such as Context ID comparators), rename them properly.

Signed-off-by: Adrien Verg? <adrienverge@gmail.com>
---
 arch/arm/include/asm/hardware/coresight.h |  4 ++--
 arch/arm/kernel/etm.c                     | 19 ++++++++++---------
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index ad774f3..8c50cf6 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -95,8 +95,8 @@
 #define ETMAAT_NSONLY		(1 << 10)
 #define ETMAAT_SONLY		(2 << 10)
 
-#define ETMR_COMP_VAL(x)	(0x40 + (x) * 4)
-#define ETMR_COMP_ACC_TYPE(x)	(0x80 + (x) * 4)
+#define ETMR_ADDRCOMP_VAL(x)	(0x40 + (x) * 4)
+#define ETMR_ADDRCOMP_ACC_TYPE(x)	(0x80 + (x) * 4)
 
 /* ETM status register, "ETM Architecture", 3.3.2 */
 #define ETMR_STATUS		(0x10)
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 7a3ee66..b3e6713 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -39,7 +39,7 @@ struct tracectx {
 	void __iomem	*etb_regs;
 	void __iomem	*etm_regs;
 	unsigned long	flags;
-	int		ncmppairs;
+	int		naddrcmppairs;
 	int		etm_portsz;
 	struct device	*dev;
 	struct clk	*emu_clk;
@@ -59,7 +59,7 @@ static int etm_setup_address_range(struct tracectx *t, int n,
 	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
 		    ETMAAT_NOVALCMP;
 
-	if (n < 1 || n > t->ncmppairs)
+	if (n < 1 || n > t->naddrcmppairs)
 		return -EINVAL;
 
 	/* comparators and ranges are numbered starting with 1 as opposed
@@ -72,12 +72,12 @@ static int etm_setup_address_range(struct tracectx *t, int n,
 		flags |= ETMAAT_IEXEC;
 
 	/* first comparator for the range */
-	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
-	etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+	etm_writel(t, flags, ETMR_ADDRCOMP_ACC_TYPE(n * 2));
+	etm_writel(t, start, ETMR_ADDRCOMP_VAL(n * 2));
 
 	/* second comparator is right next to it */
-	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
-	etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
+	etm_writel(t, flags, ETMR_ADDRCOMP_ACC_TYPE(n * 2 + 1));
+	etm_writel(t, end, ETMR_ADDRCOMP_VAL(n * 2 + 1));
 
 	flags = exclude ? ETMTE_INCLEXCL : 0;
 	etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
@@ -478,7 +478,8 @@ static ssize_t trace_info_show(struct device *dev,
 	etm_st = etm_readl(&tracer, ETMR_STATUS);
 	etm_lock(&tracer);
 
-	return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+	return sprintf(buf, "Trace buffer len: %d\n"
+			"Addr comparator pairs: %d\n"
 			"ETBR_WRITEADDR:\t%08x\n"
 			"ETBR_READADDR:\t%08x\n"
 			"ETBR_STATUS:\t%08x\n"
@@ -486,7 +487,7 @@ static ssize_t trace_info_show(struct device *dev,
 			"ETMR_CTRL:\t%08x\n"
 			"ETMR_STATUS:\t%08x\n",
 			datalen,
-			tracer.ncmppairs,
+			tracer.naddrcmppairs,
 			etb_wa,
 			etb_ra,
 			etb_st,
@@ -562,7 +563,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	/* dummy first read */
 	(void)etm_readl(&tracer, ETMMR_OSSRR);
 
-	t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+	t->naddrcmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
 	etm_writel(t, 0x440, ETMR_CTRL);
 	etm_lock(t);
 
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH V3 4/5] ARM CoreSight: ETM: Add address control support
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391098270-8867-1-git-send-email-adrienverge@gmail.com>

In the same manner as for enabling tracing, an entry is created
in sysfs to set the address range that triggers tracing.

Signed-off-by: Adrien Verg? <adrienverge@gmail.com>
---
 arch/arm/kernel/etm.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index b3e6713..fa42e32 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -44,6 +44,8 @@ struct tracectx {
 	struct device	*dev;
 	struct clk	*emu_clk;
 	struct mutex	mutex;
+	unsigned long	addrrange_start;
+	unsigned long	addrrange_end;
 };
 
 static struct tracectx tracer;
@@ -53,6 +55,13 @@ static inline bool trace_isrunning(struct tracectx *t)
 	return !!(t->flags & TRACER_RUNNING);
 }
 
+/*
+ * Setups ETM to trace only when:
+ *   - address between start and end
+ *     or address not between start and end (if exclude)
+ *   - trace executed instructions
+ *     or trace loads and stores (if data)
+ */
 static int etm_setup_address_range(struct tracectx *t, int n,
 		unsigned long start, unsigned long end, int exclude, int data)
 {
@@ -115,8 +124,8 @@ static int trace_start(struct tracectx *t)
 		return -EFAULT;
 	}
 
-	etm_setup_address_range(t, 1, (unsigned long)_stext,
-			(unsigned long)_etext, 0, 0);
+	etm_setup_address_range(t, 1, t->addrrange_start, t->addrrange_end,
+				0, 0);
 	etm_writel(t, 0, ETMR_TRACEENCTRL2);
 	etm_writel(t, 0, ETMR_TRACESSCTRL);
 	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
@@ -530,6 +539,36 @@ static ssize_t trace_mode_store(struct device *dev,
 
 DEVICE_ATTR(trace_mode, S_IRUGO|S_IWUSR, trace_mode_show, trace_mode_store);
 
+static ssize_t trace_addrrange_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%08lx - %08lx\n", tracer.addrrange_start,
+		       tracer.addrrange_end);
+}
+
+static ssize_t trace_addrrange_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t n)
+{
+	unsigned long start, end;
+
+	if (tracer.flags & TRACER_RUNNING)
+		return -EBUSY;
+
+	if (sscanf(buf, "%08lx - %08lx", &start, &end) != 2)
+		return -EINVAL;
+
+	mutex_lock(&tracer.mutex);
+	tracer.addrrange_start = start;
+	tracer.addrrange_end = end;
+	mutex_unlock(&tracer.mutex);
+
+	return n;
+}
+
+DEVICE_ATTR(trace_addrrange, S_IRUGO|S_IWUSR,
+	    trace_addrrange_show, trace_addrrange_store);
+
 static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct tracectx *t = &tracer;
@@ -557,6 +596,8 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	t->dev = &dev->dev;
 	t->flags = TRACER_CYCLE_ACC;
 	t->etm_portsz = 1;
+	t->addrrange_start = (unsigned long) _stext;
+	t->addrrange_end = (unsigned long) _etext;
 
 	etm_unlock(t);
 	(void)etm_readl(t, ETMMR_PDSR);
@@ -571,7 +612,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	if (ret)
 		goto out_unmap;
 
-	/* failing to create any of these two is not fatal */
+	/* failing to create any of these three is not fatal */
 	ret = device_create_file(&dev->dev, &dev_attr_trace_info);
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
@@ -580,6 +621,10 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
 
+	ret = device_create_file(&dev->dev, &dev_attr_trace_addrrange);
+	if (ret)
+		dev_dbg(&dev->dev, "Failed to create trace_addrrange in sysfs\n");
+
 	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
 
 out:
@@ -609,6 +654,7 @@ static int etm_remove(struct amba_device *dev)
 	device_remove_file(&dev->dev, &dev_attr_trace_running);
 	device_remove_file(&dev->dev, &dev_attr_trace_info);
 	device_remove_file(&dev->dev, &dev_attr_trace_mode);
+	device_remove_file(&dev->dev, &dev_attr_trace_addrrange);
 
 	return 0;
 }
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH V3 5/5] ARM CoreSight: ETM: Add PID control support
From: Adrien Vergé @ 2014-01-30 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391098270-8867-1-git-send-email-adrienverge@gmail.com>

In the same manner as for enabling tracing, an entry is created in
sysfs to set the PID that triggers tracing. This change is effective
only if CONFIG_PID_IN_CONTEXTIDR is set.

When using PID namespaces, the virtual PID given by the user is
converted to the globally unique ID (task_pid_nr) that is present
in the Context ID register.

Signed-off-by: Adrien Verg? <adrienverge@gmail.com>
---
 arch/arm/include/asm/hardware/coresight.h |   5 ++
 arch/arm/kernel/etm.c                     | 131 ++++++++++++++++++++++++++++--
 2 files changed, 129 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 8c50cf6..2051af0 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -98,6 +98,11 @@
 #define ETMR_ADDRCOMP_VAL(x)	(0x40 + (x) * 4)
 #define ETMR_ADDRCOMP_ACC_TYPE(x)	(0x80 + (x) * 4)
 
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+#define ETMR_CTXIDCOMP_VAL(x)	(0x1b0 + (x) * 4)
+#define ETMR_CTXIDCOMP_MASK	(0x1bc)
+#endif
+
 /* ETM status register, "ETM Architecture", 3.3.2 */
 #define ETMR_STATUS		(0x10)
 #define ETMST_OVERFLOW		BIT(0)
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index fa42e32..e8db9e2 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -25,6 +25,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <asm/hardware/coresight.h>
 #include <asm/sections.h>
 
@@ -40,12 +41,17 @@ struct tracectx {
 	void __iomem	*etm_regs;
 	unsigned long	flags;
 	int		naddrcmppairs;
+	int		nctxidcmp;
 	int		etm_portsz;
 	struct device	*dev;
 	struct clk	*emu_clk;
 	struct mutex	mutex;
 	unsigned long	addrrange_start;
 	unsigned long	addrrange_end;
+	pid_t		pid;	/* globally unique PID */
+#ifdef CONFIG_PID_NS
+	pid_t		vpid;	/* virtual PID as seen in namespace */
+#endif
 };
 
 static struct tracectx tracer;
@@ -55,18 +61,42 @@ static inline bool trace_isrunning(struct tracectx *t)
 	return !!(t->flags & TRACER_RUNNING);
 }
 
+#if defined(CONFIG_PID_IN_CONTEXTIDR) && defined(CONFIG_PID_NS)
+/*
+ * Returns the globally unique ID of a task referenced
+ * with its virtual namespace PID
+ */
+static inline pid_t pid_vnr_to_pid_nr(pid_t vpid)
+{
+	struct task_struct *task = find_task_by_vpid(vpid);
+
+	if (!task) {
+		printk(KERN_WARNING "CoreSight ETM: cannot track PID %d: "
+				    "no such PID in current namespace\n",
+		       vpid);
+		return -EINVAL;
+	}
+
+	return task_pid_nr(task);
+}
+#endif
+
 /*
  * Setups ETM to trace only when:
  *   - address between start and end
  *     or address not between start and end (if exclude)
+ *   - in user-space when process id equals pid,
+ *     in kernel-space (if pid == 0),
+ *     always (if pid == -1)
  *   - trace executed instructions
  *     or trace loads and stores (if data)
  */
-static int etm_setup_address_range(struct tracectx *t, int n,
-		unsigned long start, unsigned long end, int exclude, int data)
+static int etm_setup(struct tracectx *t, int n,
+		     unsigned long start, unsigned long end, int exclude,
+		     pid_t pid,
+		     int data)
 {
-	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
-		    ETMAAT_NOVALCMP;
+	u32 flags = ETMAAT_ARM | ETMAAT_NSONLY | ETMAAT_NOVALCMP;
 
 	if (n < 1 || n > t->naddrcmppairs)
 		return -EINVAL;
@@ -75,6 +105,23 @@ static int etm_setup_address_range(struct tracectx *t, int n,
 	 * to bits in a word */
 	n--;
 
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+	if (pid < 0) {
+		/* ignore Context ID */
+		flags |= ETMAAT_IGNCONTEXTID;
+	} else {
+		flags |= ETMAAT_VALUE1;
+
+		/* Set up the first Context ID comparator.
+		   Process ID is found in the 24 first bits of Context ID
+		   (provided by CONFIG_PID_IN_CONTEXTIDR) */
+		etm_writel(t, pid << 8, ETMR_CTXIDCOMP_VAL(0));
+		etm_writel(t, 0xff, ETMR_CTXIDCOMP_MASK);
+	}
+#else
+	flags |= ETMAAT_IGNCONTEXTID;
+#endif
+
 	if (data)
 		flags |= ETMAAT_DLOADSTORE;
 	else
@@ -124,8 +171,10 @@ static int trace_start(struct tracectx *t)
 		return -EFAULT;
 	}
 
-	etm_setup_address_range(t, 1, t->addrrange_start, t->addrrange_end,
-				0, 0);
+	etm_setup(t, 1,
+		  t->addrrange_start, t->addrrange_end, 0,
+		  t->pid,
+		  0);
 	etm_writel(t, 0, ETMR_TRACEENCTRL2);
 	etm_writel(t, 0, ETMR_TRACESSCTRL);
 	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
@@ -489,6 +538,7 @@ static ssize_t trace_info_show(struct device *dev,
 
 	return sprintf(buf, "Trace buffer len: %d\n"
 			"Addr comparator pairs: %d\n"
+			"Ctx ID comparators: %d\n"
 			"ETBR_WRITEADDR:\t%08x\n"
 			"ETBR_READADDR:\t%08x\n"
 			"ETBR_STATUS:\t%08x\n"
@@ -497,6 +547,7 @@ static ssize_t trace_info_show(struct device *dev,
 			"ETMR_STATUS:\t%08x\n",
 			datalen,
 			tracer.naddrcmppairs,
+			tracer.nctxidcmp,
 			etb_wa,
 			etb_ra,
 			etb_st,
@@ -569,6 +620,61 @@ static ssize_t trace_addrrange_store(struct device *dev,
 DEVICE_ATTR(trace_addrrange, S_IRUGO|S_IWUSR,
 	    trace_addrrange_show, trace_addrrange_store);
 
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+static ssize_t trace_pid_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+#ifdef CONFIG_PID_NS
+	return sprintf(buf, "%d\n", tracer.vpid);
+#else
+	return sprintf(buf, "%d\n", tracer.pid);
+#endif
+}
+
+static ssize_t trace_pid_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t n)
+{
+	pid_t pid;
+#ifdef CONFIG_PID_NS
+	pid_t vpid;
+#endif
+
+	if (tracer.flags & TRACER_RUNNING)
+		return -EBUSY;
+
+	if (sscanf(buf, "%i", &pid) != 1)
+		return -EINVAL;
+
+#ifdef CONFIG_PID_NS
+	/* the value written to the Context ID register is the global PID */
+	vpid = pid;
+
+	/* -1 means trace everything,
+	   0 means kernel tracing,
+	   > 0 process tracing */
+	if (pid > 0) {
+		pid = pid_vnr_to_pid_nr(vpid);
+
+		if (pid < 0)
+			return pid;
+	}
+#endif
+
+	mutex_lock(&tracer.mutex);
+	tracer.pid = pid;
+#ifdef CONFIG_PID_NS
+	tracer.vpid = vpid;
+#endif
+	mutex_unlock(&tracer.mutex);
+
+	return n;
+}
+
+DEVICE_ATTR(trace_pid, S_IRUGO|S_IWUSR, trace_pid_show, trace_pid_store);
+#endif
+
 static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct tracectx *t = &tracer;
@@ -598,6 +704,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	t->etm_portsz = 1;
 	t->addrrange_start = (unsigned long) _stext;
 	t->addrrange_end = (unsigned long) _etext;
+	t->pid = -1; /* trace everything */
 
 	etm_unlock(t);
 	(void)etm_readl(t, ETMMR_PDSR);
@@ -605,6 +712,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	(void)etm_readl(&tracer, ETMMR_OSSRR);
 
 	t->naddrcmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+	t->nctxidcmp = (etm_readl(t, ETMR_CONFCODE) >> 24) & 0x3;
 	etm_writel(t, 0x440, ETMR_CTRL);
 	etm_lock(t);
 
@@ -612,7 +720,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	if (ret)
 		goto out_unmap;
 
-	/* failing to create any of these three is not fatal */
+	/* failing to create any of these four is not fatal */
 	ret = device_create_file(&dev->dev, &dev_attr_trace_info);
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
@@ -625,6 +733,12 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_addrrange in sysfs\n");
 
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+	ret = device_create_file(&dev->dev, &dev_attr_trace_pid);
+	if (ret)
+		dev_dbg(&dev->dev, "Failed to create trace_pid in sysfs\n");
+#endif
+
 	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
 
 out:
@@ -655,6 +769,9 @@ static int etm_remove(struct amba_device *dev)
 	device_remove_file(&dev->dev, &dev_attr_trace_info);
 	device_remove_file(&dev->dev, &dev_attr_trace_mode);
 	device_remove_file(&dev->dev, &dev_attr_trace_addrrange);
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+	device_remove_file(&dev->dev, &dev_attr_trace_pid);
+#endif
 
 	return 0;
 }
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH] fix compilation of imx-hdmi
From: Russell King - ARM Linux @ 2014-01-30 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

imx-hdmi creates a hdmi_colorimetry enum.  This is also defined by
include/linux/hdmi.h, which gets included now via DRM headers since
985e5dc207e133 (drm/edid: Populate picture aspect ratio for CEA modes).
This leads to the compiler complaining:

drivers/staging/imx-drm/imx-hdmi.c:58:6: error: nested redefinition of 'enum hdmi_colorimetry'
drivers/staging/imx-drm/imx-hdmi.c:58:6: error: redeclaration of 'enum hdmi_colorimetry'
include/linux/hdmi.h:48:6: note: originally defined here

Fix it by using the one in linux/hdmi.h

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/staging/imx-drm/imx-hdmi.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
index d358d89e11c4..74d635fcb3d5 100644
--- a/drivers/staging/imx-drm/imx-hdmi.c
+++ b/drivers/staging/imx-drm/imx-hdmi.c
@@ -55,11 +55,6 @@ enum hdmi_datamap {
 	YCbCr422_12B = 0x12,
 };
 
-enum hdmi_colorimetry {
-	ITU601,
-	ITU709,
-};
-
 enum imx_hdmi_devtype {
 	IMX6Q_HDMI,
 	IMX6DL_HDMI,
@@ -475,12 +470,12 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
 
 	if (is_color_space_conversion(hdmi)) {
 		if (hdmi->hdmi_data.enc_out_format == RGB) {
-			if (hdmi->hdmi_data.colorimetry == ITU601)
+			if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
 				csc_coeff = &csc_coeff_rgb_out_eitu601;
 			else
 				csc_coeff = &csc_coeff_rgb_out_eitu709;
 		} else if (hdmi->hdmi_data.enc_in_format == RGB) {
-			if (hdmi->hdmi_data.colorimetry == ITU601)
+			if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
 				csc_coeff = &csc_coeff_rgb_in_eitu601;
 			else
 				csc_coeff = &csc_coeff_rgb_in_eitu709;
@@ -1009,14 +1004,14 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi)
 	/* Set up colorimetry */
 	if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
 		colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
-		if (hdmi->hdmi_data.colorimetry == ITU601)
+		if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
 			ext_colorimetry =
 				HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
 		else /* hdmi->hdmi_data.colorimetry == ITU709 */
 			ext_colorimetry =
 				HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
 	} else if (hdmi->hdmi_data.enc_out_format != RGB) {
-		if (hdmi->hdmi_data.colorimetry == ITU601)
+		if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
 			colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
 		else /* hdmi->hdmi_data.colorimetry == ITU709 */
 			colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
@@ -1247,9 +1242,9 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
 		(hdmi->vic == 21) || (hdmi->vic == 22) ||
 		(hdmi->vic == 2) || (hdmi->vic == 3) ||
 		(hdmi->vic == 17) || (hdmi->vic == 18))
-		hdmi->hdmi_data.colorimetry = ITU601;
+		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
 	else
-		hdmi->hdmi_data.colorimetry = ITU709;
+		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
 
 	if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
 		(hdmi->vic == 12) || (hdmi->vic == 13) ||

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply related


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