* [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
* [PATCH] tty/serial: at91: fix hardware handshake on Atmel platforms
From: Richard Genoud @ 2016-10-26 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161025171754.a4lult2ld3gv5a2q@pengutronix.de>
On 25/10/2016 19:17, Uwe Kleine-K?nig wrote:
> Hello,
>
> On Tue, Oct 25, 2016 at 06:11:35PM +0200, Richard Genoud wrote:
>> commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when
>> hardware handshake is enabled"), despite its title, broke hardware
>> handshake on *every* Atmel platforms.
>
> s/platforms/platform/
fixed.
>> The only one partially working is the SAMA5D2.
>>
>> To understand why, one has to understand the flag ATMEL_US_USMODE_HWHS
>> first:
>> Before commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management
>> when hardware handshake is enabled"), this flag was never set.
>> Thus, the CTS/RTS where only handled by serial_core (and everything
>> worked just fine).
>>
>> This commit introduced the use of the ATMEL_US_USMODE_HWHS flag,
>> enabling it for all boards when the user space enables flow control.
>>
>> When the ATMEL_US_USMODE_HWHS is set, the Atmel USART controller
>> handles a part of the flow control job:
>> - disable the transmitter when the CTS pin gets high.
>> - drive the RTS pin high when the DMA buffer transfer is completed or
>> PDC RX buffer full or RX FIFO is beyond threshold. (depending on the
>> controller version).
>
> I don't understand the DMA buffer part.
see below.
>
>> NB: This feature is *not* mandatory for the flow control to work.
>>
>> Now, the specifics of the ATMEL_US_USMODE_HWHS flag:
>>
>> - For platforms with DMAC and no FIFOs (sam9x25, sam9x35, sama5D3,
>> sama5D4, sam9g15, sam9g25, sam9g35)* this feature simply doesn't work.
>> ( source: https://lkml.org/lkml/2016/9/7/598 )
>
> What does "doesn't work" mean? Is ATMEL_US_USMODE_HWHS a noop, or does
> it break something?
Here is what the datasheet says:
"The RTS pin is driven high if the receiver is disabled or if the DMA
status flag indicates that the buffer transfer is completed.[...]
As soon as the receiver is enabled, the RTS falls, indicating to the
remote device that it can start transmitting. Defining a new transfer
descriptor in the DMA clears the status flag and, as a result, asserts
the pin RTS low."
And what's really happening:
RTS pin is stuck at high level.
Even if the receiver is enabled, or if there's a new descriptor is
the DMA, RTS is always high.
And if RTS is high, nothing can be received.
(RTS==1 means NOT ready to receive).
So it's definitely not a noop, since RX is blocked.
>
>> Tested it on sam9g35, the RTS pins always stays up, even when RXEN=1
>> or a new DMA transfer descriptor is set.
>> => ATMEL_US_USMODE_HWHS should not be used for those platforms
>
> Depending on the answer to the above question it might not matter if it
> is set or not.
>
>> - For platforms with a PDC (sam926{0,1,3}, sam9g10, sam9g20, sam9g45,
>> sam9g46)*, there's another kind of problem. Once the flag
>> ATMEL_US_USMODE_HWHS is set, the RTS pin can't be driven anymore via
>> RTSEN/RTSDIS in USART Control Register. The RTS pin can only be driven
>> by enabling/disabling the receiver or setting RCR=RNCR=0 in the PDC
>> (Receive (Next) Counter Register).
>> => Doing this is beyond the scope of this patch and could add other
>> bugs, so the original (and working) behaviour should be set for those
>> platforms (meaning ATMEL_US_USMODE_HWHS flag should be unset).
>
> Then maybe just revert the faulty patch for now and do it better later
> on top of this?
Well, we can't just revert 1cf6e8fc8341 without breaking sama5d2 platform.
And at the end, reverting 1cf6e8fc8341 without breaking sama5d2 will result
in a patch exactly like (or at least *very* similar to) this one.
>> - For platforms with a FIFO (sama5d2)*, the RTS pin is driven according
>> to the RX FIFO thresholds, and can be also driven by RTSEN/RTSDIS in
>> USART Control Register. No problem here.
>> (This was the use case of commit 1cf6e8fc8341 ("tty/serial: at91: fix
>> RTS line management when hardware handshake is enabled"))
>> NB: If the CTS pin declared as a GPIO in the DTS, (for instance
>> cts-gpios = <&pioA PIN_PB31 GPIO_ACTIVE_LOW>), the transmitter will be
>> disabled.
>> => ATMEL_US_USMODE_HWHS flag can be set for this platform ONLY IF the
>> CTS pin is not a GPIO.
>
> How did you test this? What I consider interesting here is if the
> hardware CTS function was muxed on a pin and in which state this pin (if
> any) is. If it is not muxed anywhere and disables the transmitter
> because of an internal pull up that is IMHO a hw bug and should be
> mentioned more explicitly in the comment.
I see your point, and I did some more tests.
NB: The CTS pin is PD29 (on flx2 on sama5D2).
- If I use PD24 as CTS-gpio for flx2 and PD29 is not muxed (so, as an input):
The transmitter is disabled no matter what value PD24 or PD29 are.
In the same use case, if PD29 is exported as GPIO (output), the transmitter stay disabled for every value.
- If I use PD24 as CTS-gpio for flx2 and PD39 is muxed as another function (I tried TWD0), the transmitter is also disabled.
- If I use PD24 as CTS-gpio for flx2 and PD29 is muxed as CTS function, I can activate the transmitter by setting PD29 to 0V.
- If I use PD29 as CTS-gpio, the transmitter is still disabled.
In all this tests, if I do:
devmem2 0xFC010204 w 0xC00008C0
i.e. remove the ATMEL_US_USMODE_HWHS flag in flx2 usart, the transmitter starts transmitting.
So, I guess, like you said, that there's an internal pull-up on the CTS input.
I can add some comment about that.
>> So, the only case when ATMEL_US_USMODE_HWHS can be enabled is when
>> (atmel_use_fifo(port) &&
>> !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS))
>>
>> Tested on all Atmel USART controller flavours:
>> AT91SAM9G35-CM, AT91SAM9G20-EK and SAMA5D2xplained
>> ^^^^ ^^^^ ^^^^
>> (DMAC flavour), (PDC flavour) and (FIFO flavour)
>
> I'd write that as: Tested on all Atmel USART controller flavours:
> AT91SAM9G35-CM (DMAC flavour), AT91SAM9G20-EK (PDC flavour),
> SAMA5D2xplained (FIFO flavour).
alright.
>> Changes since v4:
>> - the mctrl_gpio_use_rtscts() is gone since it was atmel_serial
>> specific. (so patch 1 is gone)
>> - patches 2 and 3 have been merged together since it didn't make
>> a lot of sense to correct the GPIO case in one separate patch.
>> - ATMEL_US_USMODE_HWHS is now unset for platform with PDC
>>
>> Changes since v3:
>> - remove superfluous #include <linux/err.h> (thanks to Uwe)
>> - rebase on next-20160930
>>
>> Changes since v2:
>> - remove IS_ERR_OR_NULL() test in patch 1/3 as Uwe suggested.
>> - fix typos in patch 2/3
>> - rebase on next-20160927
>> - simplify the logic in patch 3/3.
>>
>> Changes since v1:
>> - Correct patch 1 with the error found by kbuild.
>> - Add Alexandre's Acked-by on patch 2
>> - Rewrite patch 3 logic in the light of the on-going discussion
>> with Cyrille and Alexandre.
>>
>> * the list may not be exhaustive
>
> Add a Fixes: line please.
ok.
>> Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
>> ---
>> drivers/tty/serial/atmel_serial.c | 25 +++++++++++++++++++++----
>> 1 file changed, 21 insertions(+), 4 deletions(-)
>>
>> I think this should go in the stable tree since it fixes the flow
>> control broken since v4.0.
>> But It won't compile on versions before 4.9rc1 because:
>> function atmel_use_fifo was introduced in 4.4.12 / 4.7
>> variable atmel_port was introduced in 4.9rc1
>>
>> That's why I didn't add the Cc stable in the email body.
>>
>>
>> diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
>> index fd8aa1f4ba78..2c7c45904ba7 100644
>> --- a/drivers/tty/serial/atmel_serial.c
>> +++ b/drivers/tty/serial/atmel_serial.c
>> @@ -2132,11 +2132,28 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
>> mode |= ATMEL_US_USMODE_RS485;
>> } else if (termios->c_cflag & CRTSCTS) {
>> /* RS232 with hardware handshake (RTS/CTS) */
>> - if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
>> - dev_info(port->dev, "not enabling hardware flow control because DMA is used");
>> - termios->c_cflag &= ~CRTSCTS;
>
> This if was not introduced in commit 1cf6e8fc8341. Is it still right to
> remove this here?
This was introduced by commit 5be605ac9af9 that tried to fix
commit 1cf6e8fc8341 but based on a false assumption.
Quote from the commit message:
" Commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when
hardware handshake is enabled") actually allowed to enable hardware
handshaking.
Before, the CRTSCTS flags was silently ignored.
"
This wasn't true.
This was a misunderstanding of the ATMEL_US_USMODE_HWHS flag:
Commit 1cf6e8fc8341 didn't allowed to enable hardware handshaking, but
introduced the ATMEL_US_USMODE_HWHS flag.
And before 1cf6e8fc8341, the CRTSCTS flags wasn't silently ignored, it
was perfectly respected.
So, yes, I'm quite comfortable removing those lines here.
(maybe I should add a Fixes: 5be605ac9af9 ?)
Otherwise, we can do it the hard way, and:
- revert 5be605ac9af9 ("tty/serial: atmel: fix hardware handshake selection)"
- then apply something like:
mode |= ATMEL_US_USMODE_RS485;
} else if (termios->c_cflag & CRTSCTS) {
/* RS232 with hardware handshake (RTS/CTS) */
- mode |= ATMEL_US_USMODE_HWHS;
+ if (atmel_use_fifo(port) &&
+ !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
+ mode |= ATMEL_US_USMODE_HWHS;
+ } else {
+ mode |= ATMEL_US_USMODE_NORMAL;
+ }
} else {
/* RS232 without hadware handshake */
mode |= ATMEL_US_USMODE_NORMAL;
Or even harder:
- revert 5be605ac9af9 ("tty/serial: atmel: fix hardware handshake selection)"
- then apply something like:
if (port->rs485.flags & SER_RS485_ENABLED) {
atmel_uart_writel(port, ATMEL_US_TTGR,
port->rs485.delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
- } else if (termios->c_cflag & CRTSCTS) {
- /* RS232 with hardware handshake (RTS/CTS) */
- mode |= ATMEL_US_USMODE_HWHS;
- } else {
- /* RS232 without hadware handshake */
+ } else {
mode |= ATMEL_US_USMODE_NORMAL;
}
(at this point, every platform will work with flow control without problem)
- and finally introduce the ATMEL_US_USMODE_HWHS flag for platforms with FIFO:
if (port->rs485.flags & SER_RS485_ENABLED) {
atmel_uart_writel(port, ATMEL_US_TTGR,
port->rs485.delay_rts_after_send);
mode |= ATMEL_US_USMODE_RS485;
} else {
- mode |= ATMEL_US_USMODE_NORMAL;
+ if (termios->c_cflag & CRTSCTS) &&
+ atmel_use_fifo(port) &&
+ !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
+ mode |= ATMEL_US_USMODE_HWHS;
+ } else {
+ mode |= ATMEL_US_USMODE_NORMAL;
+ }
}
>
>> - } else {
>> + if (atmel_use_fifo(port) &&
>> + !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
>> + /*
>> + * with ATMEL_US_USMODE_HWHS set, the controller will
>> + * be able to drive the RTS pin high/low when the RX
>> + * FIFO is above RXFTHRES/below RXFTHRES2.
>> + * It will also disable the transmitter when the CTS
>> + * pin is high.
>> + * This mode is not activated if CTS pin is a GPIO
>> + * because in this case, the transmitter is always
>> + * disabled.
>> + * If the RTS pin is a GPIO, the controller won't be
>> + * able to drive it according to the FIFO thresholds,
>> + * but it will be handled by the driver.
>> + */
>> mode |= ATMEL_US_USMODE_HWHS;
>> + } else {
>> + /*
>> + * For platforms without FIFO, the flow control is
>> + * handled by the driver.
>> + */
>> + mode |= ATMEL_US_USMODE_NORMAL;
>> }
>> } else {
>> /* RS232 without hadware handshake */
>
> (unrelated to this patch) s/hadware/hardware/
>
I plan to to some janitor work on this driver, I'll add it then.
Thanks.
Richard.
^ permalink raw reply
* [PATCH v7 2/4] soc: mediatek: Init MT8173 scpsys driver earlier
From: Matthias Brugger @ 2016-10-26 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1468314071.24705.4.camel@mhfsdcap03>
Hi Yong,
On 07/12/2016 11:01 AM, Yong Wu wrote:
> Hi Matthias,
>
> On Fri, 2016-07-08 at 14:47 +0200, Matthias Brugger wrote:
>>
>> On 06/07/16 07:22, James Liao wrote:
>>> On Sat, 2016-07-02 at 18:35 +0200, Matthias Brugger wrote:
>>>>
>>>> On 05/16/2016 11:28 AM, James Liao wrote:
>>>>> Some power domain comsumers may init before module_init.
>>>>> So the power domain provider (scpsys) need to be initialized
>>>>> earlier too.
>>>>>
>>>>> Take an example for our IOMMU (M4U) and SMI. SMI is a bridge
>>>>> between IOMMU and multimedia HW. SMI is responsible to
>>>>> enable/disable iommu and help transfer data for each multimedia
>>>>> HW. Both of them have to wait until the power and clocks are
>>>>> enabled.
>>>>>
>>>>> So scpsys driver should be initialized before SMI, and SMI should
>>>>> be initialized before IOMMU, and then init IOMMU consumers
>>>>> (display/vdec/venc/camera etc.).
>>>>>
>>>>> IOMMU is subsys_init by default. So we need to init scpsys driver
>>>>> before subsys_init.
>>>>>
>>>>> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
>>>>> Reviewed-by: Kevin Hilman <khilman@baylibre.com>
>>>>> ---
>>>>> drivers/soc/mediatek/mtk-scpsys.c | 19 ++++++++++++++++++-
>>>>> 1 file changed, 18 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
>>>>> index 5870a24..00c0adb 100644
>>>>> --- a/drivers/soc/mediatek/mtk-scpsys.c
>>>>> +++ b/drivers/soc/mediatek/mtk-scpsys.c
>>>>> @@ -617,4 +617,21 @@ static struct platform_driver scpsys_drv = {
>>>>> .of_match_table = of_match_ptr(of_scpsys_match_tbl),
>>>>> },
>>>>> };
>>>>> -builtin_platform_driver(scpsys_drv);
>>>>> +
>>>>> +static int __init scpsys_drv_init(void)
>>>>> +{
>>>>> + return platform_driver_register(&scpsys_drv);
>>>>> +}
>>>>> +
>>>>> +/*
>>>>> + * There are some Mediatek drivers which depend on the power domain driver need
>>>>> + * to probe in earlier initcall levels. So scpsys driver also need to probe
>>>>> + * earlier.
>>>>> + *
>>>>> + * IOMMU(M4U) and SMI drivers for example. SMI is a bridge between IOMMU and
>>>>> + * multimedia HW. IOMMU depends on SMI, and SMI is a power domain consumer,
>>>>> + * so the proper probe sequence should be scpsys -> SMI -> IOMMU driver.
>>>>> + * IOMMU drivers are initialized during subsys_init by default, so we need to
>>>>> + * move SMI and scpsys drivers to subsys_init or earlier init levels.
>>>>> + */
>>>>> +subsys_initcall(scpsys_drv_init);
>>>>>
>>>>
>>>> Can't we achieve this with probe deferring? I'm not really keen on
>>>> coding the order of the different drivers like this.
>>>
>>> Hi Matthias,
>>>
>>> Some drivers such as IOMMU don't support probe deferring. So scpsys need
>>> to init before them by changing init level.
>>>
>>
>> SMI larbs return EPROBE_DEFER if it can't find the PM provider for it's
>> domain, so this part should not be the problem. The larbs get added as
>> components in the probe, when the PM provider is present.
>>
>> The iommu driver uses the larbs as components. As long as not all
>> components are present the iommu does not bind them. So from what I see
>> this should work without any problem.
>>
>> Can you please specify where the iommu dirver has a problem. Maybe we
>> need to fix the driver rather then scpsys.
>
> We got a problem while bootup, the hang backtrace is like below(Sorry, I
> can't find the full backtrace now):
>
> [ 7.832359] Call trace:
> [ 7.834778] [<ffffffc000764424>] mtk_smi_larb_get+0x24/0xa8
> [ 7.840300] [<ffffffc0005a1390>] mtk_drm_crtc_enable+0x6c/0x450
>
> The reason is that "larb->mmu" is NULL while DRM call mtk_smi_larb_get.
>
> DRM call iommu_present to wait for whether IOMMU is ready[1].
> But in the MTK-IOMMU, It will call
> bus_set_iommu->mtk_iommu_add_device->mtk_iommu_attach_device, then it's
> able to transfer "struct mtk_smi_iommu" to SMI whose probe maybe delayed
> by power-domain, then SMI could finish its probe.
>
> So If DRM probe is called after the time of calling bus_set_iommu and
> before the time of SMI probe finish, this problem can be reproduced.
>
> The root cause is that iommu_present cann't indicate that MTK-IOMMU and
> SMI is ready actually. in other words, the DRM cann't detect
> whether the SMI has probed done.
>
> If we move scpsys_init from module_initcall to subsys_initcall, the
> IOMMU and SMI could be probe done during the subsys_initcall period.
> this issue can be avoid.
> And as we grep before, there are also some examples whose power-domain
> is also not module_init[2].
> core_initcall(exynos4_pm_init_power_domain);
> subsys_initcall(imx_pgc_init);
>
> If you think that this patch will hide the problem above, then I have to
> add a new function, like below:
> //==================
> bool mtk_smi_larb_ready(struct device *larbdev)
> {
> struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
>
> return larb && !!larb->mmu;
> }
> //=================
>
> And in the probe of all the MTK-IOMMU consumer, we have to add this:
> //====================
> if (!mtk_smi_larb_ready(&larb_pdev->dev))
> return -EPROBE_DEFER;
> //====================
>
> The sequence is a little complex, If I don't explain clearly, please
> tell me.
> Any other suggestion about this? Thanks.
I'm still trying to find a different way to solve this. Unfortunately
I'm not able to reproduce this on my mt8173-evb...
...but: iommu_present checkes if the bus->iommu_ops is set. If we set
these option in the iommu after all components got initialized, we
should be fine. Or did I miss something?
Would you mind trying the patch below (against v4.9-rc1)?
If you know of any way to reproduce this issue, I would be happy to know.
I'm adding Joerg, the iommu maintainer, maybe he has an idea.
Thanks a lot,
Matthias
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b12c12d..9249011 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -602,10 +602,12 @@ static int mtk_iommu_probe(struct platform_device
*pdev)
if (ret)
return ret;
- if (!iommu_present(&platform_bus_type))
+ ret = component_master_add_with_match(dev, &mtk_iommu_com_ops,
match);
+
+ if (ret && !iommu_present(&platform_bus_type))
bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
- return component_master_add_with_match(dev, &mtk_iommu_com_ops,
match);
+ return ret;
}
static int mtk_iommu_remove(struct platform_device *pdev)
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox