* [PATCH v4 0/4] DMA Engine: switch PL330 driver to non-irq-safe runtime PM
From: Ulf Hansson @ 2017-01-13 14:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <60596eee-12a9-58f3-387e-145a5bc28aaa@samsung.com>
[...]
>>
>> Marek, this is great work! It's been on my TODO list forever, so I
>> really appreciate your work here.
>>
>> I did only a brief review so far, particularly concentrating on the
>> changes for device links and runtime PM. I like it!
>>
>> Perhaps we can get someone like Arnd/Vinod to comment in general idea
>> from a DT and DMA slave channel point of view. I don't know that stuff
>> good enough to give good opinion.
>
>
> Arnd already said that it looks good:
> http://www.spinics.net/lists/dmaengine/msg12186.html
Great! Clearly, I haven't fully catched up since the holidays. :-)
>
>> A couple of things that crosses my mind so far:
>> 1) I have planned to extend pm_runtime_force_suspend|resume() to cover
>> also device links. Seems like that becomes really useful together with
>> these changes.
>
>
> Is is really needed? I thought that this case is already handled by device
> core. It works perfectly fine for Exynos IOMMU and its client devices for
> suspend/resume too, which rely on pm_runtime_force_suspend|resume().
Only parent devices are being considered in
pm_runtime_force_suspend|resume(). Meaning that the runtime PM usage
count will not be updated for a device's link, even if it should.
I guess what happens is that the pl330 controller will be brought up
to full power during system resume, even if it isn't necessary to do
so. If that's the case, it's not the end of the world, we can optimize
it later on.
Note, this is very theoretical and to be sure, I need to run some
tests and think more about it.
>
>> 2) I think there will be some corner cases during system
>> suspend/resume for pl330. Not sure yet though. However, fixing 1) and
>> converting the driver to use pm_runtime_force_suspend|resume() should
>> probably work anyway.
>
>
> Do you have any particular case in mind? Device links ensures that pl330
> will
> suspended after its slave devices and waken before them. Is there anything
> more needed here?
Likely we can consider them as optimizations. See comment above.
>
>> Allow me to help out looking into 1) and 2). If not for pl330, I am
>> pretty sure it will be useful for other DMA controllers that
>> implements device links and runtime PM.
>
>
> I'm open for suggestions.
>
> Best regards
> --
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>
Kind regards
Uffe
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Mark Rutland @ 2017-01-13 14:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d496020c-a097-ffd5-adb7-7edb7c1a214e@arm.com>
Hi,
On Fri, Jan 13, 2017 at 01:30:29PM +0000, Marc Zyngier wrote:
> [+ Suzuki, who wrote the whole cpus_have_const_cap thing]
>
> On 13/01/17 12:36, Christoffer Dall wrote:
> > On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
> >> +static inline bool has_vhe(void)
> >> +{
> >> + if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
> >> + return true;
> >> +
> >> + return false;
> >> +}
> >> +
> >
> > I was experimenting with using has_vhe for some of the optimization code
> > I was writing, and I saw a hyp crash as a result. That made me wonder
> > if this is really safe in Hyp mode?
> >
> > Specifically, there is no guarantee that this will actually be inlined
> > in the caller, right? At least that's what I can gather from trying to
> > understand the semantics of the inline keyword in the GCC manual.
>
> Indeed, there is no strict guarantee that this is enforced. We should
> probably have __always_inline instead. But having checked the generated
> code for __timer_restore_state, the function is definitely inlined
> (gcc 6.2). Happy to queue an extra patch changing that.
> > Further, are we guaranteed that the static branch gets compiled into
> > something that doesn't actually look at cpu_hwcap_keys, which is not
> > mapped in hyp mode?
If I disable CONFIG_JUMP_LABEL (which lives under "General setup", with
teh title "Optimize very unlikely/likely branches"), I see adrp; add;
ldr sequences accessing cpu_hwcap_keys when using cpus_have_const_cap()
in hyp code, even with the patch below.
Do we have the whole kernel image mapped around hyp, so that this would
work by relative offset? Do we have a guarantee that adrp+add is used?
Thanks,
Mark.
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b4989df..4710469 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -105,10 +105,11 @@ static inline bool cpu_have_feature(unsigned int num)
> }
>
> /* System capability check for constant caps */
> -static inline bool cpus_have_const_cap(int num)
> +static __always_inline bool cpus_have_const_cap(int num)
> {
> - if (num >= ARM64_NCAPS)
> - return false;
> + BUILD_BUG_ON(!__builtin_constant_p(num));
> + BUILD_BUG_ON(num >= ARM64_NCAPS);
> +
> return static_branch_unlikely(&cpu_hwcap_keys[num]);
> }
>
> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> index 439f6b5..1257701 100644
> --- a/arch/arm64/include/asm/virt.h
> +++ b/arch/arm64/include/asm/virt.h
> @@ -81,7 +81,7 @@ static inline bool is_kernel_in_hyp_mode(void)
> return read_sysreg(CurrentEL) == CurrentEL_EL2;
> }
>
> -static inline bool has_vhe(void)
> +static __always_inline bool has_vhe(void)
> {
> if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
> return true;
>
>
> But that's probably another patch or two. Thoughts?
>
> M.
> --
> Jazz is not dead. It just smells funny...
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply
* [PATCH RFC v2 0/4] SolidRun Hummingboard 2 support
From: Russell King - ARM Linux @ 2017-01-13 14:44 UTC (permalink / raw)
To: linux-arm-kernel
These patches add support for SolidRun's Hummingboard 2 to mainline.
The first is the official SolidRun DTS file supplied by Jon, the
remainder are cleanups to it for mainline.
These can be found in my HB2 branch.
Version 2 updated by Jon from comments received on previous posting.
The series can be found at:
git://git.armlinux.org.uk/~rmk/linux-arm.git hb2
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/imx6dl-hummingboard2.dts | 52 +++
arch/arm/boot/dts/imx6q-hummingboard2.dts | 60 +++
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 555 +++++++++++++++++++++++++++
4 files changed, 669 insertions(+)
create mode 100644 arch/arm/boot/dts/imx6dl-hummingboard2.dts
create mode 100644 arch/arm/boot/dts/imx6q-hummingboard2.dts
create mode 100644 arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH RFC v2 1/4] ARM: dts: imx6qdl: add HummingBoard2 boards
From: Russell King @ 2017-01-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144449.GQ14217@n2100.armlinux.org.uk>
From: Jon Nettleton <jon@solid-run.com>
This adds support for the Hummingboard Gate and Edge devices from
SolidRun.
Signed-off-by: Jon Nettleton <jon@solid-run.com>
Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/imx6dl-hummingboard2.dts | 52 +++
arch/arm/boot/dts/imx6q-hummingboard2.dts | 60 +++
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 543 +++++++++++++++++++++++++++
4 files changed, 657 insertions(+)
create mode 100644 arch/arm/boot/dts/imx6dl-hummingboard2.dts
create mode 100644 arch/arm/boot/dts/imx6q-hummingboard2.dts
create mode 100644 arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7327250f0bb6..09227cc15199 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -348,6 +348,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-gw552x.dtb \
imx6dl-gw553x.dtb \
imx6dl-hummingboard.dtb \
+ imx6dl-hummingboard2.dtb \
imx6dl-icore.dtb \
imx6dl-nit6xlite.dtb \
imx6dl-nitrogen6x.dtb \
@@ -390,6 +391,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6q-gw553x.dtb \
imx6q-h100.dtb \
imx6q-hummingboard.dtb \
+ imx6q-hummingboard2.dtb \
imx6q-icore.dtb \
imx6q-icore-rqs.dtb \
imx6q-marsboard.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-hummingboard2.dts b/arch/arm/boot/dts/imx6dl-hummingboard2.dts
new file mode 100644
index 000000000000..990b5050de5b
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-hummingboard2.dts
@@ -0,0 +1,52 @@
+/*
+ * Device Tree file for SolidRun HummingBoard2
+ * Copyright (C) 2015 Rabeeh Khoury <rabeeh@solid-run.com>
+ * Based on work by Russell King
+ *
+ * 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.
+ *
+ * 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 , 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 "imx6dl.dtsi"
+#include "imx6qdl-hummingboard2.dtsi"
+
+/ {
+ model = "SolidRun HummingBoard2 Solo/DualLite";
+ compatible = "solidrun,hummingboard2/dl", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6q-hummingboard2.dts b/arch/arm/boot/dts/imx6q-hummingboard2.dts
new file mode 100644
index 000000000000..f5eec9163bb8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-hummingboard2.dts
@@ -0,0 +1,60 @@
+/*
+ * Device Tree file for SolidRun HummingBoard2
+ * Copyright (C) 2015 Rabeeh Khoury <rabeeh@solid-run.com>
+ * Based on work by Russell King
+ *
+ * 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.
+ *
+ * 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 , 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 "imx6q.dtsi"
+#include "imx6qdl-hummingboard2.dtsi"
+
+/ {
+ model = "SolidRun HummingBoard2 Dual/Quad";
+ compatible = "solidrun,hummingboard2/q", "fsl,imx6q";
+};
+
+&sata {
+ status = "okay";
+ fsl,transmit-level-mV = <1104>;
+ fsl,transmit-boost-mdB = <0>;
+ fsl,transmit-atten-16ths = <9>;
+ fsl,no-spread-spectrum;
+};
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
new file mode 100644
index 000000000000..11b63f6f2b89
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -0,0 +1,543 @@
+/*
+ * Device Tree file for SolidRun HummingBoard2
+ * Copyright (C) 2015 Rabeeh Khoury <rabeeh@solid-run.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.
+ *
+ * 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 "imx6qdl-microsom.dtsi"
+#include "imx6qdl-microsom-ar8035.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio7 9 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_gpio7_9>;
+ linux,rc-map-name = "rc-rc6-mce";
+ };
+
+ usdhc2_pwrseq: usdhc2-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_usbh1_vbus: regulator-usb-h1-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 0 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_usbh1_vbus>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbotg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 22 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_usbotg_vbus>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ reg_usbh2_vbus: regulator-usb-h2-vbus {
+ compatible = "regulator-gpio";
+ enable-active-high;
+ enable-gpio = <&gpio2 13 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_usbh2_vbus>;
+ regulator-name = "usb_h2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ reg_usbh3_vbus: regulator-usb-h3-vbus {
+ compatible = "regulator-gpio";
+ enable-active-high;
+ enable-gpio = <&gpio7 10 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_usbh3_vbus>;
+ regulator-name = "usb_h3_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ sound-sgtl5000 {
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ compatible = "fsl,imx-audio-sgtl5000";
+ model = "On-board Codec";
+ mux-ext-port = <5>;
+ mux-int-port = <1>;
+ ssi-controller = <&ssi1>;
+ };
+};
+
+&audmux {
+ status = "okay";
+};
+
+&ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_ecspi2>;
+ cs-gpios = <&gpio2 26 0>;
+ status = "okay";
+};
+
+&hdmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_hdmi>;
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_i2c1>;
+ status = "okay";
+
+ pcf8523: rtc at 68 {
+ compatible = "nxp,pcf8523";
+ reg = <0x68>;
+ nxp,12p5_pf;
+ };
+
+ sgtl5000: codec at 0a {
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+ compatible = "fsl,sgtl5000";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_sgtl5000>;
+ reg = <0x0a>;
+ VDDA-supply = <®_3p3v>;
+ VDDIO-supply = <®_3p3v>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_i2c3>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ hummingboard2 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ /*
+ * 36 pin headers GPIO description. The pins
+ * numbering as following -
+ *
+ * 3.2v 5v 74 75
+ * 73 72 71 70
+ * 69 68 67 66
+ *
+ * 77 78 79 76
+ * 65 64 61 60
+ * 53 52 51 50
+ * 49 48 166 132
+ * 95 94 90 91
+ * GND 54 24 204
+ *
+ * The GPIO numbers can be extracted using
+ * signal name from below.
+ * Example -
+ * MX6QDL_PAD_EIM_DA10__GPIO3_IO10 is
+ * GPIO(3,10) which is (3-1)*32+10 = gpio 74
+ *
+ * i.e. The mapping of GPIO(X,Y) to Linux gpio
+ * number is : gpio number = (X-1) * 32 + Y
+ */
+ /* DI1_PIN15 */
+ MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x400130b1
+ /* DI1_PIN02 */
+ MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x400130b1
+ /* DISP1_DATA00 */
+ MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x400130b1
+ /* DISP1_DATA01 */
+ MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x400130b1
+ /* DISP1_DATA02 */
+ MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x400130b1
+ /* DISP1_DATA03 */
+ MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x400130b1
+ /* DISP1_DATA04 */
+ MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x400130b1
+ /* DISP1_DATA05 */
+ MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x400130b1
+ /* DISP1_DATA06 */
+ MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x400130b1
+ /* DISP1_DATA07 */
+ MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x400130b1
+ /* DI1_D0_CS */
+ MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x400130b1
+ /* DI1_D1_CS */
+ MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x400130b1
+ /* DI1_PIN01 */
+ MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x400130b1
+ /* DI1_PIN03 */
+ MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x400130b1
+ /* DISP1_DATA08 */
+ MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x400130b1
+ /* DISP1_DATA09 */
+ MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x400130b1
+ /* DISP1_DATA10 */
+ MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x400130b1
+ /* DISP1_DATA11 */
+ MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x400130b1
+ /* DISP1_DATA12 */
+ MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x400130b1
+ /* DISP1_DATA13 */
+ MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x400130b1
+ /* DISP1_DATA14 */
+ MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x400130b1
+ /* DISP1_DATA15 */
+ MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x400130b1
+ /* DISP1_DATA16 */
+ MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x400130b1
+ /* DISP1_DATA17 */
+ MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x400130b1
+ /* DISP1_DATA18 */
+ MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x400130b1
+ /* DISP1_DATA19 */
+ MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x400130b1
+ /* DISP1_DATA20 */
+ MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x400130b1
+ /* DISP1_DATA21 */
+ MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x400130b1
+ /* DISP1_DATA22 */
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x400130b1
+ /* DISP1_DATA23 */
+ MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x400130b1
+ /* DI1_DISP_CLK */
+ MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x400130b1
+ /* SPDIF_IN */
+ MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24 0x400130b1
+ /* SPDIF_OUT */
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x400130b1
+
+ /* MikroBUS GPIO pin number 10 */
+ MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x400130b1
+ >;
+ };
+
+ pinctrl_hummingboard2_ecspi2: hummingboard2-ecspi2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x100b1
+ MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x100b1
+ MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x100b1
+ MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x000b1 /* CS */
+ >;
+ };
+
+ pinctrl_hummingboard2_gpio7_9: hummingboard2-gpio7_9 {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_CMD__GPIO7_IO09 0x80000000
+ >;
+ };
+
+ pinctrl_hummingboard2_hdmi: hummingboard2-hdmi {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
+ >;
+ };
+
+ pinctrl_hummingboard2_i2c1: hummingboard2-i2c1 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_hummingboard2_i2c2: hummingboard2-i2c2 {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_hummingboard2_i2c3: hummingboard2-i2c3 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_hummingboard2_mipi: hummingboard2_mipi {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x4001b8b1
+ MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x4001b8b1
+ MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0
+ >;
+ };
+
+ pinctrl_hummingboard2_pcie_reset: hummingboard2-pcie-reset {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x1b0b1
+ >;
+ };
+
+ pinctrl_hummingboard2_pwm1: pwm1grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_hummingboard2_sgtl5000: hummingboard2-sgtl5000 {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
+ MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0
+ MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0
+ >;
+ };
+
+ pinctrl_hummingboard2_usbh1_vbus: hummingboard2-usbh1-vbus {
+ fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard2_usbh2_vbus: hummingboard2-usbh2-vbus {
+ fsl,pins = <MX6QDL_PAD_SD4_DAT5__GPIO2_IO13 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard2_usbh3_vbus: hummingboard2-usbh3-vbus {
+ fsl,pins = <MX6QDL_PAD_SD4_CLK__GPIO7_IO10 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard2_usbotg_id: hummingboard2-usbotg-id {
+ /*
+ * Similar to pinctrl_usbotg_2, but we want it
+ * pulled down for a fixed host connection.
+ */
+ fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+ };
+
+ pinctrl_hummingboard2_usbotg_vbus: hummingboard2-usbotg-vbus {
+ fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
+ };
+
+ pinctrl_hummingboard2_usdhc2_aux: hummingboard2-usdhc2-aux {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x13071
+ MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
+ MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0
+ >;
+ };
+
+ pinctrl_hummingboard2_usdhc2: hummingboard2-usdhc2 {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
+ >;
+ };
+
+ pinctrl_hummingboard2_usdhc2_100mhz: hummingboard2-usdhc2-100mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130b9
+ >;
+ };
+
+ pinctrl_hummingboard2_usdhc2_200mhz: hummingboard2-usdhc2-200mhz {
+ fsl,pins = <
+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130f9
+ >;
+ };
+
+ pinctrl_hummingboard2_usdhc3: hummingboard2-usdhc3 {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ MX6QDL_PAD_SD3_RST__SD3_RESET 0x17059
+ >;
+ };
+
+ pinctrl_hummingboard2_uart3: hummingboard2-uart3 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D25__UART3_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D24__UART3_RX_DATA 0x40013000
+ >;
+ };
+ };
+};
+
+&ldb {
+ status = "disabled";
+
+ lvds-channel at 0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <18>;
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_pcie_reset>;
+ reset-gpio = <&gpio2 11 0>;
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_pwm1>;
+ status = "okay";
+};
+
+&pwm3 {
+ status = "disabled";
+};
+
+&pwm4 {
+ status = "disabled";
+};
+
+&ssi1 {
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ vbus-supply = <®_usbh1_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ disable-over-current;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_usbotg_id>;
+ vbus-supply = <®_usbotg_vbus>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <
+ &pinctrl_hummingboard2_usdhc2_aux
+ &pinctrl_hummingboard2_usdhc2
+ >;
+ pinctrl-1 = <
+ &pinctrl_hummingboard2_usdhc2_aux
+ &pinctrl_hummingboard2_usdhc2_100mhz
+ >;
+ pinctrl-2 = <
+ &pinctrl_hummingboard2_usdhc2_aux
+ &pinctrl_hummingboard2_usdhc2_200mhz
+ >;
+ mmc-pwrseq = <&usdhc2_pwrseq>;
+ cd-gpios = <&gpio1 4 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_hummingboard2_usdhc3
+ >;
+ vmmc-supply = <®_3p3v>;
+ vqmmc-supply = <®_3p3v>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_uart3>;
+ status = "okay";
+};
--
2.7.4
^ permalink raw reply related
* [PATCH RFC v2 2/4] ARM: dts: imx6*-hummingboard2: fix SD card detect
From: Russell King @ 2017-01-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144449.GQ14217@n2100.armlinux.org.uk>
Fix the SD card detect signal, which was missing the polarity
specification, and the pull-up necessary for proper signalling.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
index 11b63f6f2b89..734487edf200 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -393,7 +393,7 @@
pinctrl_hummingboard2_usdhc2_aux: hummingboard2-usdhc2-aux {
fsl,pins = <
- MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x13071
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0
>;
@@ -520,7 +520,7 @@
&pinctrl_hummingboard2_usdhc2_200mhz
>;
mmc-pwrseq = <&usdhc2_pwrseq>;
- cd-gpios = <&gpio1 4 0>;
+ cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
--
2.7.4
^ permalink raw reply related
* [PATCH RFC v2 3/4] ARM: dts: imx6*-hummingboard2: use proper gpio flags definitions
From: Russell King @ 2017-01-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144449.GQ14217@n2100.armlinux.org.uk>
Use proper gpio flag definitions for GPIOs rather than using opaque
uninformative numbers.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
index 734487edf200..88aaed26dd77 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -50,7 +50,7 @@
ir_recv: ir-receiver {
compatible = "gpio-ir-receiver";
- gpios = <&gpio7 9 1>;
+ gpios = <&gpio7 9 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard2_gpio7_9>;
linux,rc-map-name = "rc-rc6-mce";
@@ -80,7 +80,7 @@
reg_usbh1_vbus: regulator-usb-h1-vbus {
compatible = "regulator-fixed";
enable-active-high;
- gpio = <&gpio1 0 0>;
+ gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard2_usbh1_vbus>;
regulator-name = "usb_h1_vbus";
@@ -91,7 +91,7 @@
reg_usbotg_vbus: regulator-usb-otg-vbus {
compatible = "regulator-fixed";
enable-active-high;
- gpio = <&gpio3 22 0>;
+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard2_usbotg_vbus>;
regulator-name = "usb_otg_vbus";
@@ -102,7 +102,7 @@
reg_usbh2_vbus: regulator-usb-h2-vbus {
compatible = "regulator-gpio";
enable-active-high;
- enable-gpio = <&gpio2 13 0>;
+ enable-gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard2_usbh2_vbus>;
regulator-name = "usb_h2_vbus";
@@ -114,7 +114,7 @@
reg_usbh3_vbus: regulator-usb-h3-vbus {
compatible = "regulator-gpio";
enable-active-high;
- enable-gpio = <&gpio7 10 0>;
+ enable-gpio = <&gpio7 10 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hummingboard2_usbh3_vbus>;
regulator-name = "usb_h3_vbus";
--
2.7.4
^ permalink raw reply related
* [PATCH RFC v2 4/4] ARM: dts: imx6*-hummingboard2: convert to more conventional vmmc-supply
From: Russell King @ 2017-01-13 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144449.GQ14217@n2100.armlinux.org.uk>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
index 88aaed26dd77..f19d30b34ac4 100644
--- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi
@@ -56,11 +56,6 @@
linux,rc-map-name = "rc-rc6-mce";
};
- usdhc2_pwrseq: usdhc2-pwrseq {
- compatible = "mmc-pwrseq-simple";
- reset-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;
- };
-
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
@@ -123,6 +118,18 @@
regulator-boot-on;
};
+ reg_usdhc2_vmmc: reg-usdhc2-vmmc {
+ compatible = "regulator-fixed";
+ gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard2_vmmc>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "usdhc2_vmmc";
+ startup-delay-us = <1000>;
+ };
+
sound-sgtl5000 {
audio-codec = <&sgtl5000>;
audio-routing =
@@ -393,7 +400,6 @@
pinctrl_hummingboard2_usdhc2_aux: hummingboard2-usdhc2-aux {
fsl,pins = <
- MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0
>;
@@ -432,6 +438,12 @@
>;
};
+ pinctrl_hummingboard2_vmmc: hummingboard2-vmmc {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
+ >;
+ };
+
pinctrl_hummingboard2_usdhc3: hummingboard2-usdhc3 {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
@@ -519,7 +531,7 @@
&pinctrl_hummingboard2_usdhc2_aux
&pinctrl_hummingboard2_usdhc2_200mhz
>;
- mmc-pwrseq = <&usdhc2_pwrseq>;
+ vmmc-supply = <®_usdhc2_vmmc>;
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Mark Rutland @ 2017-01-13 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113123612.GA31994@cbox>
On Fri, Jan 13, 2017 at 01:36:12PM +0100, Christoffer Dall wrote:
> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
> Further, are we guaranteed that the static branch gets compiled into
> something that doesn't actually look at cpu_hwcap_keys, which is not
> mapped in hyp mode?
The fact that this might happen silently seems to be a larger problem.
Can we do something like the EFI stub, and ensure that (unintentional)
references to symbols outside of the hyp-stub will fail to link? That's
ensrue by some symbol mangling in drivers/firmware/efi/libstub/Makefile.
I think this may have come up before; I can't recall if there was some
reason that was problematic.
Thanks,
Mark.
^ permalink raw reply
* [PATCH] i2c: i2c-cadence: Don't register the adapter until it's ready
From: Mike Looijmans @ 2017-01-13 14:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113083727.GB1446@katana>
?On 13-01-17 09:37, Wolfram Sang wrote:
>
>> I would argue that the "info" message means "the I2C adapter is ready for
>> transaction now, and we'll start initializing devices on the bus". That is
>> the case before it calls i2c_add_adapter().
>
> I know what you mean, but i2c_add_adapter does more, and it can fail
> because the adapter is *not* ready to transfer. Seeing the success
> message before is also confusing.
>
>> When i2c_add_adapter() runs, it will start probing devices on the bus. This
>> yields very confusing output, as it will output things in a reversed order:
>>
>> - device X on I2C bus
>> - device Y on I2C bus
>> - cdns-i2c ff030000.i2c: 100 kHz mmio ff030000 irq 197
>
> I agree. That being said, somewhen I started working on moving such
> messages into the core to save string space and have consistent output.
> Then, we can print at the proper time.
>
> So, until then, we should be consistent with the other driver, I'd say.
Makes sense.
I'll create a v2 patch to just move the i2c_add_adapter to after writing the
configuration registers, and leave the dmesg output as is.
Thanks for reviewing,
Mike.
Kind regards,
Mike Looijmans
System Expert
TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans at topicproducts.com
Website: www.topicproducts.com
Please consider the environment before printing this e-mail
^ permalink raw reply
* [PATCH v4 5/5] ARM: dts: mt2701: add iommu/smi dtsi node for mt2701
From: Matthias Brugger @ 2017-01-13 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <577A1794.5040509@gmail.com>
On 04/07/16 10:00, Matthias Brugger wrote:
>
>
> On 04/07/16 03:32, Honghui Zhang wrote:
>> On Sun, 2016-07-03 at 21:12 +0200, Matthias Brugger wrote:
>>>
>>> On 07/03/2016 08:24 AM, Matthias Brugger wrote:
>>>>
>>>>
>>>> On 06/08/2016 11:51 AM, honghui.zhang at mediatek.com wrote:
>>>>> From: Honghui Zhang <honghui.zhang@mediatek.com>
>>>>>
>>>>> Add the dtsi node of iommu and smi for mt2701.
>>>>>
>>>>> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
>>>>> ---
>>>>> arch/arm/boot/dts/mt2701.dtsi | 51
>>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 51 insertions(+)
>>>>>
>>>>
>>>> Applied,
>>>
>>> Please resend the patch including the infracfg and mmsys node.
>>>
>>
>> Hi, Matthias,
>>
>> Please hold this one.
>> This one is based on CCF "arm: dts: mt2701: Add clock controller device
>> nodes"[1] and power domain patch "Mediatek MT2701 SCPSYS power domain
>> support v7"[2],
>> But these two patchset are still being reviewed now.
>>
>> Do you think it's better that I send this one later after ccf and power
>> domain patch got merged? I will send this patch later if it's OK with
>> you.
>>
>
> Sounds good.
Applied now to v4.10-next/dts32
Thanks.
>
> Thanks a lot,
> Matthias
>
>> Thanks.
>> [1] https://patchwork.kernel.org/patch/9109081
>> [2]
>> http://lists.infradead.org/pipermail/linux-mediatek/2016-May/005429.html
>>
>>> Regards,
>>> Matthias
>>>
>>>>
>>>> Thanks.
>>>>
>>>>> diff --git a/arch/arm/boot/dts/mt2701.dtsi
>>>>> b/arch/arm/boot/dts/mt2701.dtsi
>>>>> index 42d5a37..363de0d 100644
>>>>> --- a/arch/arm/boot/dts/mt2701.dtsi
>>>>> +++ b/arch/arm/boot/dts/mt2701.dtsi
>>>>> @@ -16,6 +16,7 @@
>>>>> #include <dt-bindings/power/mt2701-power.h>
>>>>> #include <dt-bindings/interrupt-controller/irq.h>
>>>>> #include <dt-bindings/interrupt-controller/arm-gic.h>
>>>>> +#include <dt-bindings/memory/mt2701-larb-port.h>
>>>>> #include "skeleton64.dtsi"
>>>>> #include "mt2701-pinfunc.h"
>>>>>
>>>>> @@ -160,6 +161,16 @@
>>>>> clock-names = "system-clk", "rtc-clk";
>>>>> };
>>>>>
>>>>> + smi_common: smi at 1000c000 {
>>>>> + compatible = "mediatek,mt2701-smi-common";
>>>>> + reg = <0 0x1000c000 0 0x1000>;
>>>>> + clocks = <&infracfg CLK_INFRA_SMI>,
>>>>> + <&mmsys CLK_MM_SMI_COMMON>,
>>>>> + <&infracfg CLK_INFRA_SMI>;
>>>>> + clock-names = "apb", "smi", "async";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
>>>>> + };
>>>>> +
>>>>> sysirq: interrupt-controller at 10200100 {
>>>>> compatible = "mediatek,mt2701-sysirq",
>>>>> "mediatek,mt6577-sysirq";
>>>>> @@ -169,6 +180,16 @@
>>>>> reg = <0 0x10200100 0 0x1c>;
>>>>> };
>>>>>
>>>>> + iommu: mmsys_iommu at 10205000 {
>>>>> + compatible = "mediatek,mt2701-m4u";
>>>>> + reg = <0 0x10205000 0 0x1000>;
>>>>> + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
>>>>> + clocks = <&infracfg CLK_INFRA_M4U>;
>>>>> + clock-names = "bclk";
>>>>> + mediatek,larbs = <&larb0 &larb1 &larb2>;
>>>>> + #iommu-cells = <1>;
>>>>> + };
>>>>> +
>>>>> apmixedsys: syscon at 10209000 {
>>>>> compatible = "mediatek,mt2701-apmixedsys", "syscon";
>>>>> reg = <0 0x10209000 0 0x1000>;
>>>>> @@ -234,6 +255,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb0: larb at 14010000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x14010000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&mmsys CLK_MM_SMI_LARB0>,
>>>>> + <&mmsys CLK_MM_SMI_LARB0>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
>>>>> + };
>>>>> +
>>>>> imgsys: syscon at 15000000 {
>>>>> compatible = "mediatek,mt2701-imgsys", "syscon";
>>>>> reg = <0 0x15000000 0 0x1000>;
>>>>> @@ -241,6 +272,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb2: larb at 15001000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x15001000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&imgsys CLK_IMG_SMI_COMM>,
>>>>> + <&imgsys CLK_IMG_SMI_COMM>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
>>>>> + };
>>>>> +
>>>>> vdecsys: syscon at 16000000 {
>>>>> compatible = "mediatek,mt2701-vdecsys", "syscon";
>>>>> reg = <0 0x16000000 0 0x1000>;
>>>>> @@ -248,6 +289,16 @@
>>>>> status = "disabled";
>>>>> };
>>>>>
>>>>> + larb1: larb at 16010000 {
>>>>> + compatible = "mediatek,mt2701-smi-larb";
>>>>> + reg = <0 0x16010000 0 0x1000>;
>>>>> + mediatek,smi = <&smi_common>;
>>>>> + clocks = <&vdecsys CLK_VDEC_CKGEN>,
>>>>> + <&vdecsys CLK_VDEC_LARB>;
>>>>> + clock-names = "apb", "smi";
>>>>> + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
>>>>> + };
>>>>> +
>>>>> hifsys: syscon at 1a000000 {
>>>>> compatible = "mediatek,mt2701-hifsys", "syscon";
>>>>> reg = <0 0x1a000000 0 0x1000>;
>>>>>
>>
>>
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Mark Rutland @ 2017-01-13 14:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144204.GB2472@leverpostej>
On Fri, Jan 13, 2017 at 02:42:04PM +0000, Mark Rutland wrote:
> On Fri, Jan 13, 2017 at 01:30:29PM +0000, Marc Zyngier wrote:
> > On 13/01/17 12:36, Christoffer Dall wrote:
> > > Further, are we guaranteed that the static branch gets compiled into
> > > something that doesn't actually look at cpu_hwcap_keys, which is not
> > > mapped in hyp mode?
>
> If I disable CONFIG_JUMP_LABEL (which lives under "General setup", with
> teh title "Optimize very unlikely/likely branches"), I see adrp; add;
> ldr sequences accessing cpu_hwcap_keys when using cpus_have_const_cap()
> in hyp code, even with the patch below.
Looking again, that's the same sequence Marc mentioned, as it falls in
the BSS. I just happened to be looking at the unlinked .o file rather
than the vmlinux.
Sorry for the noise.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Suzuki K Poulose @ 2017-01-13 14:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d496020c-a097-ffd5-adb7-7edb7c1a214e@arm.com>
On 13/01/17 13:30, Marc Zyngier wrote:
> [+ Suzuki, who wrote the whole cpus_have_const_cap thing]
>
> On 13/01/17 12:36, Christoffer Dall wrote:
>> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
>>> From: Jintack Lim <jintack@cs.columbia.edu>
>>>
...
>>> /*
>>> * __boot_cpu_mode records what mode CPUs were booted in.
>>> @@ -80,6 +81,14 @@ static inline bool is_kernel_in_hyp_mode(void)
>>> return read_sysreg(CurrentEL) == CurrentEL_EL2;
>>> }
>>>
>>> +static inline bool has_vhe(void)
>>> +{
>>> + if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
>>> + return true;
>>> +
>>> + return false;
>>> +}
>>> +
>>
>> I was experimenting with using has_vhe for some of the optimization code
>> I was writing, and I saw a hyp crash as a result. That made me wonder
>> if this is really safe in Hyp mode?
>>
>> Specifically, there is no guarantee that this will actually be inlined
>> in the caller, right? At least that's what I can gather from trying to
>> understand the semantics of the inline keyword in the GCC manual.
>
> Indeed, there is no strict guarantee that this is enforced. We should
> probably have __always_inline instead. But having checked the generated
> code for __timer_restore_state, the function is definitely inlined
> (gcc 6.2). Happy to queue an extra patch changing that.
>
>> Further, are we guaranteed that the static branch gets compiled into
>> something that doesn't actually look at cpu_hwcap_keys, which is not
>> mapped in hyp mode?
>
> Here's the disassembly:
>
> ffff000008ad01d0 <__timer_restore_state>:
> ffff000008ad01d0: f9400001 ldr x1, [x0]
> ffff000008ad01d4: 9240bc21 and x1, x1, #0xffffffffffff
> ffff000008ad01d8: d503201f nop
> ffff000008ad01dc: d503201f nop
> ffff000008ad01e0: d53ce102 mrs x2, cnthctl_el2
> ffff000008ad01e4: 927ef842 and x2, x2, #0xfffffffffffffffd
> ffff000008ad01e8: b2400042 orr x2, x2, #0x1
> ffff000008ad01ec: d51ce102 msr cnthctl_el2, x2
> ffff000008ad01f0: d2834002 mov x2, #0x1a00 // #6656
> ffff000008ad01f4: 8b020000 add x0, x0, x2
> ffff000008ad01f8: 91038002 add x2, x0, #0xe0
> ffff000008ad01fc: 39425443 ldrb w3, [x2,#149]
> ffff000008ad0200: 34000103 cbz w3, ffff000008ad0220 <__timer_restore_state+0x50>
> ffff000008ad0204: f945a821 ldr x1, [x1,#2896]
> ffff000008ad0208: d51ce061 msr cntvoff_el2, x1
> ffff000008ad020c: f9400441 ldr x1, [x2,#8]
> ffff000008ad0210: d51be341 msr cntv_cval_el0, x1
> ffff000008ad0214: d5033fdf isb
> ffff000008ad0218: b940e000 ldr w0, [x0,#224]
> ffff000008ad021c: d51be320 msr cntv_ctl_el0, x0
> ffff000008ad0220: d65f03c0 ret
>
> The static branch resolves as such when VHE is enabled (taken from
> a running model):
>
> ffff000008ad01d0 <__timer_restore_state>:
> ffff000008ad01d0: f9400001 ldr x1, [x0]
> ffff000008ad01d4: 9240bc21 nop
> ffff000008ad01d8: d503201f nop
> ffff000008ad01dc: d503201f b ffff000008ad01f0
> ffff000008ad01e0: d53ce102 mrs x2, cnthctl_el2
> [...]
>
> That's using a toolchain that supports the "asm goto" feature that is used
> to implement static branches (and that's guaranteed not to generate any
> memory access other than the code patching itself).
>
> Now, with a toolchain that doesn't support this, such as gcc 4.8:
>
> ffff000008aa5168 <__timer_restore_state>:
> ffff000008aa5168: f9400001 ldr x1, [x0]
> ffff000008aa516c: 9240bc21 and x1, x1, #0xffffffffffff
> ffff000008aa5170: d503201f nop
> ffff000008aa5174: f00038a2 adrp x2, ffff0000091bc000 <reset_devices>
> ffff000008aa5178: 9113e042 add x2, x2, #0x4f8
> ffff000008aa517c: b9402c42 ldr w2, [x2,#44]
> ffff000008aa5180: 6b1f005f cmp w2, wzr
> ffff000008aa5184: 540000ac b.gt ffff000008aa5198 <__timer_restore_state+0x30>
> ffff000008aa5188: d53ce102 mrs x2, cnthctl_el2
> ffff000008aa518c: 927ef842 and x2, x2, #0xfffffffffffffffd
> ffff000008aa5190: b2400042 orr x2, x2, #0x1
> ffff000008aa5194: d51ce102 msr cnthctl_el2, x2
> ffff000008aa5198: 91400402 add x2, x0, #0x1, lsl #12
> ffff000008aa519c: 396dd443 ldrb w3, [x2,#2933]
> ffff000008aa51a0: 34000103 cbz w3, ffff000008aa51c0 <__timer_restore_state+0x58>
> ffff000008aa51a4: f945a821 ldr x1, [x1,#2896]
> ffff000008aa51a8: d51ce061 msr cntvoff_el2, x1
> ffff000008aa51ac: f9457441 ldr x1, [x2,#2792]
> ffff000008aa51b0: d51be341 msr cntv_cval_el0, x1
> ffff000008aa51b4: d5033fdf isb
> ffff000008aa51b8: b95ae000 ldr w0, [x0,#6880]
> ffff000008aa51bc: d51be320 msr cntv_ctl_el0, x0
> ffff000008aa51c0: d65f03c0 ret
>
> This is now controlled by some date located at FFFF0000091BC524:
>
> maz at approximate:~/Work/arm-platforms$ aarch64-linux-gnu-objdump -h vmlinux
>
> vmlinux: file format elf64-littleaarch64
>
> Sections:
> Idx Name Size VMA LMA File off Algn
> [...]
> 23 .bss 000da348 ffff0000091b8000 ffff0000091b8000 01147a00 2**12
> ALLOC
>
> That's the BSS, which we do map in HYP (fairly recent).
>
> But maybe we should have have some stronger guarantees that we'll
> always get things inlined, and that the "const" side is enforced:
Agreed.
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index b4989df..4710469 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -105,10 +105,11 @@ static inline bool cpu_have_feature(unsigned int num)
> }
>
> /* System capability check for constant caps */
> -static inline bool cpus_have_const_cap(int num)
> +static __always_inline bool cpus_have_const_cap(int num)
I think we should have the above change and make it inline always.
> {
> - if (num >= ARM64_NCAPS)
> - return false;
> + BUILD_BUG_ON(!__builtin_constant_p(num));
This is not needed, as the compilation would fail if num is not a constant with
static key code.
> + BUILD_BUG_ON(num >= ARM64_NCAPS);
> +
Also, I think it would be good to return false for caps > the ARM64_NCAPS, in sync
with the non-const version.
> return static_branch_unlikely(&cpu_hwcap_keys[num]);
> }
>
> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> index 439f6b5..1257701 100644
> --- a/arch/arm64/include/asm/virt.h
> +++ b/arch/arm64/include/asm/virt.h
> @@ -81,7 +81,7 @@ static inline bool is_kernel_in_hyp_mode(void)
> return read_sysreg(CurrentEL) == CurrentEL_EL2;
> }
>
> -static inline bool has_vhe(void)
> +static __always_inline bool has_vhe(void)
> {
> if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
> return true;
>
>
> But that's probably another patch or two. Thoughts?
With the above changes, please feel free to add :
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply
* [PATCH 2/3] KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
From: Marc Zyngier @ 2017-01-13 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113144622.GC2472@leverpostej>
On 13/01/17 14:46, Mark Rutland wrote:
> On Fri, Jan 13, 2017 at 01:36:12PM +0100, Christoffer Dall wrote:
>> On Fri, Jan 13, 2017 at 11:31:32AM +0000, Marc Zyngier wrote:
>
>> Further, are we guaranteed that the static branch gets compiled into
>> something that doesn't actually look at cpu_hwcap_keys, which is not
>> mapped in hyp mode?
>
> The fact that this might happen silently seems to be a larger problem.
>
> Can we do something like the EFI stub, and ensure that (unintentional)
> references to symbols outside of the hyp-stub will fail to link? That's
> ensrue by some symbol mangling in drivers/firmware/efi/libstub/Makefile.
>
> I think this may have come up before; I can't recall if there was some
> reason that was problematic.
>From what I remember, this was a gigantic mess... We could revisit it
though (after all, it's been a whole year since we did turn the whole
thing upside down -- time for a rewrite!).
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v6 3/3] arm: dts: mt2701: Add node for Mediatek JPEG Decoder
From: Matthias Brugger @ 2017-01-13 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484011718.10361.7.camel@mtksdaap41>
Hi James,
On 10/01/17 02:28, Eddie Huang wrote:
> Hi Matthias,
>
> On Mon, 2017-01-09 at 19:45 +0100, Matthias Brugger wrote:
>>
>> On 09/01/17 12:29, Hans Verkuil wrote:
>>> Hi Rick,
>>>
>>> On 01/06/2017 03:34 AM, Rick Chang wrote:
>>>> Hi Hans,
>>>>
>>>> The dependence on [1] has been merged in 4.10, but [2] has not.Do you have
>>>> any idea about this patch series? Should we wait for [2] or we could merge
>>>> the source code and dt-binding first?
>>>
>>> Looking at [2] I noticed that the last comment was July 4th. What is the reason
>>> it hasn't been merged yet?
>>>
>>> If I know [2] will be merged for 4.11, then I am fine with merging this media
>>> patch series. The dependency of this patch on [2] is something Mauro can handle.
>>>
>>> If [2] is not merged for 4.11, then I think it is better to wait until it is
>>> merged.
>>>
>>
>> I can't take [2] because there is no scpsys in the dts present. It seems
>> that it got never posted.
>>
>> Rick can you please follow-up with James and provide a patch which adds
>> a scpsys node to the mt2701.dtsi?
>>
>
> James sent three MT2701 dts patches [1] two weeks ago, these three
> patches include scpsys node. Please take a reference. And We will send
> new MT2701 ionmmu/smi dtsi node patch base on [1] later, thus you can
> accept and merge to 4.11.
>
Thanks for the clarification. I pulled all this patches into
v4.10-next/dts32
Hans will you take v9 of this patch set?
Then I'll take the dts patch.
Regards,
Matthias
> [1]
> https://patchwork.kernel.org/patch/9489991/
> https://patchwork.kernel.org/patch/9489985/
> https://patchwork.kernel.org/patch/9489989/
>
> Thanks,
> Eddie
>
>
^ permalink raw reply
* [PATCH v2 2/6] arm: dts: mt2701: Add iommu/smi device node
From: Matthias Brugger @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484296978-18572-3-git-send-email-erin.lo@mediatek.com>
Hi Erin,
I just took the patch from Honghui he send in june.
Please see my comment inline.
On 13/01/17 09:42, Erin Lo wrote:
> From: Honghui Zhang <honghui.zhang@mediatek.com>
>
> Add the device node of iommu and smi for MT2701.
>
> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> Signed-off-by: Erin Lo <erin.lo@mediatek.com>
> ---
> arch/arm/boot/dts/mt2701.dtsi | 54 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 54 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index eb4c6fd..87be52c 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -17,6 +17,7 @@
> #include <dt-bindings/interrupt-controller/irq.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/reset/mt2701-resets.h>
> +#include <dt-bindings/memory/mt2701-larb-port.h>
> #include "skeleton64.dtsi"
> #include "mt2701-pinfunc.h"
>
> @@ -161,6 +162,16 @@
> clock-names = "system-clk", "rtc-clk";
> };
>
> + smi_common: smi at 1000c000 {
> + compatible = "mediatek,mt2701-smi-common";
> + reg = <0 0x1000c000 0 0x1000>;
> + clocks = <&infracfg CLK_INFRA_SMI>,
> + <&mmsys CLK_MM_SMI_COMMON>,
> + <&infracfg CLK_INFRA_SMI>;
> + clock-names = "apb", "smi", "async";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> + };
> +
> sysirq: interrupt-controller at 10200100 {
> compatible = "mediatek,mt2701-sysirq",
> "mediatek,mt6577-sysirq";
> @@ -170,6 +181,16 @@
> reg = <0 0x10200100 0 0x1c>;
> };
>
> + iommu: mmsys_iommu at 10205000 {
> + compatible = "mediatek,mt2701-m4u";
> + reg = <0 0x10205000 0 0x1000>;
> + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&infracfg CLK_INFRA_M4U>;
> + clock-names = "bclk";
> + mediatek,larbs = <&larb0 &larb1 &larb2>;
> + #iommu-cells = <1>;
> + };
> +
> apmixedsys: syscon at 10209000 {
> compatible = "mediatek,mt2701-apmixedsys", "syscon";
> reg = <0 0x10209000 0 0x1000>;
> @@ -272,18 +293,51 @@
> #clock-cells = <1>;
> };
>
> + larb0: larb at 14010000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x14010000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <0>;
Did I miss something? 'mediatek,larbidx' does not sound familiar to me.
Regards,
Matthias
> + clocks = <&mmsys CLK_MM_SMI_LARB0>,
> + <&mmsys CLK_MM_SMI_LARB0>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
> + };
> +
> imgsys: syscon at 15000000 {
> compatible = "mediatek,mt2701-imgsys", "syscon";
> reg = <0 0x15000000 0 0x1000>;
> #clock-cells = <1>;
> };
>
> + larb2: larb at 15001000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x15001000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <2>;
> + clocks = <&imgsys CLK_IMG_SMI_COMM>,
> + <&imgsys CLK_IMG_SMI_COMM>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
> + };
> +
> vdecsys: syscon at 16000000 {
> compatible = "mediatek,mt2701-vdecsys", "syscon";
> reg = <0 0x16000000 0 0x1000>;
> #clock-cells = <1>;
> };
>
> + larb1: larb at 16010000 {
> + compatible = "mediatek,mt2701-smi-larb";
> + reg = <0 0x16010000 0 0x1000>;
> + mediatek,smi = <&smi_common>;
> + mediatek,larbidx = <1>;
> + clocks = <&vdecsys CLK_VDEC_CKGEN>,
> + <&vdecsys CLK_VDEC_LARB>;
> + clock-names = "apb", "smi";
> + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
> + };
> +
> hifsys: syscon at 1a000000 {
> compatible = "mediatek,mt2701-hifsys", "syscon";
> reg = <0 0x1a000000 0 0x1000>;
>
^ permalink raw reply
* [PATCH v3 0/2] mmc: host: s3cmci: add device tree support
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
This series adds support for configuring Samsung's S3C24XX MMC/SD/SDIO
controller via device tree.
Tested on FriendlyARM mini2440, based on s3c2440 SoC.
Changes since v2:
- struct "s3cmci_drv_data" and flag "is2440" renamed
- copying the whole driver data struct instead of only its member so
it will be easier to extend the information in the future
- using mmc_of_parse() to read "cd-gpios" and "wp-gpios" properties
from device tree
Changes since v1:
- pinctrl description removed from DT binding
- unit and label on DT binding renamed to mmc
Sergio Prado (2):
dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
mmc: host: s3cmci: allow probing from device tree
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 +++
drivers/mmc/host/s3cmci.c | 298 +++++++++++----------
drivers/mmc/host/s3cmci.h | 3 +-
3 files changed, 192 insertions(+), 143 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
--
1.9.1
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484319953-6479-1-git-send-email-sergio.prado@e-labworks.com>
Adds the device tree bindings description for Samsung S3C24XX
MMC/SD/SDIO controller, used as a connectivity interface with external
MMC, SD and SDIO storage mediums.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 ++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
diff --git a/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
new file mode 100644
index 000000000000..d09dbf4b3824
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
@@ -0,0 +1,34 @@
+* Samsung's S3C24XX MMC/SD/SDIO controller device tree bindings
+
+Samsung's S3C24XX MMC/SD/SDIO controller is used as a connectivity interface
+with external MMC, SD and SDIO storage mediums.
+
+This file documents differences between the core mmc properties described by
+mmc.txt and the properties used by the Samsung S3C24XX MMC/SD/SDIO controller
+implementation.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c2410-sdi": for controllers compatible with s3c2410
+ - "samsung,s3c2412-sdi": for controllers compatible with s3c2412
+ - "samsung,s3c2440-sdi": for controllers compatible with s3c2440
+- clocks: Should reference the controller clock
+- clock-names: Should contain "sdi"
+
+Example:
+ mmc0: mmc at 5a000000 {
+ compatible = "samsung,s3c2440-sdi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdi_pins>;
+ reg = <0x5a000000 0x100000>;
+ interrupts = <0 0 21 3>;
+ clocks = <&clocks PCLK_SDI>;
+ clock-names = "sdi";
+ bus-width = <4>;
+ cd-gpios = <&gpg 8 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gph 8 GPIO_ACTIVE_LOW>;
+ };
+
+ Note: This example shows both SoC specific and board specific properties
+ in a single device node. The properties can be actually be separated
+ into SoC specific node and board specific node.
--
1.9.1
^ permalink raw reply related
* [PATCH v3 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2017-01-13 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484319953-6479-1-git-send-email-sergio.prado@e-labworks.com>
Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
tree.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
drivers/mmc/host/s3cmci.c | 298 ++++++++++++++++++++++++----------------------
drivers/mmc/host/s3cmci.h | 3 +-
2 files changed, 158 insertions(+), 143 deletions(-)
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 932a4b1fed33..55535b65e0b3 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -23,6 +23,10 @@
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/dma.h>
@@ -127,6 +131,22 @@ enum dbg_channels {
dbg_conf = (1 << 8),
};
+struct s3cmci_variant_data {
+ int s3c2440_compatible;
+};
+
+static const struct s3cmci_variant_data s3c2410_s3cmci_variant_data = {
+ .s3c2440_compatible = 0,
+};
+
+static const struct s3cmci_variant_data s3c2412_s3cmci_variant_data = {
+ .s3c2440_compatible = 1,
+};
+
+static const struct s3cmci_variant_data s3c2440_s3cmci_variant_data = {
+ .s3c2440_compatible = 1,
+};
+
static const int dbgmap_err = dbg_fail;
static const int dbgmap_info = dbg_info | dbg_conf;
static const int dbgmap_debug = dbg_err | dbg_debug;
@@ -730,7 +750,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
goto clear_status_bits;
/* Check for FIFO failure */
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
dbg(host, dbg_err, "FIFO failure\n");
host->mrq->data->error = -EILSEQ;
@@ -806,21 +826,6 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
}
-/*
- * ISR for the CardDetect Pin
-*/
-
-static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
-{
- struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
-
- dbg(host, dbg_irq, "card detect\n");
-
- mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-
- return IRQ_HANDLED;
-}
-
static void s3cmci_dma_done_callback(void *arg)
{
struct s3cmci_host *host = arg;
@@ -912,7 +917,7 @@ static void finalize_request(struct s3cmci_host *host)
if (s3cmci_host_usedma(host))
dmaengine_terminate_all(host->dma);
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
/* Clear failure register and reset fifo. */
writel(S3C2440_SDIFSTA_FIFORESET |
S3C2440_SDIFSTA_FIFOFAIL,
@@ -1025,7 +1030,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
dcon |= S3C2410_SDIDCON_XFER_RXSTART;
}
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
dcon |= S3C2440_SDIDCON_DS_WORD;
dcon |= S3C2440_SDIDCON_DATSTART;
}
@@ -1044,7 +1049,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
/* write TIMER register */
- if (host->is2440) {
+ if (host->variant->s3c2440_compatible) {
writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
} else {
writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
@@ -1176,19 +1181,6 @@ static void s3cmci_send_request(struct mmc_host *mmc)
s3cmci_enable_irq(host, true);
}
-static int s3cmci_card_present(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_detect)
- return -ENOSYS;
-
- ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
- return ret ^ pdata->detect_invert;
-}
-
static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1197,7 +1189,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->cmd_is_stop = 0;
host->mrq = mrq;
- if (s3cmci_card_present(mmc) == 0) {
+ if (mmc_gpio_get_cd(mmc) == 0) {
dbg(host, dbg_err, "%s: no medium present\n", __func__);
host->mrq->cmd->error = -ENOMEDIUM;
mmc_request_done(mmc, mrq);
@@ -1241,22 +1233,24 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_ON:
case MMC_POWER_UP:
/* Configure GPE5...GPE10 pins in SD mode */
- s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
- S3C_GPIO_PULL_NONE);
+ if (!host->pdev->dev.of_node)
+ s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_NONE);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
- if (!host->is2440)
+ if (!host->variant->s3c2440_compatible)
mci_con |= S3C2410_SDICON_FIFORESET;
break;
case MMC_POWER_OFF:
default:
- gpio_direction_output(S3C2410_GPE(5), 0);
+ if (!host->pdev->dev.of_node)
+ gpio_direction_output(S3C2410_GPE(5), 0);
- if (host->is2440)
+ if (host->variant->s3c2440_compatible)
mci_con |= S3C2440_SDICON_SDRESET;
if (host->pdata->set_power)
@@ -1294,21 +1288,6 @@ static void s3cmci_reset(struct s3cmci_host *host)
writel(con, host->base + S3C2410_SDICON);
}
-static int s3cmci_get_ro(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_wprotect)
- return 0;
-
- ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
- ret ^= pdata->wprotect_invert;
-
- return ret;
-}
-
static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1352,8 +1331,8 @@ static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
static struct mmc_host_ops s3cmci_ops = {
.request = s3cmci_request,
.set_ios = s3cmci_set_ios,
- .get_ro = s3cmci_get_ro,
- .get_cd = s3cmci_card_present,
+ .get_ro = mmc_gpio_get_ro,
+ .get_cd = mmc_gpio_get_cd,
.enable_sdio_irq = s3cmci_enable_sdio_irq,
};
@@ -1429,7 +1408,7 @@ static int s3cmci_state_show(struct seq_file *seq, void *v)
seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
seq_printf(seq, "Prescale = %d\n", host->prescaler);
- seq_printf(seq, "is2440 = %d\n", host->is2440);
+ seq_printf(seq, "S3C2440 compatible = %d\n", host->variant->s3c2440_compatible);
seq_printf(seq, "IRQ = %d\n", host->irq);
seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
@@ -1544,21 +1523,15 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
#endif /* CONFIG_DEBUG_FS */
-static int s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe_pdata(struct s3cmci_host *host)
{
- struct s3cmci_host *host;
- struct mmc_host *mmc;
- int ret;
- int is2440;
- int i;
+ struct platform_device *pdev = host->pdev;
+ struct mmc_host *mmc = host->mmc;
+ struct s3c24xx_mci_pdata *pdata;
+ int i, ret;
- is2440 = platform_get_device_id(pdev)->driver_data;
-
- mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- goto probe_out;
- }
+ host->variant = (const struct s3cmci_variant_data *)
+ platform_get_device_id(pdev)->driver_data;
for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
ret = gpio_request(i, dev_name(&pdev->dev));
@@ -1568,25 +1541,103 @@ static int s3cmci_probe(struct platform_device *pdev)
for (i--; i >= S3C2410_GPE(5); i--)
gpio_free(i);
- goto probe_free_host;
+ return ret;
}
}
+ if (!pdev->dev.platform_data)
+ pdev->dev.platform_data = &s3cmci_def_pdata;
+
+ pdata = pdev->dev.platform_data;
+
+ if (pdata->no_wprotect)
+ mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
+
+ if (pdata->no_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (pdata->wprotect_invert);
+ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+ if (pdata->detect_invert)
+ mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
+ if (gpio_is_valid(pdata->gpio_detect)) {
+ ret = mmc_gpio_request_cd(mmc, pdata->gpio_detect, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ if (gpio_is_valid(pdata->gpio_wprotect)) {
+ ret = mmc_gpio_request_ro(mmc, pdata->gpio_wprotect);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int s3cmci_probe_dt(struct s3cmci_host *host)
+{
+ struct platform_device *pdev = host->pdev;
+ struct s3c24xx_mci_pdata *pdata;
+ struct mmc_host *mmc = host->mmc;
+ int ret;
+
+ host->variant = of_device_get_match_data(&pdev->dev);
+ if (!host->variant)
+ return -ENODEV;
+
+ ret = mmc_of_parse(mmc);
+ if (ret)
+ return ret;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdev->dev.platform_data = pdata;
+
+ return 0;
+}
+
+static int s3cmci_probe(struct platform_device *pdev)
+{
+ struct s3cmci_host *host;
+ struct mmc_host *mmc;
+ int ret;
+ int i;
+
+ mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto probe_out;
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
- host->is2440 = is2440;
+
+ if (pdev->dev.of_node)
+ ret = s3cmci_probe_dt(host);
+ else
+ ret = s3cmci_probe_pdata(host);
+
+ if (ret)
+ goto probe_free_host;
host->pdata = pdev->dev.platform_data;
- if (!host->pdata) {
- pdev->dev.platform_data = &s3cmci_def_pdata;
- host->pdata = &s3cmci_def_pdata;
- }
spin_lock_init(&host->complete_lock);
tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
- if (is2440) {
+ if (host->variant->s3c2440_compatible) {
host->sdiimsk = S3C2440_SDIIMSK;
host->sdidata = S3C2440_SDIDATA;
host->clk_div = 1;
@@ -1644,43 +1695,6 @@ static int s3cmci_probe(struct platform_device *pdev)
disable_irq(host->irq);
host->irq_state = false;
- if (!host->pdata->no_detect) {
- ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
- if (ret) {
- dev_err(&pdev->dev, "failed to get detect gpio\n");
- goto probe_free_irq;
- }
-
- host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
-
- if (host->irq_cd >= 0) {
- if (request_irq(host->irq_cd, s3cmci_irq_cd,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- DRIVER_NAME, host)) {
- dev_err(&pdev->dev,
- "can't get card detect irq.\n");
- ret = -ENOENT;
- goto probe_free_gpio_cd;
- }
- } else {
- dev_warn(&pdev->dev,
- "host detect has no irq available\n");
- gpio_direction_input(host->pdata->gpio_detect);
- }
- } else
- host->irq_cd = -1;
-
- if (!host->pdata->no_wprotect) {
- ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
- if (ret) {
- dev_err(&pdev->dev, "failed to get writeprotect\n");
- goto probe_free_irq_cd;
- }
-
- gpio_direction_input(host->pdata->gpio_wprotect);
- }
-
/* Depending on the dma state, get a DMA channel to use. */
if (s3cmci_host_usedma(host)) {
@@ -1688,7 +1702,7 @@ static int s3cmci_probe(struct platform_device *pdev)
ret = PTR_ERR_OR_ZERO(host->dma);
if (ret) {
dev_err(&pdev->dev, "cannot get DMA channel.\n");
- goto probe_free_gpio_wp;
+ goto probe_free_irq;
}
}
@@ -1730,7 +1744,7 @@ static int s3cmci_probe(struct platform_device *pdev)
dbg(host, dbg_debug,
"probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
- (host->is2440?"2440":""),
+ (host->variant->s3c2440_compatible?"2440":""),
host->base, host->irq, host->irq_cd, host->dma);
ret = s3cmci_cpufreq_register(host);
@@ -1767,18 +1781,6 @@ static int s3cmci_probe(struct platform_device *pdev)
if (s3cmci_host_usedma(host))
dma_release_channel(host->dma);
- probe_free_gpio_wp:
- if (!host->pdata->no_wprotect)
- gpio_free(host->pdata->gpio_wprotect);
-
- probe_free_gpio_cd:
- if (!host->pdata->no_detect)
- gpio_free(host->pdata->gpio_detect);
-
- probe_free_irq_cd:
- if (host->irq_cd >= 0)
- free_irq(host->irq_cd, host);
-
probe_free_irq:
free_irq(host->irq, host);
@@ -1789,8 +1791,9 @@ static int s3cmci_probe(struct platform_device *pdev)
release_mem_region(host->mem->start, resource_size(host->mem));
probe_free_gpio:
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
@@ -1817,7 +1820,6 @@ static int s3cmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pd = host->pdata;
int i;
s3cmci_shutdown(pdev);
@@ -1831,15 +1833,9 @@ static int s3cmci_remove(struct platform_device *pdev)
free_irq(host->irq, host);
- if (!pd->no_wprotect)
- gpio_free(pd->gpio_wprotect);
-
- if (!pd->no_detect)
- gpio_free(pd->gpio_detect);
-
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
-
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
iounmap(host->base);
release_mem_region(host->mem->start, resource_size(host->mem));
@@ -1848,16 +1844,33 @@ static int s3cmci_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id s3cmci_dt_match[] = {
+ {
+ .compatible = "samsung,s3c2410-sdi",
+ .data = &s3c2410_s3cmci_variant_data,
+ },
+ {
+ .compatible = "samsung,s3c2412-sdi",
+ .data = &s3c2412_s3cmci_variant_data,
+ },
+ {
+ .compatible = "samsung,s3c2440-sdi",
+ .data = &s3c2440_s3cmci_variant_data,
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+
static const struct platform_device_id s3cmci_driver_ids[] = {
{
.name = "s3c2410-sdi",
- .driver_data = 0,
+ .driver_data = (kernel_ulong_t) &s3c2410_s3cmci_variant_data,
}, {
.name = "s3c2412-sdi",
- .driver_data = 1,
+ .driver_data = (kernel_ulong_t) &s3c2412_s3cmci_variant_data,
}, {
.name = "s3c2440-sdi",
- .driver_data = 1,
+ .driver_data = (kernel_ulong_t) &s3c2440_s3cmci_variant_data,
},
{ }
};
@@ -1867,6 +1880,7 @@ static int s3cmci_remove(struct platform_device *pdev)
static struct platform_driver s3cmci_driver = {
.driver = {
.name = "s3c-sdi",
+ .of_match_table = s3cmci_dt_match,
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index 30c2c0dd1bc8..e9fe48915a2e 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -33,7 +33,8 @@ struct s3cmci_host {
unsigned long real_rate;
u8 prescaler;
- int is2440;
+ const struct s3cmci_variant_data *variant;
+
unsigned sdiimsk;
unsigned sdidata;
--
1.9.1
^ permalink raw reply related
* [PATCH 1/3] ARM: dts: Ux500: move USB PHY pins to PHY device
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
The physical pins from the SoC are in a sense belonging to the
PHY device (AB8500 USB) rather than the MUSB USB IP block.
The driver definately assumes so: before this change it
complains that it cannot control the pins it is using:
abx5x0-usb ab8500-usb.0: could not get/set default pinstate
After this patch the warning goes away.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-href.dtsi | 12 ++++++------
arch/arm/boot/dts/ste-snowball.dts | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 48dc38482633..965fa10d1e8a 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -19,12 +19,6 @@
};
soc {
- usb_per5 at a03e0000 {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&musb_default_mode>;
- pinctrl-1 = <&musb_sleep_mode>;
- };
-
uart at 80120000 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&uart0_default_mode>;
@@ -225,6 +219,12 @@
ab8500-gpio {
};
+ ab8500_usb {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
ab8500-regulators {
ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
regulator-name = "V-DISPLAY";
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 386eee6de232..71daa27bb7e3 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -159,12 +159,6 @@
"", "", "", "", "", "", "", "";
};
- usb_per5 at a03e0000 {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&musb_default_mode>;
- pinctrl-1 = <&musb_sleep_mode>;
- };
-
sound {
compatible = "stericsson,snd-soc-mop500";
@@ -448,6 +442,12 @@
"PM_GPIO42"; /* AB8500 GPIO42 */
};
+ ab8500_usb {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&musb_default_mode>;
+ pinctrl-1 = <&musb_sleep_mode>;
+ };
+
ext_regulators: ab8500-ext-regulators {
ab8500_ext1_reg: ab8500_ext1 {
regulator-name = "ab8500-ext-supply1";
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] ARM: dts: add the AB8500 sysclk to the device trees
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
This clock has been missing since some early stages of device tree
conversion. Adding the right clocks to the device tree makes USB
work again.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-dbx5x0.dtsi | 2 ++
arch/arm/boot/dts/ste-href.dtsi | 2 ++
arch/arm/boot/dts/ste-snowball.dts | 2 ++
3 files changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index d309314f3a36..82d8c4771293 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -669,6 +669,8 @@
vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
v-ape-supply = <&db8500_vape_reg>;
musb_1v8-supply = <&db8500_vsmps2_reg>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
ab8500-ponkey {
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 965fa10d1e8a..4f70088d3c8a 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -191,6 +191,8 @@
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
msp0: msp at 80123000 {
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 71daa27bb7e3..c6bcc8e2f29a 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -164,6 +164,8 @@
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>;
+ clock-names = "sysclk";
};
msp0: msp at 80123000 {
--
2.9.3
^ permalink raw reply related
* [PATCH 3/3] ARM: dts: add the AB8500 clocks to the device tree
From: Linus Walleij @ 2017-01-13 15:11 UTC (permalink / raw)
To: linux-arm-kernel
This adds the AB8500 clocks to the device tree using the new
bindings from the clk subsystem, making audio work again.
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
arch/arm/boot/dts/ste-dbx5x0.dtsi | 19 +++++++++++++++++++
arch/arm/boot/dts/ste-href.dtsi | 9 ---------
arch/arm/boot/dts/ste-snowball.dts | 9 ---------
3 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index 82d8c4771293..084fb4f13a7b 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/mfd/dbx500-prcmu.h>
#include <dt-bindings/arm/ux500_pm_domains.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/ste-ab8500.h>
#include "skeleton.dtsi"
/ {
@@ -603,6 +604,11 @@
interrupt-controller;
#interrupt-cells = <2>;
+ ab8500_clock: ab8500-clock {
+ compatible = "stericsson,ab8500-clk";
+ #clock-cells = <1>;
+ };
+
ab8500_gpio: ab8500-gpio {
compatible = "stericsson,ab8500-gpio";
gpio-controller;
@@ -686,6 +692,8 @@
ab8500-pwm {
compatible = "stericsson,ab8500-pwm";
+ clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
+ clock-names = "intclk";
};
ab8500-debugfs {
@@ -700,6 +708,9 @@
V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
+ clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
+ clock-names = "audioclk";
+
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
@@ -1095,6 +1106,14 @@
status = "disabled";
};
+ sound {
+ compatible = "stericsson,snd-soc-mop500";
+ stericsson,cpu-dai = <&msp1 &msp3>;
+ stericsson,audio-codec = <&codec>;
+ clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
+ clock-names = "sysclk", "ulpclk", "intclk";
+ };
+
msp0: msp at 80123000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80123000 0x1000>;
diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
index 4f70088d3c8a..a10369ed36e0 100644
--- a/arch/arm/boot/dts/ste-href.dtsi
+++ b/arch/arm/boot/dts/ste-href.dtsi
@@ -186,15 +186,6 @@
status = "okay";
};
- sound {
- compatible = "stericsson,snd-soc-mop500";
-
- stericsson,cpu-dai = <&msp1 &msp3>;
- stericsson,audio-codec = <&codec>;
- clocks = <&prcmu_clk PRCMU_SYSCLK>;
- clock-names = "sysclk";
- };
-
msp0: msp at 80123000 {
pinctrl-names = "default";
pinctrl-0 = <&msp0_default_mode>;
diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index c6bcc8e2f29a..d1be40f96154 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -159,15 +159,6 @@
"", "", "", "", "", "", "", "";
};
- sound {
- compatible = "stericsson,snd-soc-mop500";
-
- stericsson,cpu-dai = <&msp1 &msp3>;
- stericsson,audio-codec = <&codec>;
- clocks = <&prcmu_clk PRCMU_SYSCLK>;
- clock-names = "sysclk";
- };
-
msp0: msp at 80123000 {
pinctrl-names = "default";
pinctrl-0 = <&msp0_default_mode>;
--
2.9.3
^ permalink raw reply related
* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Matthias Brugger @ 2017-01-13 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170113151747.6bc85245@bbrezillon>
On 13/01/17 15:17, Boris Brezillon wrote:
> On Fri, 13 Jan 2017 15:13:29 +0800
> Guochun Mao <guochun.mao@mediatek.com> wrote:
>
>> Add Mediatek nor flash node.
>>
>> Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
>> ---
>> arch/arm/boot/dts/mt2701-evb.dts | 25 +++++++++++++++++++++++++
>> arch/arm/boot/dts/mt2701.dtsi | 12 ++++++++++++
>> 2 files changed, 37 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
>> index 082ca88..85e5ae8 100644
>> --- a/arch/arm/boot/dts/mt2701-evb.dts
>> +++ b/arch/arm/boot/dts/mt2701-evb.dts
>> @@ -24,6 +24,31 @@
>> };
>> };
>>
>> +&nor_flash {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&nor_pins_default>;
>> + status = "okay";
>> + flash at 0 {
>> + compatible = "jedec,spi-nor";
>> + reg = <0>;
>> + };
>> +};
>> +
>> +&pio {
>> + nor_pins_default: nor {
>> + pins1 {
>> + pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
>> + <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
>> + <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
>> + <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
>> + <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
>> + <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
>> + drive-strength = <MTK_DRIVE_4mA>;
>> + bias-pull-up;
>> + };
>> + };
>> +};
>> +
>> &uart0 {
>> status = "okay";
>> };
>> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
>> index bdf8954..1eefce4 100644
>> --- a/arch/arm/boot/dts/mt2701.dtsi
>> +++ b/arch/arm/boot/dts/mt2701.dtsi
>> @@ -227,6 +227,18 @@
>> status = "disabled";
>> };
>>
>> + nor_flash: spi at 11014000 {
>> + compatible = "mediatek,mt2701-nor",
>> + "mediatek,mt8173-nor";
>
> Why define both here? Is "mediatek,mt8173-nor" really providing a
> subset of the features supported by "mediatek,mt2701-nor"?
>
I think even if the ip block is the same, we should provide both
bindings, just in case in the future we find out that mt2701 has some
hidden bug, feature or bug-feature. This way even if we update the
driver, we stay compatible with older device tree blobs in the wild.
We can drop the mt2701-nor in the bindings definition if you want.
Regards,
Matthias
>> + reg = <0 0x11014000 0 0xe0>;
>> + clocks = <&pericfg CLK_PERI_FLASH>,
>> + <&topckgen CLK_TOP_FLASH_SEL>;
>> + clock-names = "spi", "sf";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + status = "disabled";
>> + };
>> +
>> mmsys: syscon at 14000000 {
>> compatible = "mediatek,mt2701-mmsys", "syscon";
>> reg = <0 0x14000000 0 0x1000>;
>
^ permalink raw reply
* [PATCH v3 3/5] arm64: Create and use __tlbi_dsb() macros
From: Christopher Covington @ 2017-01-13 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170112165852.GH13843@arm.com>
Hi Will,
On 01/12/2017 11:58 AM, Will Deacon wrote:
> Hi Christopher,
>
> On Wed, Jan 11, 2017 at 09:41:16AM -0500, Christopher Covington wrote:
>> This refactoring will allow an errata workaround that repeats tlbi dsb
>> sequences to only change one location. This is not intended to change the
>> generated assembly and comparison of before and after preprocessor output
>> of arch/arm64/mm/mmu.c and vmlinux objdump shows no functional changes.
>>
>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>> ---
>> arch/arm64/include/asm/tlbflush.h | 104 +++++++++++++++++++++++++-------------
>> 1 file changed, 69 insertions(+), 35 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
>> index deab523..f28813c 100644
>> --- a/arch/arm64/include/asm/tlbflush.h
>> +++ b/arch/arm64/include/asm/tlbflush.h
>> @@ -25,22 +25,69 @@
>> #include <asm/cputype.h>
>>
>> /*
>> - * Raw TLBI operations.
>> + * Raw TLBI, DSB operations
>> *
>> - * Where necessary, use the __tlbi() macro to avoid asm()
>> - * boilerplate. Drivers and most kernel code should use the TLB
>> - * management routines in preference to the macro below.
>> + * Where necessary, use __tlbi_*dsb() macros to avoid asm() boilerplate.
>> + * Drivers and most kernel code should use the TLB management routines in
>> + * preference to the macros below.
>> *
>> - * The macro can be used as __tlbi(op) or __tlbi(op, arg), depending
>> - * on whether a particular TLBI operation takes an argument or
>> - * not. The macros handles invoking the asm with or without the
>> - * register argument as appropriate.
>> + * The __tlbi_dsb() macro handles invoking the asm without any register
>> + * argument, with a single register argument, and with start (included)
>> + * and end (excluded) range of register arguments. For example:
>> + *
>> + * __tlbi_dsb(op, attr)
>> + *
>> + * tlbi op
>> + * dsb attr
>> + *
>> + * __tlbi_dsb(op, attr, addr)
>> + *
>> + * mov %[addr], =addr
>> + * tlbi op, %[addr]
>> + * dsb attr
>> + *
>> + * __tlbi_range_dsb(op, attr, start, end)
>> + *
>> + * mov %[arg], =start
>> + * mov %[end], =end
>> + * for:
>> + * tlbi op, %[addr]
>> + * add %[addr], %[addr], #(1 << (PAGE_SHIFT - 12))
>> + * cmp %[addr], %[end]
>> + * b.ne for
>> + * dsb attr
>> */
>> -#define __TLBI_0(op, arg) asm ("tlbi " #op)
>> -#define __TLBI_1(op, arg) asm ("tlbi " #op ", %0" : : "r" (arg))
>> -#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
>>
>> -#define __tlbi(op, ...) __TLBI_N(op, ##__VA_ARGS__, 1, 0)
>> +#define __TLBI_FOR_0(ig0, ig1, ig2)
>> +#define __TLBI_INSTR_0(op, ig1, ig2) "tlbi " #op
>> +#define __TLBI_IO_0(ig0, ig1, ig2) : :
>> +
>> +#define __TLBI_FOR_1(ig0, ig1, ig2)
>> +#define __TLBI_INSTR_1(op, ig0, ig1) "tlbi " #op ", %0"
>> +#define __TLBI_IO_1(ig0, arg, ig1) : : "r" (arg)
>> +
>> +#define __TLBI_FOR_2(ig0, start, ig1) unsigned long addr; \
>> + for (addr = start; addr < end; \
>> + addr += 1 << (PAGE_SHIFT - 12))
>> +#define __TLBI_INSTR_2(op, ig0, ig1) "tlbi " #op ", %0"
>> +#define __TLBI_IO_2(ig0, ig1, ig2) : : "r" (addr)
>> +
>> +#define __TLBI_FOR_N(op, a1, a2, n, ...) __TLBI_FOR_##n(op, a1, a2)
>> +#define __TLBI_INSTR_N(op, a1, a2, n, ...) __TLBI_INSTR_##n(op, a1, a2)
>> +#define __TLBI_IO_N(op, a1, a2, n, ...) __TLBI_IO_##n(op, a1, a2)
>> +
>> +#define __TLBI_FOR(op, ...) __TLBI_FOR_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +#define __TLBI_INSTR(op, ...) __TLBI_INSTR_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +#define __TLBI_IO(op, ...) __TLBI_IO_N(op, ##__VA_ARGS__, 2, 1, 0)
>> +
>> +#define __tlbi_asm_dsb(as, op, attr, ...) do { \
>> + __TLBI_FOR(op, ##__VA_ARGS__) \
>> + asm (__TLBI_INSTR(op, ##__VA_ARGS__) \
>> + __TLBI_IO(op, ##__VA_ARGS__)); \
>> + asm volatile ( as "\ndsb " #attr "\n" \
>> + : : : "memory"); } while (0)
>> +
>> +#define __tlbi_dsb(...) __tlbi_asm_dsb("", ##__VA_ARGS__)
>
> I can't deny that this is cool, but ultimately it's completely unreadable.
> What I was thinking you'd do would be make __tlbi expand to:
>
> tlbi
> dsb
> tlbi
> dsb
>
> for Falkor, and:
>
> tlbi
> nop
> nop
> nop
>
> for everybody else.
Thanks for the suggestion. So would __tlbi take a dsb sharability argument in
your proposal? Or would it be communicated in some other fashion, maybe inferred
from the tlbi argument? Or would the workaround dsbs all be the worst/broadest
case?
> Wouldn't that localise this change sufficiently that you wouldn't need
> to change all the callers and encode the looping in your cpp macros?
>
> I realise you get an extra dsb in some places with that change, but I'd
> like to see numbers for the impact of that on top of the workaround. If
> it's an issue, then an alternative sequence would be:
>
> tlbi
> dsb
> tlbi
>
> and you'd rely on the existing dsb to complete that.
>
> Having said that, I don't understand how your current loop code works
> when the workaround is applied. AFAICT, you end up emitting something
> like:
>
> dsb ishst
> for i in 0 to n
> tlbi va+i
> dsb
> tlbi va+n
> dsb
>
> which looks wrong to me. Am I misreading something here?
You're right, I am off by 1 << (PAGE_SHIFT - 12) here. I would need to
increment, compare, not take the loop branch (regular for loop stuff),
then decrement (missing) and perform TLB invalidation again (present but
using incorrect value).
Thanks,
Cov
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code
Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v3 16/24] media: Add i.MX media core driver
From: Philipp Zabel @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483755102-24785-17-git-send-email-steve_longerbeam@mentor.com>
Am Freitag, den 06.01.2017, 18:11 -0800 schrieb Steve Longerbeam:
> Add the core media driver for i.MX SOC.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
> Documentation/media/v4l-drivers/imx.rst | 443 ++++++++++
> drivers/staging/media/Kconfig | 2 +
> drivers/staging/media/Makefile | 1 +
> drivers/staging/media/imx/Kconfig | 8 +
> drivers/staging/media/imx/Makefile | 6 +
> drivers/staging/media/imx/TODO | 22 +
> drivers/staging/media/imx/imx-media-common.c | 981 ++++++++++++++++++++++
> drivers/staging/media/imx/imx-media-dev.c | 486 +++++++++++
> drivers/staging/media/imx/imx-media-fim.c | 471 +++++++++++
> drivers/staging/media/imx/imx-media-internal-sd.c | 457 ++++++++++
> drivers/staging/media/imx/imx-media-of.c | 289 +++++++
> drivers/staging/media/imx/imx-media.h | 310 +++++++
> include/media/imx.h | 15 +
> include/uapi/linux/v4l2-controls.h | 4 +
> 14 files changed, 3495 insertions(+)
> create mode 100644 Documentation/media/v4l-drivers/imx.rst
> create mode 100644 drivers/staging/media/imx/Kconfig
> create mode 100644 drivers/staging/media/imx/Makefile
> create mode 100644 drivers/staging/media/imx/TODO
> create mode 100644 drivers/staging/media/imx/imx-media-common.c
> create mode 100644 drivers/staging/media/imx/imx-media-dev.c
> create mode 100644 drivers/staging/media/imx/imx-media-fim.c
> create mode 100644 drivers/staging/media/imx/imx-media-internal-sd.c
> create mode 100644 drivers/staging/media/imx/imx-media-of.c
> create mode 100644 drivers/staging/media/imx/imx-media.h
> create mode 100644 include/media/imx.h
>
> diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
> new file mode 100644
> index 0000000..87b37b5
> --- /dev/null
> +++ b/Documentation/media/v4l-drivers/imx.rst
> @@ -0,0 +1,443 @@
> +i.MX Video Capture Driver
> +=========================
> +
> +Introduction
> +------------
> +
> +The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
> +handles the flow of image frames to and from capture devices and
> +display devices.
> +
> +For image capture, the IPU contains the following internal subunits:
> +
> +- Image DMA Controller (IDMAC)
> +- Camera Serial Interface (CSI)
> +- Image Converter (IC)
> +- Sensor Multi-FIFO Controller (SMFC)
> +- Image Rotator (IRT)
> +- Video De-Interlace Controller (VDIC)
Nitpick: Video De-Interlacing or Combining Block (VDIC)
> +
> +The IDMAC is the DMA controller for transfer of image frames to and from
> +memory. Various dedicated DMA channels exist for both video capture and
> +display paths.
> +
> +The CSI is the frontend capture unit that interfaces directly with
> +capture sensors over Parallel, BT.656/1120, and MIPI CSI-2 busses.
> +
> +The IC handles color-space conversion, resizing, and rotation
> +operations.
And horizontal flipping.
> There are three independent "tasks" within the IC that can
> +carry out conversions concurrently: pre-processing encoding,
> +pre-processing preview, and post-processing.
s/preview/viewfinder/ seems to be the commonly used name.
This paragraph could mention that a single hardware unit is used
transparently time multiplexed by the three tasks at different
granularity for the downsizing, main processing, and rotation sections.
The downscale unit switches between tasks at 8-pixel burst granularity,
the main processing unit at line granularity. The rotation units switch
only at frame granularity.
> +The SMFC is composed of four independent channels that each can transfer
> +captured frames from sensors directly to memory concurrently.
> +
> +The IRT carries out 90 and 270 degree image rotation operations.
... on 8x8 pixel blocks, supported by the IDMAC which handles block
transfers, block reordering, and vertical flipping.
> +The VDIC handles the conversion of interlaced video to progressive, with
> +support for different motion compensation modes (low, medium, and high
> +motion). The deinterlaced output frames from the VDIC can be sent to the
> +IC pre-process preview task for further conversions.
> +
> +In addition to the IPU internal subunits, there are also two units
> +outside the IPU that are also involved in video capture on i.MX:
> +
> +- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
> + interface. This is a Synopsys DesignWare core.
> +- A video multiplexer for selecting among multiple sensor inputs to
> + send to a CSI.
Two of them, actually.
> +For more info, refer to the latest versions of the i.MX5/6 reference
> +manuals listed under References.
> +
> +
> +Features
> +--------
> +
> +Some of the features of this driver include:
> +
> +- Many different pipelines can be configured via media controller API,
> + that correspond to the hardware video capture pipelines supported in
> + the i.MX.
> +
> +- Supports parallel, BT.565, and MIPI CSI-2 interfaces.
> +
> +- Up to four concurrent sensor acquisitions, by configuring each
> + sensor's pipeline using independent entities. This is currently
> + demonstrated with the SabreSD and SabreLite reference boards with
> + independent OV5642 and MIPI CSI-2 OV5640 sensor modules.
> +
> +- Scaling, color-space conversion, and image rotation via IC task
> + subdevs.
> +
> +- Many pixel formats supported (RGB, packed and planar YUV, partial
> + planar YUV).
> +
> +- The IC pre-process preview subdev supports motion compensated
> + de-interlacing using the VDIC, with three motion compensation modes:
> + low, medium, and high motion. The mode is specified with a custom
> + control. Pipelines are defined that allow sending frames to the
> + preview subdev directly from the CSI or from the SMFC.
> +
> +- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
> + problems with the ADV718x video decoders. See below for a description
> + of the FIM.
Could this also be used to calculate more precise capture timestamps?
> +Capture Pipelines
> +-----------------
> +
> +The following describe the various use-cases supported by the pipelines.
> +
> +The links shown do not include the frontend sensor, video mux, or mipi
> +csi-2 receiver links. This depends on the type of sensor interface
> +(parallel or mipi csi-2). So in all cases, these pipelines begin with:
> +
> +sensor -> ipu_csi_mux -> ipu_csi -> ...
> +
> +for parallel sensors, or:
> +
> +sensor -> imx-mipi-csi2 -> (ipu_csi_mux) -> ipu_csi -> ...
> +
> +for mipi csi-2 sensors. The imx-mipi-csi2 receiver may need to route
> +to the video mux (ipu_csi_mux) before sending to the CSI, depending
> +on the mipi csi-2 virtual channel, hence ipu_csi_mux is shown in
> +parenthesis.
> +
> +Unprocessed Video Capture:
> +--------------------------
> +
> +Send frames directly from sensor to camera interface, with no
> +conversions:
> +
> +-> ipu_smfc -> camif
I'd call this capture interface, this is not just for cameras. Or maybe
idmac if you want to mirror hardware names?
> +Note the ipu_smfc can do pixel reordering within the same colorspace.
That isn't a feature of the SMFC, but of the IDMAC (FCW & FCR).
> +For example, its sink pad can take UYVY2X8, but its source pad can
> +output YUYV2X8.
I don't think this is correct. Re-reading "37.4.3.7 Packing to memory"
in the CSI chapter, for 8-bit per component data, the internal format
between CSI, SMFC, and IDMAC is always some 32-bit RGBx/YUVx variant
(or "bayer/generic data"). In either case, the internal format does not
change along the way.
> +IC Direct Conversions:
> +----------------------
> +
> +This pipeline uses the preprocess encode entity to route frames directly
> +from the CSI to the IC (bypassing the SMFC), to carry out scaling up to
> +1024x1024 resolution, CSC, and image rotation:
> +
> +-> ipu_ic_prpenc -> camif
> +
> +This can be a useful capture pipeline for heavily loaded memory bus
> +traffic environments, since it has minimal IDMAC channel usage.
Note that if rotation is enabled, transfers between IC processing and
rotation still have to go through memory once.
> +Post-Processing Conversions:
> +----------------------------
> +
> +This pipeline routes frames from the SMFC to the post-processing
> +entity.
No, frames written by the CSI -> SMFC -> IDMAC path are read back into
the post-processing entity.
> In addition to CSC and rotation, this entity supports tiling
> +which allows scaled output beyond the 1024x1024 limitation of the IC
> +(up to 4096x4096 scaling output is supported):
> +
> +-> ipu_smfc -> ipu_ic_pp -> camif
> +
> +Motion Compensated De-interlace:
> +--------------------------------
> +
> +This pipeline routes frames from the SMFC to the preprocess preview
> +entity to support motion-compensated de-interlacing using the VDIC,
> +scaling up to 1024x1024, and CSC:
> +
> +-> ipu_smfc -> ipu_ic_prpvf -> camif
Same as above.
> +This pipeline also carries out the same conversions as above, but routes
> +frames directly from the CSI to the IC preprocess preview entity for
> +minimal memory bandwidth usage (note: this pipeline only works in
> +"high motion" mode):
> +
> +-> ipu_ic_prpvf -> camif
> +
> +This pipeline takes the motion-compensated de-interlaced frames and
> +sends them to the post-processor, to support motion-compensated
> +de-interlacing, scaling up to 4096x4096, CSC, and rotation:
> +
> +-> (ipu_smfc) -> ipu_ic_prpvf -> ipu_ic_pp -> camif
> +
> +
> +Usage Notes
> +-----------
[...]
> +SabreLite with OV5642 and OV5640
> +--------------------------------
> +
> +This platform requires the OmniVision OV5642 module with a parallel
> +camera interface, and the OV5640 module with a MIPI CSI-2
> +interface. Both modules are available from Boundary Devices:
> +
> +https://boundarydevices.com/products/nit6x_5mp
> +https://boundarydevices.com/product/nit6x_5mp_mipi
> +
> +Note that if only one camera module is available, the other sensor
> +node can be disabled in the device tree.
> +
> +The OV5642 module is connected to the parallel bus input on the i.MX
> +internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.
> +
> +The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
> +receiver, and the four virtual channel outputs from the receiver are
> +routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
> +vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
> +also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
> +OV5640 must not share the same i2c slave address.
> +
> +The following basic example configures unprocessed video capture
> +pipelines for both sensors. The OV5642 is routed to camif0
> +(usually /dev/video0), and the OV5640 (transmitting on mipi csi-2
> +virtual channel 1) is routed to camif1 (usually /dev/video1). Both
> +sensors are configured to output 640x480, UYVY (not shown: all pad
> +field types should be set to "NONE"):
> +
> +.. code-block:: none
> +
> + # Setup links for OV5642
> + media-ctl -l '"ov5642 1-0042":0 -> "ipu1_csi0_mux":1[1]'
> + media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
> + media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
> + media-ctl -l '"ipu1_smfc0":1 -> "camif0":0[1]'
> + media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
> + # Setup links for OV5640
> + media-ctl -l '"ov5640_mipi 1-0040":0 -> "imx-mipi-csi2":0[1]'
> + media-ctl -l '"imx-mipi-csi2":2 -> "ipu1_csi1":0[1]'
> + media-ctl -l '"ipu1_csi1":1 -> "ipu1_smfc1":0[1]'
> + media-ctl -l '"ipu1_smfc1":1 -> "camif1":0[1]'
> + media-ctl -l '"camif1":1 -> "camif1 devnode":0[1]'
> + # Configure pads for OV5642 pipeline
> + media-ctl -V "\"ov5642 1-0042\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_csi0\":1 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_smfc0\":0 [fmt:YUYV2X8/640x480]"
> + media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/640x480]"
I think the smfc entities should be dropped.
> + media-ctl -V "\"camif0\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"camif0\":1 [fmt:UYVY2X8/640x480]"
> + # Configure pads for OV5640 pipeline
> + media-ctl -V "\"ov5640_mipi 1-0040\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"imx-mipi-csi2\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"imx-mipi-csi2\":2 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"ipu1_csi1\":0 [fmt:UYVY2X8/640x480]"
> + media-ctl -V "\"ipu1_csi1\":1 [fmt:UYVY2X8/640x480]"
[...]
> + media-ctl -V "\"camif1\":0 [fmt:UYVY2X8/640x480]"
I agree this looks very intuitive, but technically correct for the
csi1:1 and camif1:0 pads would be a 32-bit YUV format.
(MEDIA_BUS_FMT_YUV8_1X32_PADLO doesn't exist yet).
I think it would be better to use the correct format as that will allow
to chose the regular vs. companded packings in the future for formats
with more than 8 bits per component.
> + media-ctl -V "\"camif1\":1 [fmt:UYVY2X8/640x480]"
>+
> +Streaming can then begin independently on device nodes /dev/video0
> +and /dev/video1.
> +
> +SabreAuto with ADV7180 decoder
> +------------------------------
> +
> +On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
> +parallel bus input on the internal video mux to IPU1 CSI0.
> +
> +The following example configures a pipeline to capture from the ADV7180
> +video decoder, assuming NTSC 720x480 input signals, with Motion
> +Compensated de-interlacing (not shown: all pad field types should be set
> +as indicated). $outputfmt can be any format supported by the
> +ipu1_ic_prpvf entity at its output pad:
> +
> +.. code-block:: none
> +
> + # Setup links
> + media-ctl -l '"adv7180 3-0021":0 -> "ipu1_csi0_mux":1[1]'
> + media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
> + media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
> + media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
> + media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
> + media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
> + # Configure pads
> + # pad field types for below pads must be an interlaced type
> + # such as "ALTERNATE"
I think alternate should only extend as far as the CSI, since the CSI
can only capture NTSC/PAL fields in a fixed order.
> + media-ctl -V "\"adv7180 3-0021\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
>From here the interlaced field type should be sequential in the correct
order depending on NTSC/PAL.
> + media-ctl -V "\"ipu1_csi0_mux\":2 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_csi0\":1 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_smfc0\":0 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/720x480]"
> + media-ctl -V "\"ipu1_ic_prpvf\":0 [fmt:UYVY2X8/720x480]"
> + # pad field types for below pads must be "NONE"
> + media-ctl -V "\"ipu1_ic_prpvf\":1 [fmt:$outputfmt]"
> + media-ctl -V "\"camif0\":0 [fmt:$outputfmt]"
> + media-ctl -V "\"camif0\":1 [fmt:$outputfmt]"
> +
> +Streaming can then begin on /dev/video0.
> +
> +This platform accepts Composite Video analog inputs to the ADV7180 on
> +Ain1 (connector J42) and Ain3 (connector J43).
> +
> +To switch to Ain1:
> +
> +.. code-block:: none
> +
> + # v4l2-ctl -i0
> +
> +To switch to Ain3:
> +
> +.. code-block:: none
> +
> + # v4l2-ctl -i1
> +
> +
> +Frame Interval Monitor
> +----------------------
> +
> +The adv718x decoders can occasionally send corrupt fields during
> +NTSC/PAL signal re-sync (too little or too many video lines). When
> +this happens, the IPU triggers a mechanism to re-establish vertical
> +sync by adding 1 dummy line every frame, which causes a rolling effect
> +from image to image, and can last a long time before a stable image is
> +recovered. Or sometimes the mechanism doesn't work at all, causing a
> +permanent split image (one frame contains lines from two consecutive
> +captured images).
Is it only SabreAuto on which the FIM mechanism can be used due to the
pad routing?
[...]
> +/*
> + * DMA buffer ring handling
> + */
> +struct imx_media_dma_buf_ring {
> + struct imx_media_dev *imxmd;
> +
> + /* the ring */
> + struct imx_media_dma_buf buf[IMX_MEDIA_MAX_RING_BUFS];
> + /* the scratch buffer for underruns */
> + struct imx_media_dma_buf scratch;
> +
> + /* buffer generator */
> + struct media_entity *src;
> + /* buffer receiver */
> + struct media_entity *sink;
> +
> + spinlock_t lock;
> +
> + int num_bufs;
> + unsigned long last_seq;
> +};
I don't think this belongs in the capture driver at all.
Memory-to-memory transfers should be handled at the videobuf2 level.
[...]
> +static struct imx_media_dma_buf *
> +__dma_buf_queue(struct imx_media_dma_buf_ring *ring, int index)
> +{
> + struct imx_media_dma_buf *buf;
> +
> + if (index >= ring->num_bufs)
> + return ERR_PTR(-EINVAL);
> +
> + buf = &ring->buf[index];
> + if (WARN_ON(buf->state != IMX_MEDIA_BUF_STATUS_PREPARED))
> + return ERR_PTR(-EINVAL);
> +
> + buf->state = IMX_MEDIA_BUF_STATUS_QUEUED;
> + buf->seq = ring->last_seq++;
> +
> + return buf;
> +}
Is this a whole software buffer queue implementation? I thought the
whole point of putting the custom mem2mem framework into the capture
driver was to use the hardware FSU channel linking?
> +int imx_media_dma_buf_queue(struct imx_media_dma_buf_ring *ring, int index)
> +{
> + struct imx_media_dma_buf *buf;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + buf = __dma_buf_queue(ring, index);
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + if (IS_ERR(buf))
> + return PTR_ERR(buf);
> +
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] queued\n",
> + index, ring->src->name, ring->sink->name);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_dma_buf_queue);
> +
> +int imx_media_dma_buf_queue_from_vb(struct imx_media_dma_buf_ring *ring,
> + struct vb2_buffer *vb)
> +{
> + struct imx_media_dma_buf *buf;
> + unsigned long flags;
> + dma_addr_t phys;
> + void *virt;
> +
> + if (vb->index >= ring->num_bufs)
> + return -EINVAL;
> +
> + virt = vb2_plane_vaddr(vb, 0);
> + phys = vb2_dma_contig_plane_dma_addr(vb, 0);
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + buf = __dma_buf_queue(ring, vb->index);
> + if (IS_ERR(buf))
> + goto err_unlock;
> +
> + buf->virt = virt;
> + buf->phys = phys;
> + buf->vb = vb;
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] queued from vb\n",
> + buf->index, ring->src->name, ring->sink->name);
> +
> + return 0;
> +err_unlock:
> + spin_unlock_irqrestore(&ring->lock, flags);
> + return PTR_ERR(buf);
> +}
> +EXPORT_SYMBOL_GPL(imx_media_dma_buf_queue_from_vb);
> +
> +void imx_media_dma_buf_done(struct imx_media_dma_buf *buf,
> + enum imx_media_dma_buf_status status)
> +{
> + struct imx_media_dma_buf_ring *ring = buf->ring;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ring->lock, flags);
> + WARN_ON(buf->state != IMX_MEDIA_BUF_STATUS_ACTIVE);
> + buf->state = buf->status = status;
> + spin_unlock_irqrestore(&ring->lock, flags);
> +
> + if (buf == &ring->scratch)
> + dev_dbg(ring->imxmd->dev, "buf-scratch [%s -> %s] done\n",
> + ring->src->name, ring->sink->name);
> + else
> + dev_dbg(ring->imxmd->dev, "buf%d [%s -> %s] done\n",
> + buf->index, ring->src->name, ring->sink->name);
> +
> + /* if the sink is a subdev, inform it that new buffers are available */
> + if (is_media_entity_v4l2_subdev(ring->sink)) {
> + struct v4l2_subdev *sd =
> + media_entity_to_v4l2_subdev(ring->sink);
> + v4l2_subdev_call(sd, core, ioctl, IMX_MEDIA_NEW_DMA_BUF, NULL);
What is the purpose of this if the sink should be triggered by the FSU?
[...]
> +/*
> + * The subdevs have to be powered on/off, and streaming
> + * enabled/disabled, in a specific sequence.
> + */
> +static const u32 stream_on_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI,
> +};
> +
> +static const u32 stream_off_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_SENSOR,
> +};
> +
> +#define NUM_STREAM_ENTITIES ARRAY_SIZE(stream_on_seq)
> +
> +static const u32 power_on_seq[] = {
> + IMX_MEDIA_GRP_ID_CSI2,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PP,
> +};
> +
> +static const u32 power_off_seq[] = {
> + IMX_MEDIA_GRP_ID_IC_PP,
> + IMX_MEDIA_GRP_ID_IC_PRPVF,
> + IMX_MEDIA_GRP_ID_IC_PRPENC,
> + IMX_MEDIA_GRP_ID_SMFC,
> + IMX_MEDIA_GRP_ID_CSI,
> + IMX_MEDIA_GRP_ID_VIDMUX,
> + IMX_MEDIA_GRP_ID_SENSOR,
> + IMX_MEDIA_GRP_ID_CSI2,
> +};
This seems somewhat arbitrary. Why is a power sequence needed?
[...]
> +/*
> + * Turn current pipeline power on/off starting from start_entity.
> + * Must be called with mdev->graph_mutex held.
> + */
> +int imx_media_pipeline_set_power(struct imx_media_dev *imxmd,
> + struct media_entity_graph *graph,
> + struct media_entity *start_entity, bool on)
> +{
> + struct media_entity *entity;
> + struct v4l2_subdev *sd;
> + int i, ret = 0;
> + u32 id;
> +
> + for (i = 0; i < NUM_POWER_ENTITIES; i++) {
> + id = on ? power_on_seq[i] : power_off_seq[i];
> + entity = find_pipeline_entity(imxmd, graph, start_entity, id);
> + if (!entity)
> + continue;
> +
> + sd = media_entity_to_v4l2_subdev(entity);
> +
> + ret = v4l2_subdev_call(sd, core, s_power, on);
> + if (ret && ret != -ENOIOCTLCMD)
> + break;
> + }
> +
> + return (ret && ret != -ENOIOCTLCMD) ? ret : 0;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_pipeline_set_power);
This should really be handled by v4l2_pipeline_pm_use.
> +/*
> + * Inherit the v4l2 controls from all entities in a pipeline
> + * to the given video device.
> + * Must be called with mdev->graph_mutex held.
> + */
> +int imx_media_inherit_controls(struct imx_media_dev *imxmd,
> + struct video_device *vfd,
> + struct media_entity *start_entity)
> +{
> + struct media_entity_graph graph;
> + struct media_entity *entity;
> + struct v4l2_subdev *sd;
> + int ret;
> +
> + ret = media_entity_graph_walk_init(&graph, &imxmd->md);
> + if (ret)
> + return ret;
> +
> + media_entity_graph_walk_start(&graph, start_entity);
> +
> + while ((entity = media_entity_graph_walk_next(&graph))) {
> + if (is_media_entity_v4l2_video_device(entity))
> + continue;
> +
> + sd = media_entity_to_v4l2_subdev(entity);
> +
> + dev_dbg(imxmd->dev, "%s: adding controls from %s\n",
> + __func__, sd->name);
> +
> + ret = v4l2_ctrl_add_handler(vfd->ctrl_handler,
> + sd->ctrl_handler,
> + NULL);
> + if (ret)
> + break;
> + }
> +
> + media_entity_graph_walk_cleanup(&graph);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(imx_media_inherit_controls);
> +
> +MODULE_DESCRIPTION("i.MX5/6 v4l2 media controller driver");
> +MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
> new file mode 100644
> index 0000000..357654d
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-dev.c
This file is full of code that should live in the v4l2 core.
[...]
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-internal-sd.c
[...]
> +int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *csi[4])
> +{
> + int ret;
> +
> + /* there must be at least one CSI in first IPU */
Why?
> + if (!(csi[0] || csi[1]))
> + return -EINVAL;
> +
> + ret = add_ipu_internal_subdevs(imxmd, csi[0], csi[1], 0);
> + if (ret)
> + return ret;
> +
> + if (csi[2] || csi[3])
> + ret = add_ipu_internal_subdevs(imxmd, csi[2], csi[3], 1);
> +
> + return ret;
> +}
> diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
> new file mode 100644
> index 0000000..a939c34
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-media-of.c
> @@ -0,0 +1,289 @@
> +/*
> + * Media driver for Freescale i.MX5/6 SOC
> + *
> + * Open Firmware parsing.
> + *
> + * Copyright (c) 2016 Mentor Graphics Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/of_platform.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <video/imx-ipu-v3.h>
> +#include "imx-media.h"
> +
> +static int of_add_pad_link(struct imx_media_dev *imxmd,
> + struct imx_media_pad *pad,
> + struct device_node *local_sd_node,
> + struct device_node *remote_sd_node,
> + int local_pad, int remote_pad)
> +{
> + dev_dbg(imxmd->dev, "%s: adding %s:%d -> %s:%d\n", __func__,
> + local_sd_node->name, local_pad,
> + remote_sd_node->name, remote_pad);
> +
> + return imx_media_add_pad_link(imxmd, pad, remote_sd_node, NULL,
> + local_pad, remote_pad);
> +}
> +
> +/* parse inputs property from a sensor node */
> +static void of_parse_sensor_inputs(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *sensor,
> + struct device_node *sensor_np)
> +{
> + struct imx_media_sensor_input *sinput = &sensor->input;
> + int ret, i;
> +
> + for (i = 0; i < IMX_MEDIA_MAX_SENSOR_INPUTS; i++) {
> + const char *input_name;
> + u32 val;
> +
> + ret = of_property_read_u32_index(sensor_np, "inputs", i, &val);
> + if (ret)
> + break;
> +
> + sinput->value[i] = val;
> +
> + ret = of_property_read_string_index(sensor_np, "input-names",
> + i, &input_name);
> + /*
> + * if input-names not provided, they will be set using
> + * the subdev name once the sensor is known during
> + * async bind
> + */
> + if (!ret)
> + strncpy(sinput->name[i], input_name,
> + sizeof(sinput->name[i]));
> + }
> +
> + sinput->num = i;
> +
> + /* if no inputs provided just assume a single input */
> + if (sinput->num == 0)
> + sinput->num = 1;
> +}
This should be parsed by the sensor driver, not imx-media.
> +static void of_parse_sensor(struct imx_media_dev *imxmd,
> + struct imx_media_subdev *sensor,
> + struct device_node *sensor_np)
> +{
> + struct device_node *endpoint;
> +
> + of_parse_sensor_inputs(imxmd, sensor, sensor_np);
> +
> + endpoint = of_graph_get_next_endpoint(sensor_np, NULL);
> + if (endpoint) {
> + v4l2_of_parse_endpoint(endpoint, &sensor->sensor_ep);
> + of_node_put(endpoint);
> + }
> +}
> +
> +static int of_get_port_count(const struct device_node *np)
> +{
> + struct device_node *child;
> + int num = 0;
> +
> + /* if this node is itself a port, return 1 */
> + if (of_node_cmp(np->name, "port") == 0)
> + return 1;
> +
> + for_each_child_of_node(np, child)
> + if (of_node_cmp(child->name, "port") == 0)
> + num++;
> +
> + return num;
> +}
If this is extended to handle the ports subnode properly, it could be
moved into drivers/of/base.c.
regards
Philipp
^ permalink raw reply
* [GIT PULL 1/4] ARM: exynos: Mach/soc for v4.11
From: Krzysztof Kozlowski @ 2017-01-13 15:20 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Mostly cleanups for v4.11.
Best regards,
Krzysztof
The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:
Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-soc-4.11
for you to fetch changes up to cda1a52dab50340728e46601e6c9da9fc4beaf1f:
ARM: s3c64xx: Constify wake_irqs (2016-12-29 15:41:44 +0200)
----------------------------------------------------------------
Samsung mach/soc update for v4.11. Mostly cleanups:
1. Removal of unused platform data in S3C24XX and S3C64xx as follow up of
conversion to new DMA channel request API.
2. Adding const and __ro_after_init to various data in Samsung platforms.
----------------------------------------------------------------
Krzysztof Kozlowski (7):
ARM: EXYNOS: Constify list of retention registers
ARM: EXYNOS: Annotate iomem and pm_data pointers __ro_after_init
ARM: s3c24xx: Constify few integer tables
ARM: s3c64xx: Annotate external clock frequencies __ro_after_init
ARM: SAMSUNG: Constify array of wake irqs passed to samsung_sync_wakemask
ARM: s3c24xx: Constify wake_irqs
ARM: s3c64xx: Constify wake_irqs
Sylwester Nawrocki (2):
ARM: s3c64xx: Drop initialization of unused struct s3c_audio_pdata fields
ARM: s3c24xx: Drop unused struct s3c_audio_pdata entries
arch/arm/mach-exynos/exynos.c | 4 ++--
arch/arm/mach-exynos/mcpm-exynos.c | 2 +-
arch/arm/mach-exynos/suspend.c | 10 +++++-----
arch/arm/mach-s3c24xx/bast-irq.c | 4 ++--
arch/arm/mach-s3c24xx/iotiming-s3c2410.c | 2 +-
arch/arm/mach-s3c24xx/pm-s3c2412.c | 2 +-
arch/arm/mach-s3c64xx/common.c | 3 ++-
arch/arm/mach-s3c64xx/dev-audio.c | 19 -------------------
arch/arm/mach-s3c64xx/pm.c | 2 +-
arch/arm/plat-samsung/devs.c | 19 -------------------
arch/arm/plat-samsung/include/plat/wakeup-mask.h | 2 +-
arch/arm/plat-samsung/wakeup-mask.c | 2 +-
12 files changed, 17 insertions(+), 54 deletions(-)
^ permalink raw reply
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