Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/5] ARM: OMAP4+: Fix bad fallthrough for cpuidle
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

We don't want to fall through to a bunch of errors for retention
if PM_OMAP4_CPU_OSWR_DISABLE is not configured for a SoC.

Fixes: 6099dd37c669 ("ARM: OMAP5 / DRA7: Enable CPU RET on suspend")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -244,10 +244,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		save_state = 1;
 		break;
 	case PWRDM_POWER_RET:
-		if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
+		if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
 			save_state = 0;
-			break;
-		}
+		break;
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
-- 
2.9.3

^ permalink raw reply

* [PATCH 2/5] ARM: OMAP5: Fix mpuss_early_init
From: Tony Lindgren @ 2016-10-26 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

We need to properly initialize mpuss also on omap5 like we do on omap4.
Otherwise we run into similar kexec problems like we had on omap4 when
trying to kexec from a kernel with PM initialized.

Fixes: 0573b957fc21 ("ARM: OMAP4+: Prevent CPU1 related hang with kexec")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/io.c                  |  3 ++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 28 +++++++++++++++++++++-------
 arch/arm/mach-omap2/omap4-sar-layout.h    |  2 ++
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -717,10 +717,11 @@ void __init omap5_init_early(void)
 			      OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap2_control_base_init();
-	omap4_pm_init_early();
 	omap2_prcm_base_init();
 	omap5xxx_check_revision();
 	omap4_sar_ram_init();
+	omap4_mpuss_early_init();
+	omap4_pm_init_early();
 	omap54xx_voltagedomains_init();
 	omap54xx_powerdomains_init();
 	omap54xx_clockdomains_init();
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -371,8 +371,12 @@ int __init omap4_mpuss_init(void)
 	pm_info = &per_cpu(omap4_pm_info, 0x0);
 	if (sar_base) {
 		pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
-		pm_info->wkup_sar_addr = sar_base +
-					CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+		if (cpu_is_omap44xx())
+			pm_info->wkup_sar_addr = sar_base +
+				CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+		else
+			pm_info->wkup_sar_addr = sar_base +
+				OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
 		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
 	}
 	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
@@ -391,8 +395,12 @@ int __init omap4_mpuss_init(void)
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	if (sar_base) {
 		pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
-		pm_info->wkup_sar_addr = sar_base +
-					CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+		if (cpu_is_omap44xx())
+			pm_info->wkup_sar_addr = sar_base +
+				CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+		else
+			pm_info->wkup_sar_addr = sar_base +
+				OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
 		pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
 	}
 
@@ -453,15 +461,21 @@ void __init omap4_mpuss_early_init(void)
 {
 	unsigned long startup_pa;
 
-	if (!cpu_is_omap44xx())
+	if (!(cpu_is_omap44xx() || soc_is_omap54xx()))
 		return;
 
 	sar_base = omap4_get_sar_ram_base();
 
 	if (cpu_is_omap443x())
 		startup_pa = virt_to_phys(omap4_secondary_startup);
-	else
+	else if (cpu_is_omap446x())
 		startup_pa = virt_to_phys(omap4460_secondary_startup);
+	else
+		startup_pa = virt_to_phys(omap5_secondary_startup);
 
-	writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+	if (cpu_is_omap44xx())
+		writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
+	else
+		writel_relaxed(startup_pa, sar_base +
+			       OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET);
 }
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -31,6 +31,8 @@
 /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET		0xa04
 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET		0xa08
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
 
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
-- 
2.9.3

^ permalink raw reply

* [PATCH 1/5] ARM: OMAP5: Fix build for PM code
From: Tony Lindgren @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151703.24730-1-tony@atomide.com>

It's CONFIG_SOC_OMAP5, not CONFIG_ARCH_OMAP5. Looks like make randconfig
builds have not hit this one yet.

Fixes: b3bf289c1c45 ("ARM: OMAP2+: Fix build with CONFIG_SMP and CONFIG_PM
is not set")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -80,7 +80,7 @@ endif
 # Power Management
 omap-4-5-pm-common			= omap-mpuss-lowpower.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-pm-common)
-obj-$(CONFIG_ARCH_OMAP5)		+= $(omap-4-5-pm-common)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-pm-common)
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 
 ifeq ($(CONFIG_PM),y)
-- 
2.9.3

^ permalink raw reply

* [PATCH 0/5] Minimal cpuidle fixes for omap5 and dra7
From: Tony Lindgren @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Here are some fixes to get minimal cpuidle support working with omap5
and dra7. Not sure if there are still some unsorted issues on enabling
this on dra7, but at least omap5 has been behving for me for few
weeks with these.

Regards,

Tony


Santosh Shilimkar (1):
  ARM: DRA7: PM: cpuidle MPU CSWR support

Tony Lindgren (4):
  ARM: OMAP5: Fix build for PM code
  ARM: OMAP5: Fix mpuss_early_init
  ARM: OMAP4+: Fix bad fallthrough for cpuidle
  ARM: OMAP5: Enable minimal cpuidle for omap5 retention

 arch/arm/mach-omap2/Makefile              |  2 +-
 arch/arm/mach-omap2/cpuidle44xx.c         | 80 ++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/io.c                  |  3 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 33 +++++++++----
 arch/arm/mach-omap2/omap4-sar-layout.h    |  2 +
 arch/arm/mach-omap2/pm44xx.c              |  2 +-
 6 files changed, 108 insertions(+), 14 deletions(-)

-- 
2.9.3

^ permalink raw reply

* [PATCH V3 7/8] arm/arm64: dma-mapping: Call iommu's remove_device callback during device detach
From: Robin Murphy @ 2016-10-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475600632-21289-8-git-send-email-sricharan@codeaurora.org>

On 04/10/16 18:03, Sricharan R wrote:
> dma_deconfigure calls arch_teardown_dma_ops in the device_detach path,
> which is called when the device gets detached from the driver.
> When the device was added, iommu's add_device callback was used to
> add the device in to its iommu_group and setup the device to be ready
> to use its iommu. Similarly, call remove_device callback to remove the
> device from the group and reset any other device's iommu configurations.
> 
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>  arch/arm/mm/dma-mapping.c   | 8 ++++++++
>  arch/arm64/mm/dma-mapping.c | 7 +++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index b9191f0..cbe22de 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2289,11 +2289,19 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  static void arm_teardown_iommu_dma_ops(struct device *dev)
>  {
>  	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
> +	const struct iommu_ops *ops;
>  
>  	if (!mapping)
>  		return;
>  
>  	__arm_iommu_detach_device(dev);
> +
> +	if (dev->iommu_fwspec) {
> +		ops = dev->iommu_fwspec->ops;
> +		if (ops->remove_device)
> +			ops->remove_device(dev);
> +	}
> +

Yuck. It's a little unfortunate that we have to do this at all, but I
see why. Still, it should be done in common code, not duplicated across
arch code, not least for symmetry with where the matching add_device
happened (although I think of_dma_deconfigure() would suffice, I'm not
sure we really need to add an of_iommu_deconfigure() just for this).

It's also broken for IOMMU drivers which rely on the
of_iommu_configure() mechanism but have not yet been converted to use
iommu_fwspec (Exynos, MSM, etc.)

Robin.

>  	arm_iommu_release_mapping(mapping);
>  	set_dma_ops(dev, NULL);
>  }
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 610d8e5..faf4b92 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -938,6 +938,13 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>  void arch_teardown_dma_ops(struct device *dev)
>  {
>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> +	const struct iommu_ops *ops;
> +
> +	if (dev->iommu_fwspec) {
> +		ops = dev->iommu_fwspec->ops;
> +		if (ops->remove_device)
> +			ops->remove_device(dev);
> +	}
>  
>  	if (WARN_ON(domain))
>  		iommu_detach_device(domain, dev);
> 

^ permalink raw reply

* [PATCH 5/5] ARM: configs: Add new config fragment to change RAM size
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/configs/dram_size_0x2000000.config b/arch/arm/configs/dram_size_0x2000000.config
new file mode 100644
index 0000000..e66430d
--- /dev/null
+++ b/arch/arm/configs/dram_size_0x2000000.config
@@ -0,0 +1 @@
+CONFIG_DRAM_SIZE=0x002000000
-- 
1.9.1

^ permalink raw reply related

* [PATCH 4/5] ARM: configs: Add new config fragment to change RAM start point
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/configs/dram_0xc0000000.config b/arch/arm/configs/dram_0xc0000000.config
new file mode 100644
index 0000000..343d533
--- /dev/null
+++ b/arch/arm/configs/dram_0xc0000000.config
@@ -0,0 +1 @@
+CONFIG_DRAM_BASE=0xc0000000
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/5] ARM: dts: Add STM32F746 MCU and STM32746g-EVAL board
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

The STMicrolectornics's STM32F746 MCU has the following main features:
 - Cortex-M7 core running up to @216MHz
 - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
 - FMC controller to connect SDRAM, NOR and NAND memories
 - Dual mode QSPI
 - SD/MMC/SDIO support
 - Ethernet controller
 - USB OTFG FS & HS controllers
 - I2C, SPI, CAN busses support
 - Several 16 & 32 bits general purpose timers
 - Serial Audio interface
 - LCD controller
 - HDMI-CEC
 - SPDIFRX

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index befcd26..343dda2 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -721,7 +721,8 @@ dtb-$(CONFIG_ARCH_STI) += \
 dtb-$(CONFIG_ARCH_STM32)+= \
 	stm32f429-disco.dtb \
 	stm32f469-disco.dtb \
-	stm32429i-eval.dtb
+	stm32429i-eval.dtb \
+	stm32746g-eval.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-a1000.dtb \
 	sun4i-a10-ba10-tvbox.dtb \
diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts
new file mode 100644
index 0000000..aa03fac
--- /dev/null
+++ b/arch/arm/boot/dts/stm32746g-eval.dts
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f746.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "STMicroelectronics STM32746g-EVAL board";
+	compatible = "st,stm32746g-eval", "st,stm32f746";
+
+	chosen {
+		bootargs = "root=/dev/ram";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		reg = <0xc0000000 0x2000000>;
+	};
+
+	aliases {
+		serial0 = &usart1;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		green {
+			gpios = <&gpiof 10 1>;
+			linux,default-trigger = "heartbeat";
+		};
+		red {
+			gpios = <&gpiob 7 1>;
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		autorepeat;
+		button at 0 {
+			label = "Wake up";
+			linux,code = <KEY_WAKEUP>;
+			gpios = <&gpioc 13 0>;
+		};
+	};
+};
+
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi
new file mode 100644
index 0000000..f321ffe
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f746.dtsi
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include "armv7-m.dtsi"
+#include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
+
+/ {
+	clocks {
+		clk_hse: clk-hse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+	};
+
+	soc {
+		timer2: timer at 40000000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000000 0x400>;
+			interrupts = <28>;
+			clocks = <&rcc 0 128>;
+			status = "disabled";
+		};
+
+		timer3: timer at 40000400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000400 0x400>;
+			interrupts = <29>;
+			clocks = <&rcc 0 129>;
+			status = "disabled";
+		};
+
+		timer4: timer at 40000800 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000800 0x400>;
+			interrupts = <30>;
+			clocks = <&rcc 0 130>;
+			status = "disabled";
+		};
+
+		timer5: timer at 40000c00 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000c00 0x400>;
+			interrupts = <50>;
+			clocks = <&rcc 0 131>;
+		};
+
+		timer6: timer at 40001000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001000 0x400>;
+			interrupts = <54>;
+			clocks = <&rcc 0 132>;
+			status = "disabled";
+		};
+
+		timer7: timer at 40001400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001400 0x400>;
+			interrupts = <55>;
+			clocks = <&rcc 0 133>;
+			status = "disabled";
+		};
+
+		usart2: serial at 40004400 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40004400 0x400>;
+			interrupts = <38>;
+			clocks =  <&rcc 0 145>;
+			status = "disabled";
+		};
+
+		usart3: serial at 40004800 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40004800 0x400>;
+			interrupts = <39>;
+			clocks = <&rcc 0 146>;
+			status = "disabled";
+		};
+
+		usart4: serial at 40004c00 {
+			compatible = "st,stm32f7-uart";
+			reg = <0x40004c00 0x400>;
+			interrupts = <52>;
+			clocks = <&rcc 0 147>;
+			status = "disabled";
+		};
+
+		usart5: serial at 40005000 {
+			compatible = "st,stm32f7-uart";
+			reg = <0x40005000 0x400>;
+			interrupts = <53>;
+			clocks = <&rcc 0 148>;
+			status = "disabled";
+		};
+
+		usart7: serial at 40007800 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40007800 0x400>;
+			interrupts = <82>;
+			clocks = <&rcc 0 158>;
+			status = "disabled";
+		};
+
+		usart8: serial at 40007c00 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40007c00 0x400>;
+			interrupts = <83>;
+			clocks = <&rcc 0 159>;
+			status = "disabled";
+		};
+
+		usart1: serial at 40011000 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40011000 0x400>;
+			interrupts = <37>;
+			clocks = <&rcc 0 164>;
+			status = "disabled";
+		};
+
+		usart6: serial at 40011400 {
+			compatible = "st,stm32f7-usart", "st,stm32f7-uart";
+			reg = <0x40011400 0x400>;
+			interrupts = <71>;
+			clocks = <&rcc 0 165>;
+			status = "disabled";
+		};
+
+		syscfg: system-config at 40013800 {
+			compatible = "syscon";
+			reg = <0x40013800 0x400>;
+		};
+
+		exti: interrupt-controller at 40013c00 {
+			compatible = "st,stm32-exti";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x40013C00 0x400>;
+			interrupts = <1>, <2>, <3>, <6>, <7>, <8>, <9>, <10>, <23>, <40>, <41>, <42>, <62>, <76>;
+		};
+
+		pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32f746-pinctrl";
+			ranges = <0 0x40020000 0x3000>;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&syscfg 0x8>;
+			pins-are-numbered;
+
+			gpioa: gpio at 40020000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&rcc 0 256>;
+				st,bank-name = "GPIOA";
+			};
+
+			gpiob: gpio at 40020400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x400 0x400>;
+				clocks = <&rcc 0 257>;
+				st,bank-name = "GPIOB";
+			};
+
+			gpioc: gpio at 40020800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x800 0x400>;
+				clocks = <&rcc 0 258>;
+				st,bank-name = "GPIOC";
+			};
+
+			gpiod: gpio at 40020c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0xc00 0x400>;
+				clocks = <&rcc 0 259>;
+				st,bank-name = "GPIOD";
+			};
+
+			gpioe: gpio at 40021000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&rcc 0 260>;
+				st,bank-name = "GPIOE";
+			};
+
+			gpiof: gpio at 40021400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1400 0x400>;
+				clocks = <&rcc 0 261>;
+				st,bank-name = "GPIOF";
+			};
+
+			gpiog: gpio at 40021800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1800 0x400>;
+				clocks = <&rcc 0 262>;
+				st,bank-name = "GPIOG";
+			};
+
+			gpioh: gpio at 40021c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1c00 0x400>;
+				clocks = <&rcc 0 263>;
+				st,bank-name = "GPIOH";
+			};
+
+			gpioi: gpio at 40022000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&rcc 0 264>;
+				st,bank-name = "GPIOI";
+			};
+
+			gpioj: gpio at 40022400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2400 0x400>;
+				clocks = <&rcc 0 265>;
+				st,bank-name = "GPIOJ";
+			};
+
+			gpiok: gpio at 40022800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2800 0x400>;
+				clocks = <&rcc 0 266>;
+				st,bank-name = "GPIOK";
+			};
+
+			usart1_pins_a: usart1 at 0 {
+				pins1 {
+					pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32F746_PA10_FUNC_USART1_RX>;
+					bias-disable;
+				};
+			};
+		};
+
+		rcc: rcc at 40023800 {
+			#clock-cells = <2>;
+			compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
+			reg = <0x40023800 0x400>;
+			clocks = <&clk_hse>;
+		};
+	};
+};
+
+&systick {
+	clocks = <&rcc 1 0>;
+	status = "okay";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/5] ARM: Kconfig: Introduce MACH_STM32F746 flag
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

This patch introduces the MACH_STM32F746 to make possible to only select
STM32F746 pinctrl driver

By default, all the MACH_STM32Fxxx flags will be set with STM32 defconfig.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5d529f..4353765 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -887,6 +887,11 @@ config MACH_STM32F429
 	depends on ARCH_STM32
 	default y
 
+config MACH_STM32F746
+	bool "STMicrolectronics STM32F746"
+	depends on ARCH_STM32
+	default y
+
 config ARCH_MPS2
 	bool "ARM MPS2 platform"
 	depends on ARM_SINGLE_ARMV7M
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/5] ARM: mach-stm32: Add a new SOC - STM32F746
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494683-29890-1-git-send-email-alexandre.torgue@st.com>

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>

diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
index 09aed55..a03b035 100644
--- a/Documentation/arm/stm32/overview.txt
+++ b/Documentation/arm/stm32/overview.txt
@@ -5,7 +5,8 @@ Introduction
 ------------
 
   The STMicroelectronics family of Cortex-M based MCUs are supported by the
-  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+  'STM32' platform of ARM Linux. Currently only the STM32F429 (Cortex-M4)
+  and STM32F746 (Cortex-M7) are supported.
 
 
 Configuration
diff --git a/Documentation/arm/stm32/stm32f746-overview.txt b/Documentation/arm/stm32/stm32f746-overview.txt
new file mode 100644
index 0000000..cffd2b1
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f746-overview.txt
@@ -0,0 +1,34 @@
+			STM32F746 Overview
+			==================
+
+  Introduction
+  ------------
+	The STM32F746 is a Cortex-M7 MCU aimed at various applications.
+	It features:
+	- Cortex-M7 core running up to @216MHz
+	- 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
+	- FMC controller to connect SDRAM, NOR and NAND memories
+	- Dual mode QSPI
+	- SD/MMC/SDIO support
+	- Ethernet controller
+	- USB OTFG FS & HS controllers
+	- I2C, SPI, CAN busses support
+	- Several 16 & 32 bits general purpose timers
+	- Serial Audio interface
+	- LCD controller
+	- HDMI-CEC
+	- SPDIFRX
+
+  Resources
+  ---------
+	Datasheet and reference manual are publicly available on ST website:
+	- http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html
+
+  Document Author
+  ---------------
+	Alexandre Torgue <alexandre.torgue@st.com>
+
+
+
+
+
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
index ceee477..c354222 100644
--- a/arch/arm/mach-stm32/board-dt.c
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -11,6 +11,7 @@
 static const char *const stm32_compat[] __initconst = {
 	"st,stm32f429",
 	"st,stm32f469",
+	"st,stm32f746",
 	NULL
 };
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/5] ADD STM32F746 MCU and STM32746G-Eval board supports
From: Alexandre TORGUE @ 2016-10-26 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds basic support for STM32F746 MCU and stm32746g-eval board.
With it, you can boot stm32746g-eval board successfully.
In this series timer, usart/uart, exti, rng, basic rcc IPs are supported.
Other Ips (Ethernet, dma, ...) will come later.

For your information:

The STMicrolectornics's STM32F746 MCU has the following main features:
 - Cortex-M7 core running up to @216MHz
 - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM)
 - FMC controller to connect SDRAM, NOR and NAND memories
 - Dual mode QSPI
 - SD/MMC/SDIO support
 - Ethernet controller
 - USB OTFG FS & HS controllers
 - I2C, SPI, CAN busses support
 - Several 16 & 32 bits general purpose timers
 - Serial Audio interface
 - LCD controller
 - HDMI-CEC
 - SPDIFRX 

Regards

Alex

Alexandre TORGUE (5):
  ARM: mach-stm32: Add a new SOC - STM32F746
  ARM: Kconfig: Introduce MACH_STM32F746 flag
  ARM: dts: Add STM32F746 MCU and STM32746g-EVAL board
  ARM: configs: Add new config fragment to change RAM start point
  ARM: configs: Add new config fragment to change RAM size

 Documentation/arm/stm32/overview.txt           |   3 +-
 Documentation/arm/stm32/stm32f746-overview.txt |  34 +++
 arch/arm/Kconfig                               |   5 +
 arch/arm/boot/dts/Makefile                     |   3 +-
 arch/arm/boot/dts/stm32746g-eval.dts           |  96 ++++++++
 arch/arm/boot/dts/stm32f746.dtsi               | 304 +++++++++++++++++++++++++
 arch/arm/configs/dram_0xc0000000.config        |   1 +
 arch/arm/configs/dram_size_0x2000000.config    |   1 +
 arch/arm/mach-stm32/board-dt.c                 |   1 +
 9 files changed, 446 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/arm/stm32/stm32f746-overview.txt
 create mode 100644 arch/arm/boot/dts/stm32746g-eval.dts
 create mode 100644 arch/arm/boot/dts/stm32f746.dtsi
 create mode 100644 arch/arm/configs/dram_0xc0000000.config
 create mode 100644 arch/arm/configs/dram_size_0x2000000.config

-- 
1.9.1

^ permalink raw reply

* [PATCH] mfd: qcom-pm8xxx: Clean up PM8XXX namespace
From: Andy Gross @ 2016-10-26 15:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477487453-15801-1-git-send-email-linus.walleij@linaro.org>

On Wed, Oct 26, 2016 at 03:10:53PM +0200, Linus Walleij wrote:
> The Kconfig and file naming for the PM8xxx driver is totally
> confusing:
> 
> - Kconfig options MFD_PM8XXX and MFD_PM8921_CORE, some in-kernel
>   users depending on or selecting either at random.
> - A driver file named pm8921-core.c even if it is indeed
>   used by the whole PM8xxx family of chips.
> - An irqchip named pm8xxx since it was (I guess) realized that
>   the driver was generic for all pm8xxx PMICs.
> 
> As I may want to add support for PM8901 this is starting to get
> really messy. Fix this situation by:
> 
> - Remove the MFD_PM8921_CORE symbol and rely solely on MFD_PM8XXX
>   and convert all users, including LEDs Kconfig and ARM defconfigs
>   for qcom and multi_v7 to use that single symbol.
> - Renaming the driver to qcom-pm8xxx.c to fit along the two
>   other qcom* prefixed drivers.
> - Rename functions withing the driver from 8921 to 8xxx to
>   indicate it is generic.
> - Just drop the =m config from the pxa_defconfig, I have no clue
>   why it is even there, it is not a Qualcomm platform. (Possibly
>   older Kconfig noise from saveconfig.)
> 
> Cc: Stephen Boyd <sboyd@codeaurora.org>
> Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
> Cc: Neil Armstrong <narmstrong@baylibre.com>
> Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>


Reviewed-by: Andy Gross <andy.gross@linaro.org>

^ permalink raw reply

* [PATCH V3 6/8] arm: dma-mapping: Reset the device's dma_ops
From: Robin Murphy @ 2016-10-26 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475600632-21289-7-git-send-email-sricharan@codeaurora.org>

On 04/10/16 18:03, Sricharan R wrote:
> The dma_ops for the device is not getting set to NULL in
> arch_tear_down_dma_ops and this causes an issue when the
> device's probe gets deferred and retried. So reset the
> dma_ops to NULL.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

This seems like it could stand independently from the rest of the series
- might be worth rewording the commit message to more general terms,
i.e. arch_teardown_dma_ops() being the inverse of arch_setup_dma_ops()
thus clearing the ops set by the latter, and sending it to Russell as a
fix in its own right.

Robin.

> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>  arch/arm/mm/dma-mapping.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index dde6514..b9191f0 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2295,6 +2295,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
>  
>  	__arm_iommu_detach_device(dev);
>  	arm_iommu_release_mapping(mapping);
> +	set_dma_ops(dev, NULL);
>  }
>  
>  #else
> 

^ permalink raw reply

* [PATCH V3 4/8] drivers: platform: Configure dma operations at probe time
From: Sricharan @ 2016-10-26 15:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <a77ab9da-1347-49e8-6c55-071bd712729a@arm.com>

Hi Robin,

>On 04/10/16 18:03, Sricharan R wrote:
>> Configuring DMA ops at probe time will allow deferring device probe when
>> the IOMMU isn't available yet. The dma_configure for the device is now called
>> from the generic device_attach callback just before the bus/driver probe
>> is called. This way, configuring the dma ops for the device would be called
>> at the same place for all bus_types, hence the deferred probing mechanism
>> should work for all buses as well.
>>
>> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>>        |                         |
>> pci_bus_add_device     (device_add/driver_register)
>>        |                         |
>> device_attach           device_initial_probe
>>        |                         |
>> __device_attach_driver    __device_attach_driver
>>        |
>> driver_probe_device
>>        |
>> really_probe
>>        |
>> dma_configure
>>
>>  Similarly on the device/driver_unregister path __device_release_driver is
>>  called which inturn calls dma_deconfigure.
>>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>  drivers/base/dd.c           | 10 ++++++++++
>>  drivers/base/dma-mapping.c  | 11 +++++++++++
>>  drivers/of/platform.c       |  4 ----
>>  drivers/pci/probe.c         |  5 +----
>>  include/linux/dma-mapping.h |  3 +++
>>  5 files changed, 25 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>> index 16688f5..cfebd48 100644
>> --- a/drivers/base/dd.c
>> +++ b/drivers/base/dd.c
>> @@ -19,6 +19,7 @@
>>
>>  #include <linux/device.h>
>>  #include <linux/delay.h>
>> +#include <linux/dma-mapping.h>
>>  #include <linux/module.h>
>>  #include <linux/kthread.h>
>>  #include <linux/wait.h>
>> @@ -353,6 +354,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>>  	if (ret)
>>  		goto pinctrl_bind_failed;
>>
>> +	ret = dma_configure(dev);
>> +	if (ret)
>> +		goto dma_failed;
>> +
>>  	if (driver_sysfs_add(dev)) {
>>  		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
>>  			__func__, dev_name(dev));
>> @@ -395,6 +400,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
>>  	goto done;
>>
>>  probe_failed:
>> +	dma_deconfigure(dev);
>> +dma_failed:
>>  	if (dev->bus)
>>  		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
>>  					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
>> @@ -780,6 +787,9 @@ static void __device_release_driver(struct device *dev)
>>  			dev->bus->remove(dev);
>>  		else if (drv->remove)
>>  			drv->remove(dev);
>> +
>> +		dma_deconfigure(dev);
>> +
>>  		devres_release_all(dev);
>>  		dev->driver = NULL;
>>  		dev_set_drvdata(dev, NULL);
>> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index d799662..54e87f5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -10,6 +10,7 @@
>>  #include <linux/dma-mapping.h>
>>  #include <linux/export.h>
>>  #include <linux/gfp.h>
>> +#include <linux/of_device.h>
>>  #include <linux/slab.h>
>>  #include <linux/vmalloc.h>
>>
>> @@ -166,6 +167,16 @@ void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
>>  }
>>  EXPORT_SYMBOL(dmam_free_noncoherent);
>>
>> +int dma_configure(struct device *dev)
>> +{
>> +	return of_dma_configure(dev, dev->of_node);
>> +}
>> +
>> +void dma_deconfigure(struct device *dev)
>> +{
>> +	of_dma_deconfigure(dev);
>> +}
>> +
>>  #ifdef CONFIG_HAVE_GENERIC_DMA_COHERENT
>>
>>  static void dmam_coherent_decl_release(struct device *dev, void *res)
>> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
>> index 9cb7090..adbd77c 100644
>> --- a/drivers/of/platform.c
>> +++ b/drivers/of/platform.c
>> @@ -181,11 +181,9 @@ static struct platform_device *of_platform_device_create_pdata(
>>
>>  	dev->dev.bus = &platform_bus_type;
>>  	dev->dev.platform_data = platform_data;
>> -	of_dma_configure(&dev->dev, dev->dev.of_node);
>>  	of_msi_configure(&dev->dev, dev->dev.of_node);
>>
>>  	if (of_device_add(dev) != 0) {
>> -		of_dma_deconfigure(&dev->dev);
>>  		platform_device_put(dev);
>>  		goto err_clear_flag;
>>  	}
>> @@ -242,7 +240,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>>  		dev_set_name(&dev->dev, "%s", bus_id);
>>  	else
>>  		of_device_make_bus_id(&dev->dev);
>> -	of_dma_configure(&dev->dev, dev->dev.of_node);
>>
>>  	/* Allow the HW Peripheral ID to be overridden */
>>  	prop = of_get_property(node, "arm,primecell-periphid", NULL);
>> @@ -536,7 +533,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
>>  		amba_device_unregister(to_amba_device(dev));
>>  #endif
>>
>> -	of_dma_deconfigure(dev);
>>  	of_node_clear_flag(dev->of_node, OF_POPULATED);
>>  	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
>>  	return 0;
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 93f280d..85c9553 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1724,10 +1724,7 @@ static void pci_dma_configure(struct pci_dev *dev)
>>  {
>>  	struct device *bridge = pci_get_host_bridge_device(dev);
>>
>> -	if (IS_ENABLED(CONFIG_OF) &&
>> -		bridge->parent && bridge->parent->of_node) {
>> -			of_dma_configure(&dev->dev, bridge->parent->of_node);
>> -	} else if (has_acpi_companion(bridge)) {
>> +	if (has_acpi_companion(bridge)) {
>>  		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
>>  		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
>
>It seems a bit awkward leaving pci_dma_configure here, doing DMA
>configuration at device add, after we've allegedly moved DMA
>configuration to driver probe. Lorenzo, do you foresee any issues if
>this probe-time of_dma_configure() path were to also multiplex
>acpi_dma_configure() in future, such that everything would be back in
>the same place eventually?
>
>Conversely, is there actually any issue with leaving pci_dma_configure()
>unchanged, and simply moving the call from pci_device_add() into
>dma_configure()?

Ya i removed only the CONFIG_OF part out of this, and was hoping that
the acpi configure can also be called from the dma_configure during
probe later. I did not have an ACPI based platform though.
 As you said, if that looks right to the ACPI world, it can be
moved out from here. I can try mergin series (after fixing the vfio errors
 part) with the ACPI IO port and see how it behaves.

Regards,
 Sricharan
  

^ permalink raw reply

* [PATCH v2 4/4] ARM: dts: da850: Add the usb otg device node
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

This adds the device tree node for the usb otg
controller present in the da850 family of SoC's.
This also enables the otg usb controller for the lcdk board.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 arch/arm/boot/dts/da850-lcdk.dts |  8 ++++++++
 arch/arm/boot/dts/da850.dtsi     | 15 +++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 7b8ab21..9f5040c 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -158,6 +158,14 @@
 	rx-num-evt = <32>;
 };
 
+&usb_phy {
+	status = "okay";
+	};
+
+&usb0 {
+	status = "okay";
+};
+
 &aemif {
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_pins>;
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index f79e1b9..322a31a 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -372,6 +372,21 @@
 					>;
 			status = "disabled";
 		};
+		usb_phy: usb-phy {
+			compatible = "ti,da830-usb-phy";
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+		usb0: usb at 200000 {
+			compatible = "ti,da830-musb";
+			reg = <0x200000 0x10000>;
+			interrupts = <58>;
+			interrupt-names = "mc";
+			dr_mode = "otg";
+			phys = <&usb_phy 0>;
+			phy-names = "usb-phy";
+			status = "disabled";
+		};
 		gpio: gpio at 226000 {
 			compatible = "ti,dm6441-gpio";
 			gpio-controller;
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 3/4] usb: musb: da8xx: Add DT support for the DA8xx driver
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

This adds DT support for TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver

Signed-off-by: Petr Kulhavy <petr@barix.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 drivers/usb/musb/da8xx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 210b7e4..bfa571d 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -6,6 +6,9 @@
  * Based on the DaVinci "glue layer" code.
  * Copyright (C) 2005-2006 by Texas Instruments
  *
+ * DT support
+ * Copyright (c) 2016 Petr Kulhavy <petr@barix.com>
+ *
  * This file is part of the Inventra Controller Driver for Linux.
  *
  * The Inventra Controller Driver for Linux is free software; you
@@ -433,6 +436,21 @@ static int da8xx_musb_exit(struct musb *musb)
 	return 0;
 }
 
+static inline u8 get_vbus_power(struct device *dev)
+{
+	struct regulator *vbus_supply;
+	int current_uA;
+
+	vbus_supply = regulator_get_optional(dev, "vbus");
+	if (IS_ERR(vbus_supply))
+		return 255;
+	current_uA = regulator_get_current_limit(vbus_supply);
+	regulator_put(vbus_supply);
+	if (current_uA <= 0 || current_uA > 510000)
+		return 255;
+	return current_uA / 1000 / 2;
+}
+
 static const struct musb_platform_ops da8xx_ops = {
 	.quirks		= MUSB_DMA_CPPI | MUSB_INDEXED_EP,
 	.init		= da8xx_musb_init,
@@ -458,6 +476,12 @@ static const struct platform_device_info da8xx_dev_info = {
 	.dma_mask	= DMA_BIT_MASK(32),
 };
 
+static const struct musb_hdrc_config da8xx_config = {
+	.ram_bits = 10,
+	.num_eps = 5,
+	.multipoint = 1,
+};
+
 static int da8xx_probe(struct platform_device *pdev)
 {
 	struct resource musb_resources[2];
@@ -465,7 +489,9 @@ static int da8xx_probe(struct platform_device *pdev)
 	struct da8xx_glue		*glue;
 	struct platform_device_info	pinfo;
 	struct clk			*clk;
+	struct device_node		*np = pdev->dev.of_node;
 	int				ret;
+	struct resource *res;
 
 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
 	if (!glue)
@@ -486,6 +512,18 @@ static int da8xx_probe(struct platform_device *pdev)
 	glue->dev			= &pdev->dev;
 	glue->clk			= clk;
 
+	if (IS_ENABLED(CONFIG_OF) && np) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			/* FIXME */
+			return -ENOMEM;
+		}
+
+		pdata->config	= &da8xx_config;
+		pdata->mode	= musb_get_mode(&pdev->dev);
+		pdata->power	= get_vbus_power(&pdev->dev);
+	}
+
 	pdata->platform_ops		= &da8xx_ops;
 
 	glue->usb_phy = usb_phy_generic_register();
@@ -536,11 +574,20 @@ static int da8xx_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id da8xx_id_table[] = {
+	{
+		.compatible = "ti,da830-musb",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, da8xx_id_table);
+
 static struct platform_driver da8xx_driver = {
 	.probe		= da8xx_probe,
 	.remove		= da8xx_remove,
 	.driver		= {
 		.name	= "musb-da8xx",
+		.of_match_table = of_match_ptr(da8xx_id_table),
 	},
 };
 
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 2/4] usb: musb: core: added helper function for parsing DT
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

This adds the function musb_get_mode() to get the DT property "dr_mode"

Signed-off-by: Petr Kulhavy <petr@barix.com>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 drivers/usb/musb/musb_core.c | 19 +++++++++++++++++++
 drivers/usb/musb/musb_core.h |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 27dadc0..bba07e7 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -100,6 +100,7 @@
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb.h>
+#include <linux/usb/of.h>
 
 #include "musb_core.h"
 #include "musb_trace.h"
@@ -130,6 +131,24 @@ static inline struct musb *dev_to_musb(struct device *dev)
 	return dev_get_drvdata(dev);
 }
 
+enum musb_mode musb_get_mode(struct device *dev)
+{
+	enum usb_dr_mode mode;
+
+	mode = usb_get_dr_mode(dev);
+	switch (mode) {
+	case USB_DR_MODE_HOST:
+		return MUSB_HOST;
+	case USB_DR_MODE_PERIPHERAL:
+		return MUSB_PERIPHERAL;
+	case USB_DR_MODE_OTG:
+	case USB_DR_MODE_UNKNOWN:
+	default:
+		return MUSB_OTG;
+	}
+}
+EXPORT_SYMBOL_GPL(musb_get_mode);
+
 /*-------------------------------------------------------------------------*/
 
 #ifndef CONFIG_BLACKFIN
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 2cb88a49..a406468 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -617,4 +617,9 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb)
 		musb->ops->post_root_reset_end(musb);
 }
 
+/* gets the "dr_mode" property from DT and converts it into musb_mode
+ * if the property is not found or not recognized returns MUSB_OTG
+ */
+extern enum musb_mode musb_get_mode(struct device *dev);
+
 #endif	/* __MUSB_CORE_H__ */
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 1/4] dt/bindings: Add binding for the DA8xx MUSB driver
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477494237-22831-1-git-send-email-abailon@baylibre.com>

From: Petr Kulhavy <petr@barix.com>

DT binding for the TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver.

Signed-off-by: Petr Kulhavy <petr@barix.com>
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 .../devicetree/bindings/usb/da8xx-usb.txt          | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/da8xx-usb.txt

diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
new file mode 100644
index 0000000..5663d79
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
@@ -0,0 +1,43 @@
+TI DA8xx MUSB
+~~~~~~~~~~~~~
+For DA8xx/OMAP-L1x/AM17xx/AM18xx platforms.
+
+Required properties:
+~~~~~~~~~~~~~~~~~~~~
+ - compatible : Should be set to "ti,da830-musb".
+
+ - reg: Offset and length of the USB controller register set.
+
+ - interrupts: The USB interrupt number.
+
+ - interrupt-names: Should be set to "mc".
+
+ - dr_mode: The USB operation mode. Should be one of "host", "peripheral" or "otg".
+
+ - phys: Phandle for the PHY device
+
+ - phy-names: Should be "usb-phy"
+
+Optional properties:
+~~~~~~~~~~~~~~~~~~~~
+ - vbus-supply: Phandle to a regulator providing the USB bus power.
+
+Example:
+	usb_phy: usb-phy {
+		compatible = "ti,da830-usb-phy";
+		#phy-cells = <0>;
+		status = "okay";
+	};
+	usb20: usb at 1e00000 {
+		compatible = "ti,da830-musb";
+		reg =   <0x00200000 0x10000>;
+		interrupts = <58>;
+		interrupt-names = "mc";
+
+		dr_mode = "host";
+		vbus-supply = <&usb_vbus>;
+		phys = <&usb_phy 0>;
+		phy-names = "usb-phy";
+
+		status = "okay";
+	};
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 0/4] Add DT support for DA8xx
From: Alexandre Bailon @ 2016-10-26 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

The purpose of this series is to add DT support to the da8xx USB OTG.
This series should apply and build without any issues but it has
some dependencies on "Add DT support for ohci-da8xx" series.
Without it, the phy init will fail and then the da8xx driver will also fail.

Changes in v2:
* Remove unrelated changes in patch 3
* Rename the device node in patch 4

Alexandre Bailon (1):
  ARM: dts: da850: Add the usb otg device node

Petr Kulhavy (3):
  dt/bindings: Add binding for the DA8xx MUSB driver
  usb: musb: core: added helper function for parsing DT
  usb: musb: da8xx: Add DT support for the DA8xx driver

 .../devicetree/bindings/usb/da8xx-usb.txt          | 43 ++++++++++++++++++++
 arch/arm/boot/dts/da850-lcdk.dts                   |  8 ++++
 arch/arm/boot/dts/da850.dtsi                       | 15 +++++++
 drivers/usb/musb/da8xx.c                           | 47 ++++++++++++++++++++++
 drivers/usb/musb/musb_core.c                       | 19 +++++++++
 drivers/usb/musb/musb_core.h                       |  5 +++
 6 files changed, 137 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/da8xx-usb.txt

-- 
2.7.3

^ permalink raw reply

* [RFC PATCH 5/5] of: overlay-mgr: add a detector for headers stored on a ds2431 eeprom over w1
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026145756.21689-1-antoine.tenart@free-electrons.com>

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/of/overlay-manager/Kconfig | 10 ++++++++++
 drivers/w1/slaves/w1_ds2431.c      | 39 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/of/overlay-manager/Kconfig b/drivers/of/overlay-manager/Kconfig
index 1a36613c0c53..ad0a5b8e9e5e 100644
--- a/drivers/of/overlay-manager/Kconfig
+++ b/drivers/of/overlay-manager/Kconfig
@@ -16,4 +16,14 @@ config OF_OVERLAY_MGR_FORMAT_CHIP
 
 endmenu
 
+menu "Overlay Manager detectors"
+
+config OF_OVERLAY_MGR_DETECTOR_DS2431
+	bool "Dip header on a DS2431 EEPROM"
+	depends on W1_SLAVE_DS2431
+	help
+	  Enable dip header DS2431 EEPROM support.
+
+endmenu
+
 endif
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
index 80572cb63ba8..760325f9a2bd 100644
--- a/drivers/w1/slaves/w1_ds2431.c
+++ b/drivers/w1/slaves/w1_ds2431.c
@@ -15,6 +15,9 @@
 #include <linux/device.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <linux/overlay-manager.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
@@ -280,7 +283,43 @@ static const struct attribute_group *w1_f2d_groups[] = {
 	NULL,
 };
 
+#if IS_ENABLED(CONFIG_OF_OVERLAY_MGR_DETECTOR_DS2431)
+static int chip_dip_callback(struct w1_slave *sl)
+{
+	char **candidates = NULL;
+	int i, n, err = 0;
+	u8 *data;
+
+	data = kzalloc(OVERLAY_MGR_DIP_MAX_SZ, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* sizeof(struct chip_header) is a mulitple of 8 */
+	for (i = 0; i < OVERLAY_MGR_DIP_MAX_SZ; i += 8) {
+		if (w1_f2d_readblock(sl, i, 8, &data[i])) {
+			err = -EIO;
+			goto end;
+		}
+	}
+
+	overlay_mgr_parse(&sl->dev, data, &candidates, &n);
+	if (!n) {
+		err = -EINVAL;
+		goto end;
+	}
+
+	err = overlay_mgr_apply(&sl->dev, candidates, n);
+
+end:
+	kfree(data);
+	return err;
+}
+#endif
+
 static struct w1_family_ops w1_f2d_fops = {
+#if IS_ENABLED(CONFIG_OF_OVERLAY_MGR_DETECTOR_DS2431)
+	.callback	= chip_dip_callback,
+#endif
 	.groups		= w1_f2d_groups,
 };
 
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 4/5] w1: add a callback to call slave when a new device is connected
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026145756.21689-1-antoine.tenart@free-electrons.com>

This patch adds the possibility for slave drivers to register a
callback, to be called whenever a new device matching the slave ID
is connected.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/w1/w1.c        | 10 ++++++++++
 drivers/w1/w1_family.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 80d0cc4e6e7f..7010ffd1ea93 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -659,6 +659,16 @@ static int w1_family_notify(unsigned long action, struct w1_slave *sl)
 				return err;
 			}
 		}
+		if (fops->callback) {
+			err = fops->callback(sl);
+			/*
+			 * Do not return an error as the slave driver correctly
+			 * probed.
+			 */
+			if (err)
+				dev_err(&sl->dev,
+					"callback call failed. err=%d\n", err);
+		}
 
 		break;
 	case BUS_NOTIFY_DEL_DEVICE:
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 10a7a0767187..5e165babc6f3 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -55,11 +55,13 @@ struct w1_slave;
  * @add_slave: add_slave
  * @remove_slave: remove_slave
  * @groups: sysfs group
+ * @callback: called when a new device is discovered
  */
 struct w1_family_ops
 {
 	int  (* add_slave)(struct w1_slave *);
 	void (* remove_slave)(struct w1_slave *);
+	int  (* callback)(struct w1_slave *);
 	const struct attribute_group **groups;
 };
 
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 3/5] w1: report errors returned by w1_family_notify
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026145756.21689-1-antoine.tenart@free-electrons.com>

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/w1/w1.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index bb34362e930a..80d0cc4e6e7f 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -702,7 +702,9 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
 			dev_name(&sl->dev), err);
 		return err;
 	}
-	w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
+	err = w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
+	if (err)
+		return err;
 
 	dev_set_uevent_suppress(&sl->dev, false);
 	kobject_uevent(&sl->dev.kobj, KOBJ_ADD);
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 2/5] of: overlay-mgr: add the CHIP format
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026145756.21689-1-antoine.tenart@free-electrons.com>

Support parsing the header used by capes compatible with Nextthing's
C.H.I.P.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/of/overlay-manager/Kconfig       | 13 ++++++
 drivers/of/overlay-manager/Makefile      |  1 +
 drivers/of/overlay-manager/format-chip.c | 72 ++++++++++++++++++++++++++++++++
 include/linux/overlay-manager.h          | 13 ++++++
 4 files changed, 99 insertions(+)
 create mode 100644 drivers/of/overlay-manager/format-chip.c

diff --git a/drivers/of/overlay-manager/Kconfig b/drivers/of/overlay-manager/Kconfig
index eeb76054dcb8..1a36613c0c53 100644
--- a/drivers/of/overlay-manager/Kconfig
+++ b/drivers/of/overlay-manager/Kconfig
@@ -4,3 +4,16 @@ config OF_OVERLAY_MGR
 	help
 	  Enable the overlay manager to handle automatic overlay loading when
 	  devices are detected.
+
+if OF_OVERLAY_MGR
+
+menu "Dips header formats"
+
+config OF_OVERLAY_MGR_FORMAT_CHIP
+	bool "Nextthing's C.H.I.P. dip header format"
+	help
+	  Enable Nextthing's C.H.I.P. dip header format support.
+
+endmenu
+
+endif
diff --git a/drivers/of/overlay-manager/Makefile b/drivers/of/overlay-manager/Makefile
index 86d2b53950e7..637cc7ba20c2 100644
--- a/drivers/of/overlay-manager/Makefile
+++ b/drivers/of/overlay-manager/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_OF_OVERLAY_MGR)			+= overlay-manager.o
+obj-$(CONFIG_OF_OVERLAY_MGR_FORMAT_CHIP)	+= format-chip.o
diff --git a/drivers/of/overlay-manager/format-chip.c b/drivers/of/overlay-manager/format-chip.c
new file mode 100644
index 000000000000..3a3d315dcb5c
--- /dev/null
+++ b/drivers/of/overlay-manager/format-chip.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 - Antoine Tenart <antoine.tenart@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/device.h>
+#include <linux/overlay-manager.h>
+#include <linux/slab.h>
+
+#define CAPE_CHIP_MAGIC		0x43484950
+#define CAPE_CHIP_VERSION	1
+#define CAPE_CHIP_CANDIDATES	2
+
+static int cape_chip_parse(struct device *dev, void *data, char ***candidates,
+			   unsigned *n)
+{
+	struct chip_header *header = (struct chip_header *)data;
+	char **tmp;
+	int err;
+
+	if (dip_convert(header->magic) != CAPE_CHIP_MAGIC)
+		return -EINVAL;
+
+	if (dip_convert(header->version) > CAPE_CHIP_VERSION)
+		return -EINVAL;
+
+	tmp = devm_kzalloc(dev, CAPE_CHIP_CANDIDATES * sizeof(char *), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	tmp[0] = devm_kasprintf(dev, GFP_KERNEL, "%x-%x-%x",
+				dip_convert(header->vendor_id),
+				dip_convert(header->product_id),
+				dip_convert(header->product_version));
+	if (!tmp[0]) {
+		err = -ENOMEM;
+		goto err_free_list;
+	}
+
+	tmp[1] = devm_kasprintf(dev, GFP_KERNEL, "%x-%x",
+				dip_convert(header->vendor_id),
+				dip_convert(header->product_id));
+	if (!tmp[1]) {
+		err = -ENOMEM;
+		goto err_free_0;
+	}
+
+	*candidates = tmp;
+	*n = CAPE_CHIP_CANDIDATES;
+
+	return 0;
+
+err_free_0:
+	devm_kfree(dev, tmp[0]);
+err_free_list:
+	devm_kfree(dev, tmp);
+	return err;
+}
+
+static struct overlay_mgr_format format_chip = {
+	.name	= "Nextthing C.H.I.P. dip header format",
+	.parse	= &cape_chip_parse,
+};
+
+static int __init cape_chip_init(void)
+{
+	return overlay_mgr_register_format(&format_chip);
+}
+device_initcall(cape_chip_init);
diff --git a/include/linux/overlay-manager.h b/include/linux/overlay-manager.h
index 8adcc4f5ddf6..d76c3c9fd863 100644
--- a/include/linux/overlay-manager.h
+++ b/include/linux/overlay-manager.h
@@ -35,4 +35,17 @@ int overlay_mgr_apply(struct device *dev, char **candidates, unsigned n);
                 -1                                              \
         )
 
+/* Nextthing's C.H.I.P. dip header */
+struct chip_header {
+        u32     magic;                  /* rsvd */
+        u8      version;                /* spec version */
+        u32     vendor_id;
+        u16     product_id;
+        u8      product_version;
+        char    vendor_name[32];
+        char    product_name[32];
+        u8      rsvd[36];               /* rsvd for futre spec versions */
+        u8      data[16];               /* user data, per-cape specific */
+} __packed;
+
 #endif /* __OVERLAY_MGR_H__ */
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 1/5] of: introduce the overlay manager
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026145756.21689-1-antoine.tenart@free-electrons.com>

The overlay manager is an in-kernel library helping to handle dt overlay
loading when using capes.

Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
---
 drivers/of/Kconfig                           |   2 +
 drivers/of/Makefile                          |   1 +
 drivers/of/overlay-manager/Kconfig           |   6 +
 drivers/of/overlay-manager/Makefile          |   1 +
 drivers/of/overlay-manager/overlay-manager.c | 199 +++++++++++++++++++++++++++
 include/linux/overlay-manager.h              |  38 +++++
 6 files changed, 247 insertions(+)
 create mode 100644 drivers/of/overlay-manager/Kconfig
 create mode 100644 drivers/of/overlay-manager/Makefile
 create mode 100644 drivers/of/overlay-manager/overlay-manager.c
 create mode 100644 include/linux/overlay-manager.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index bc07ad30c9bf..e57aeaf0bf4f 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -116,4 +116,6 @@ config OF_OVERLAY
 config OF_NUMA
 	bool
 
+source "drivers/of/overlay-manager/Kconfig"
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index d7efd9d458aa..d738fd41271f 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.o
 obj-$(CONFIG_OF_NUMA) += of_numa.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
+obj-y += overlay-manager/
diff --git a/drivers/of/overlay-manager/Kconfig b/drivers/of/overlay-manager/Kconfig
new file mode 100644
index 000000000000..eeb76054dcb8
--- /dev/null
+++ b/drivers/of/overlay-manager/Kconfig
@@ -0,0 +1,6 @@
+config OF_OVERLAY_MGR
+	bool "Device Tree Overlay Manager"
+	depends on OF_OVERLAY
+	help
+	  Enable the overlay manager to handle automatic overlay loading when
+	  devices are detected.
diff --git a/drivers/of/overlay-manager/Makefile b/drivers/of/overlay-manager/Makefile
new file mode 100644
index 000000000000..86d2b53950e7
--- /dev/null
+++ b/drivers/of/overlay-manager/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_OF_OVERLAY_MGR)			+= overlay-manager.o
diff --git a/drivers/of/overlay-manager/overlay-manager.c b/drivers/of/overlay-manager/overlay-manager.c
new file mode 100644
index 000000000000..a725d7e24d38
--- /dev/null
+++ b/drivers/of/overlay-manager/overlay-manager.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016 - Antoine Tenart <antoine.tenart@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/firmware.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/overlay-manager.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+struct overlay_mgr_overlay {
+	struct list_head list;
+	char *name;
+};
+
+LIST_HEAD(overlay_mgr_overlays);
+LIST_HEAD(overlay_mgr_formats);
+DEFINE_SPINLOCK(overlay_mgr_lock);
+DEFINE_SPINLOCK(overlay_mgr_format_lock);
+
+/*
+ * overlay_mgr_register_format()
+ *
+ * Adds a new format candidate to the list of supported formats. The registered
+ * formats are used to parse the headers stored on the dips.
+ */
+int overlay_mgr_register_format(struct overlay_mgr_format *candidate)
+{
+	struct overlay_mgr_format *format;
+	int err = 0;
+
+	spin_lock(&overlay_mgr_format_lock);
+
+	/* Check if the format is already registered */
+	list_for_each_entry(format, &overlay_mgr_formats, list) {
+		if (!strcpy(format->name, candidate->name)) {
+			err = -EEXIST;
+			goto err;
+		}
+	}
+
+	list_add_tail(&candidate->list, &overlay_mgr_formats);
+
+err:
+	spin_unlock(&overlay_mgr_format_lock);
+	return err;
+}
+EXPORT_SYMBOL_GPL(overlay_mgr_register_format);
+
+/*
+ * overlay_mgr_parse()
+ *
+ * Parse raw data with registered format parsers. Fills the candidate string if
+ * one parser understood the raw data format.
+ */
+int overlay_mgr_parse(struct device *dev, void *data, char ***candidates,
+		      unsigned *n)
+{
+	struct list_head *pos, *tmp;
+	struct overlay_mgr_format *format;
+
+	list_for_each_safe(pos, tmp, &overlay_mgr_formats) {
+		format = list_entry(pos, struct overlay_mgr_format, list);
+
+		format->parse(dev, data, candidates, n);
+		if (n > 0)
+			return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(overlay_mgr_parse);
+
+static int overlay_mgr_check_overlay(struct device_node *node)
+{
+	struct property *p;
+	const char *str = NULL;
+
+	p = of_find_property(node, "compatible", NULL);
+	if (!p)
+		return -EINVAL;
+
+	do {
+		str = of_prop_next_string(p, str);
+		if (of_machine_is_compatible(str))
+			return 0;
+	} while (str);
+
+	return -EINVAL;
+}
+
+/*
+ * _overlay_mgr_insert()
+ *
+ * Try to request and apply an overlay given a candidate name.
+ */
+static int _overlay_mgr_apply(struct device *dev, char *candidate)
+{
+	struct overlay_mgr_overlay *overlay;
+	struct device_node *node;
+	const struct firmware *firmware;
+	char *firmware_name;
+	int err = 0;
+
+	spin_lock(&overlay_mgr_lock);
+
+	list_for_each_entry(overlay, &overlay_mgr_overlays, list) {
+		if (!strcmp(overlay->name, candidate)) {
+			dev_err(dev, "overlay already loaded\n");
+			err = -EEXIST;
+			goto err_lock;
+		}
+	}
+
+	overlay = devm_kzalloc(dev, sizeof(*overlay), GFP_KERNEL);
+	if (!overlay) {
+		err = -ENOMEM;
+		goto err_lock;
+	}
+
+	overlay->name = candidate;
+
+	firmware_name = kasprintf(GFP_KERNEL, "overlay-%s.dtbo", candidate);
+	if (!firmware_name) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	dev_info(dev, "requesting firmware '%s'\n", firmware_name);
+
+	err = request_firmware_direct(&firmware, firmware_name, dev);
+	if (err) {
+		dev_info(dev, "failed to request firmware '%s'\n",
+			 firmware_name);
+		goto err_free;
+	}
+
+	of_fdt_unflatten_tree((unsigned long *)firmware->data, NULL, &node);
+	if (!node) {
+		dev_err(dev, "failed to unflatted tree\n");
+		err = -EINVAL;
+		goto err_fw;
+	}
+
+	of_node_set_flag(node, OF_DETACHED);
+
+	err = of_resolve_phandles(node);
+	if (err) {
+		dev_err(dev, "failed to resolve phandles: %d\n", err);
+		goto err_fw;
+	}
+
+	err = overlay_mgr_check_overlay(node);
+	if (err) {
+		dev_err(dev, "overlay checks failed: %d\n", err);
+		goto err_fw;
+	}
+
+	err = of_overlay_create(node);
+	if (err < 0) {
+		dev_err(dev, "failed to create overlay: %d\n", err);
+		goto err_fw;
+	}
+
+	list_add_tail(&overlay->list, &overlay_mgr_overlays);
+
+	dev_info(dev, "loaded firmware '%s'\n", firmware_name);
+
+	spin_unlock(&overlay_mgr_lock);
+	return 0;
+
+err_fw:
+	release_firmware(firmware);
+err_free:
+	devm_kfree(dev, overlay);
+err_lock:
+	spin_unlock(&overlay_mgr_lock);
+	return err;
+}
+
+int overlay_mgr_apply(struct device *dev, char **candidates, unsigned n)
+{
+	int i, ret;
+
+	for (i=0; i < n; i++) {
+		ret = _overlay_mgr_apply(dev, candidates[i]);
+		if (!ret)
+			return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(overlay_mgr_apply);
diff --git a/include/linux/overlay-manager.h b/include/linux/overlay-manager.h
new file mode 100644
index 000000000000..8adcc4f5ddf6
--- /dev/null
+++ b/include/linux/overlay-manager.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 - Antoine Tenart <antoine.tenart@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __OVERLAY_MGR_H__
+#define __OVERLAY_MGR_H__
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/sizes.h>
+
+#define OVERLAY_MGR_DIP_MAX_SZ		SZ_128
+
+struct overlay_mgr_format {
+	struct list_head list;
+	char *name;
+	int (*parse)(struct device *dev, void *data, char ***candidates,
+		     unsigned *n);
+};
+
+int overlay_mgr_register_format(struct overlay_mgr_format *candidate);
+int overlay_mgr_parse(struct device *dev, void *data, char ***candidates,
+		      unsigned *n);
+int overlay_mgr_apply(struct device *dev, char **candidates, unsigned n);
+
+#define dip_convert(field)                                      \
+        (                                                       \
+                (sizeof(field) == 1) ? field :                  \
+                (sizeof(field) == 2) ? be16_to_cpu(field) :     \
+                (sizeof(field) == 4) ? be32_to_cpu(field) :     \
+                -1                                              \
+        )
+
+#endif /* __OVERLAY_MGR_H__ */
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 0/5] Add an overlay manager to handle board capes
From: Antoine Tenart @ 2016-10-26 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Many boards now come with dips and compatible capes; among others the
C.H.I.P, or Beaglebones. All these boards have a kernel implementing an
out-of-tree "cape manager" which is used to detected capes, retrieve
their description and apply a corresponding overlay. This series is an
attempt to start a discussion, with an implementation of such a manager
which is somehow generic (i.e. formats or cape detectors can be added).
Other use cases could make use of this manager to dynamically load dt
overlays based on some input / hw presence.

The proposed design is a library which can be used by detector drivers
to parse headers and load the corresponding overlay. Helpers are
provided for this purpose. The whole thing is divided into 3 entities:

- The parser which is project-specific (to allow supporting headers
  already into the wild). It registers a function parsing an header's
  data and filling one or more strings which will be used to find
  matching dtbo on the fs.

- The overlay manager helpers allowing to parse a header to retrieve
  the previously mentioned strings and to load a compatible overlay.

- The detectors which are used to detect capes and get their description
  (to be parsed).

An example of parser and detector is given, compatible with what's done
for the C.H.I.P. As the w1 framework is really bad (and we should
probably do something about that) the detector code is far from being
perfect; but that's not related to what we try to achieve here.

The actual implementation has a limitation: the detectors cannot be
built-in the kernel image as they would likely detect capes at boot time
but will fail to get their corresponding dt overlays as the fs isn't
mounted yet. The only case this can work is when dt overlays are
built-in firmwares. This isn't an issue for the C.H.I.P. use case right
now. There was a discussion about making an helper to wait for the
rootfs to be mount but the answer was "this is the driver's problem".

I'd like to get comments, specifically from people using custom cape
managers, to see if this could fill their needs (with I guess some
modifications).

Thanks!

Antoine

Antoine Tenart (5):
  of: introduce the overlay manager
  of: overlay-mgr: add the CHIP format
  w1: report errors returned by w1_family_notify
  w1: add a callback to call slave when a new device is connected
  of: overlay-mgr: add a detector for headers stored on a ds2431 eeprom
    over w1

 drivers/of/Kconfig                           |   2 +
 drivers/of/Makefile                          |   1 +
 drivers/of/overlay-manager/Kconfig           |  29 ++++
 drivers/of/overlay-manager/Makefile          |   2 +
 drivers/of/overlay-manager/format-chip.c     |  72 ++++++++++
 drivers/of/overlay-manager/overlay-manager.c | 199 +++++++++++++++++++++++++++
 drivers/w1/slaves/w1_ds2431.c                |  39 ++++++
 drivers/w1/w1.c                              |  14 +-
 drivers/w1/w1_family.h                       |   2 +
 include/linux/overlay-manager.h              |  51 +++++++
 10 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 drivers/of/overlay-manager/Kconfig
 create mode 100644 drivers/of/overlay-manager/Makefile
 create mode 100644 drivers/of/overlay-manager/format-chip.c
 create mode 100644 drivers/of/overlay-manager/overlay-manager.c
 create mode 100644 include/linux/overlay-manager.h

-- 
2.10.1

^ permalink raw reply


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