Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: imx: mmdc perf function support i.MX6QP
From: Frank Li @ 2016-10-25 21:26 UTC (permalink / raw)
  To: linux-arm-kernel

i.MX6QP added new reigster bit PROFILE_SEL in MADPCR0.
need set it at perf start.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 arch/arm/mach-imx/mmdc.c | 45 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index d82d14c..d833b87 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -44,6 +44,7 @@
 #define DBG_RST			0x2
 #define PRF_FRZ			0x4
 #define CYC_OVF			0x8
+#define PROFILE_SEL		0x10
 
 #define MMDC_MADPCR0	0x410
 #define MMDC_MADPSR0	0x418
@@ -55,10 +56,36 @@
 
 #define MMDC_NUM_COUNTERS	6
 
+#define FSL_MMDC_QUIRK_PROFILE_SEL	0x1
+
 #define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
 
 static int ddr_type;
 
+enum fsl_mmdc_devtype {
+	FSL_MMDC_IMX6Q,
+	FSL_MMDC_IMX6QP,
+};
+
+struct fsl_mmdc_devtype_data {
+	enum fsl_mmdc_devtype devtype;
+	int driver_data;
+};
+
+static struct fsl_mmdc_devtype_data imx6q_data = {
+	.devtype = FSL_MMDC_IMX6Q,
+};
+
+static struct fsl_mmdc_devtype_data imx6qp_data = {
+	.driver_data = FSL_MMDC_QUIRK_PROFILE_SEL,
+};
+
+static const struct of_device_id imx_mmdc_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-mmdc", .data = (void *)&imx6q_data},
+	{ .compatible = "fsl,imx6qp-mmdc", .data = (void *)&imx6qp_data},
+	{ /* sentinel */ }
+};
+
 #ifdef CONFIG_PERF_EVENTS
 
 static DEFINE_IDA(mmdc_ida);
@@ -83,6 +110,7 @@ struct mmdc_pmu {
 	struct device *dev;
 	struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
 	struct hlist_node node;
+	struct fsl_mmdc_devtype_data *devtype_data;
 };
 
 /*
@@ -307,6 +335,7 @@ static void mmdc_pmu_event_start(struct perf_event *event, int flags)
 	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 	void __iomem *mmdc_base, *reg;
+	int val;
 
 	mmdc_base = pmu_mmdc->mmdc_base;
 	reg = mmdc_base + MMDC_MADPCR0;
@@ -321,7 +350,12 @@ static void mmdc_pmu_event_start(struct perf_event *event, int flags)
 	local64_set(&hwc->prev_count, 0);
 
 	writel(DBG_RST, reg);
-	writel(DBG_EN, reg);
+
+	val = DBG_EN;
+	if (pmu_mmdc->devtype_data->driver_data & FSL_MMDC_QUIRK_PROFILE_SEL)
+		val |= PROFILE_SEL;
+
+	writel(val, reg);
 }
 
 static int mmdc_pmu_event_add(struct perf_event *event, int flags)
@@ -436,6 +470,8 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 	char *name;
 	int mmdc_num;
 	int ret;
+	const struct of_device_id *of_id =
+		of_match_device(imx_mmdc_dt_ids, &pdev->dev);
 
 	pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
 	if (!pmu_mmdc) {
@@ -450,6 +486,8 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 		name = devm_kasprintf(&pdev->dev,
 				GFP_KERNEL, "mmdc%d", mmdc_num);
 
+	pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
+
 	hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
 			HRTIMER_MODE_REL);
 	pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler;
@@ -524,11 +562,6 @@ int imx_mmdc_get_ddr_type(void)
 	return ddr_type;
 }
 
-static const struct of_device_id imx_mmdc_dt_ids[] = {
-	{ .compatible = "fsl,imx6q-mmdc", },
-	{ /* sentinel */ }
-};
-
 static struct platform_driver imx_mmdc_driver = {
 	.driver		= {
 		.name	= "imx-mmdc",
-- 
2.5.2

^ permalink raw reply related

* [PATCH 5/5] ARM: dts: imx6qdl-nitrogen6x: add missing USB PHY reset control
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025211955.5345-1-gary.bisson@boundarydevices.com>

Declared as a regulator since the driver doesn't have a reset-gpios
property for this.

This ensures that the PHY is woken up, not depending on the state the
second stage bootloader leaves the pin.

Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index c7016b2..d471ced 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -108,6 +108,19 @@
 			startup-delay-us = <70000>;
 			enable-active-high;
 		};
+
+		reg_usb_h1_vbus: regulator at 5 {
+			compatible = "regulator-fixed";
+			reg = <5>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usbh1>;
+			regulator-name = "usb_h1_vbus";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			regulator-always-on;
+		};
 	};
 
 	gpio-keys {
@@ -516,6 +529,12 @@
 			>;
 		};
 
+		pinctrl_usbh1: usbh1grp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x030b0
+			>;
+		};
+
 		pinctrl_usbotg: usbotggrp {
 			fsl,pins = <
 				MX6QDL_PAD_GPIO_1__USB_OTG_ID	0x17059
@@ -633,6 +652,7 @@
 };
 
 &usbh1 {
+	vbus-supply = <&reg_usb_h1_vbus>;
 	status = "okay";
 };
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 4/5] ARM: dts: imx6qdl-nitrogen6x: rename panel nodes
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025211955.5345-1-gary.bisson@boundarydevices.com>

So it is in line with other Boundary Device device tree (nit6xlite
and nitrogen6_max).

Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index db868bc..c7016b2 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -211,7 +211,7 @@
 		};
 	};
 
-	lcd_panel {
+	panel_lcd {
 		compatible = "okaya,rs800480t-7x0gp";
 		backlight = <&backlight_lcd>;
 
@@ -222,7 +222,7 @@
 		};
 	};
 
-	panel {
+	panel_lvds0 {
 		compatible = "hannstar,hsd100pxn1";
 		backlight = <&backlight_lvds>;
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 3/5] ARM: dts: imx6qdl-sabrelite: add missing USB PHY reset control
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025211955.5345-1-gary.bisson@boundarydevices.com>

Declared as a regulator since the driver doesn't have a reset-gpios
property for this.

This ensures that the PHY is woken up, not depending on the state the
second stage bootloader leaves the pin.

Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index cebea8a..bf00267 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -94,6 +94,19 @@
 			pinctrl-0 = <&pinctrl_can_xcvr>;
 			gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
 		};
+
+		reg_usb_h1_vbus: regulator at 4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usbh1>;
+			regulator-name = "usb_h1_vbus";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			regulator-always-on;
+		};
 	};
 
 	gpio-keys {
@@ -481,6 +494,12 @@
 			>;
 		};
 
+		pinctrl_usbh1: usbh1grp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x030b0
+			>;
+		};
+
 		pinctrl_usbotg: usbotggrp {
 			fsl,pins = <
 				MX6QDL_PAD_GPIO_1__USB_OTG_ID		0x17059
@@ -578,6 +597,7 @@
 };
 
 &usbh1 {
+	vbus-supply = <&reg_usb_h1_vbus>;
 	status = "okay";
 };
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 2/5] ARM: dts: imx6qdl-sabrelite: rename panel nodes
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025211955.5345-1-gary.bisson@boundarydevices.com>

So it is in line with other Boundary Device device tree (nit6xlite
and nitrogen6_max).

Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 81dd6cd..cebea8a 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -197,7 +197,7 @@
 		};
 	};
 
-	lcd_panel {
+	panel_lcd {
 		compatible = "okaya,rs800480t-7x0gp";
 		backlight = <&backlight_lcd>;
 
@@ -208,7 +208,7 @@
 		};
 	};
 
-	panel {
+	panel_lvds0 {
 		compatible = "hannstar,hsd100pxn1";
 		backlight = <&backlight_lvds>;
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/5] ARM: dts: imx: add Boundary Devices Nitrogen6_SOM2 support
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025211955.5345-1-gary.bisson@boundarydevices.com>

SoM based on i.MX6 Quad with 1GB of DDR3.

https://boundarydevices.com/product/nit6x-som-v2/

Signed-off-by: Gary Bisson <gary.bisson@boundarydevices.com>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/imx6q-nitrogen6_som2.dts    |  53 ++
 arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi | 770 ++++++++++++++++++++++++++
 3 files changed, 824 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 191807c..5647cc1 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -386,6 +386,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6q-marsboard.dtb \
 	imx6q-nitrogen6x.dtb \
 	imx6q-nitrogen6_max.dtb \
+	imx6q-nitrogen6_som2.dtb \
 	imx6q-novena.dtb \
 	imx6q-phytec-pbab01.dtb \
 	imx6q-rex-pro.dtb \
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts b/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
new file mode 100644
index 0000000..cf4feef
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Boundary Devices, Inc.
+ *
+ * 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
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     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-nitrogen6_som2.dtsi"
+
+/ {
+	model = "Boundary Devices i.MX6 Quad Nitrogen6_SOM2 Board";
+	compatible = "boundary,imx6q-nitrogen6_som2", "fsl,imx6q";
+};
+
+&sata {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
new file mode 100644
index 0000000..76f9b2a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2016 Boundary Devices, Inc.
+ *
+ * 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
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     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.
+ */
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	memory {
+		reg = <0x10000000 0x40000000>;
+	};
+
+	backlight_lcd: backlight_lcd {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <7>;
+		power-supply = <&reg_3p3v>;
+		status = "okay";
+	};
+
+	backlight_lvds0: backlight_lvds0 {
+		compatible = "pwm-backlight";
+		pwms = <&pwm4 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <7>;
+		power-supply = <&reg_3p3v>;
+		status = "okay";
+	};
+
+	backlight_lvds1: backlight_lvds1 {
+		compatible = "gpio-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight_lvds1>;
+		gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+		default-on;
+		status = "okay";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		power {
+			label = "Power Button";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+
+		menu {
+			label = "Menu";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MENU>;
+		};
+
+		home {
+			label = "Home";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_HOME>;
+		};
+
+		back {
+			label = "Back";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_BACK>;
+		};
+
+		volume-up {
+			label = "Volume Up";
+			gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		volume-down {
+			label = "Volume Down";
+			gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+
+	lcd_display: display at di0 {
+		compatible = "fsl,imx-parallel-display";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interface-pix-fmt = "bgr666";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_j15>;
+		status = "okay";
+
+		port at 0 {
+			reg = <0>;
+
+			lcd_display_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			lcd_display_out: endpoint {
+				remote-endpoint = <&lcd_panel_in>;
+			};
+		};
+	};
+
+	panel_lcd {
+		compatible = "okaya,rs800480t-7x0gp";
+		backlight = <&backlight_lcd>;
+
+		port {
+			lcd_panel_in: endpoint {
+				remote-endpoint = <&lcd_display_out>;
+			};
+		};
+	};
+
+	panel_lvds0 {
+		compatible = "hannstar,hsd100pxn1";
+		backlight = <&backlight_lvds0>;
+
+		port {
+			panel_in_lvds0: endpoint {
+				remote-endpoint = <&lvds0_out>;
+			};
+		};
+	};
+
+	panel_lvds1 {
+		compatible = "hannstar,hsd100pxn1";
+		backlight = <&backlight_lvds1>;
+
+		port {
+			panel_in_lvds1: endpoint {
+				remote-endpoint = <&lvds1_out>;
+			};
+		};
+	};
+
+	reg_1p8v: regulator-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "1P8V";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	reg_2p5v: regulator-2v5 {
+		compatible = "regulator-fixed";
+		regulator-name = "2P5V";
+		regulator-min-microvolt = <2500000>;
+		regulator-max-microvolt = <2500000>;
+		regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3P3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	reg_can_xcvr: regulator-can-xcvr {
+		compatible = "regulator-fixed";
+		regulator-name = "CAN XCVR";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can_xcvr>;
+		gpio = <&gpio1 2 GPIO_ACTIVE_LOW>;
+	};
+
+	reg_usb_h1_vbus: regulator-usb-h1-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbh1>;
+		regulator-name = "usb_h1_vbus";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	reg_usb_otg_vbus: regulator-usb-otg-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	reg_wlan_vmmc: regulator-wlan-vmmc {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wlan_vmmc>;
+		regulator-name = "reg_wlan_vmmc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+		startup-delay-us = <70000>;
+		enable-active-high;
+	};
+
+	sound {
+		compatible = "fsl,imx6q-nitrogen6_som2-sgtl5000",
+			     "fsl,imx-audio-sgtl5000";
+		model = "imx6q-nitrogen6_som2-sgtl5000";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_sgtl5000>;
+		ssi-controller = <&ssi1>;
+		audio-codec = <&codec>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <1>;
+		mux-ext-port = <3>;
+	};
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	status = "okay";
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1>;
+	xceiver-supply = <&reg_can_xcvr>;
+	status = "okay";
+};
+
+&clks {
+	assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+			  <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+	assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>,
+				 <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
+};
+
+&ecspi1 {
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	status = "okay";
+
+	flash: m25p80 at 0 {
+		compatible = "microchip,sst25vf016b";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-mode = "rgmii";
+	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+	fsl,err006687-workaround-present;
+	status = "okay";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	codec: sgtl5000 at 0a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		VDDA-supply = <&reg_2p5v>;
+		VDDIO-supply = <&reg_3p3v>;
+	};
+
+	rtc at 68 {
+		compatible = "st,rv4162";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rv4162>;
+		reg = <0x68>;
+		interrupts-extended = <&gpio6 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+};
+
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	touchscreen at 04 {
+		compatible = "eeti,egalax_ts";
+		reg = <0x04>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+	};
+
+	touchscreen at 38 {
+		compatible = "edt,edt-ft5x06";
+		reg = <0x38>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&iomuxc {
+	pinctrl_audmux: audmuxgrp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
+			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
+			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
+			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+		>;
+	};
+
+	pinctrl_backlight_lvds1: backlight-lvds1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_EB3__GPIO2_IO31		0x0b0b0
+		>;
+	};
+
+	pinctrl_can1: can1grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX	0x1b0b0
+			MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX	0x1b0b0
+		>;
+	};
+
+	pinctrl_can_xcvr: can-xcvrgrp {
+		fsl,pins = <
+			/* Flexcan XCVR enable */
+			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x0b0b0
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__ECSPI1_MISO		0x100b1
+			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI		0x100b1
+			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK		0x100b1
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19		0x000b1
+		>;
+	};
+
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x130b0
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x130b0
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x130b0
+			MX6QDL_PAD_ENET_RXD0__GPIO1_IO27	0x030b0
+			MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28	0x1b0b0
+			MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
+		>;
+	};
+
+	pinctrl_gpio_keys: gpio_keysgrp {
+		fsl,pins = <
+			/* Power Button */
+			MX6QDL_PAD_NANDF_D3__GPIO2_IO03		0x1b0b0
+			/* Menu Button */
+			MX6QDL_PAD_NANDF_D1__GPIO2_IO01		0x1b0b0
+			/* Home Button */
+			MX6QDL_PAD_NANDF_D4__GPIO2_IO04		0x1b0b0
+			/* Back Button */
+			MX6QDL_PAD_NANDF_D2__GPIO2_IO02		0x1b0b0
+			/* Volume Up Button */
+			MX6QDL_PAD_GPIO_18__GPIO7_IO13		0x1b0b0
+			/* Volume Down Button */
+			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01		0x1b0b0
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D21__I2C1_SCL	0x4001b8b1
+			MX6QDL_PAD_EIM_D28__I2C1_SDA	0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL	0x4001b8b1
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA	0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_5__I2C3_SCL	0x4001b8b1
+			MX6QDL_PAD_GPIO_16__I2C3_SDA	0x4001b8b1
+			MX6QDL_PAD_GPIO_9__GPIO1_IO09	0x1b0b0
+		>;
+	};
+
+	pinctrl_i2c3mux: i2c3muxgrp {
+		fsl,pins = <
+			/* PCIe I2C enable */
+			MX6QDL_PAD_EIM_OE__GPIO2_IO25	0x000b0
+		>;
+	};
+
+	pinctrl_j15: j15grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
+		>;
+	};
+
+	pinctrl_pcie: pciegrp {
+		fsl,pins = <
+			/* PCIe reset */
+			MX6QDL_PAD_EIM_BCLK__GPIO6_IO31	0x030b0
+			MX6QDL_PAD_EIM_DA4__GPIO3_IO04	0x030b0
+		>;
+	};
+
+	pinctrl_pwm1: pwm1grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT3__PWM1_OUT	0x030b1
+		>;
+	};
+
+	pinctrl_pwm3: pwm3grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT1__PWM3_OUT	0x030b1
+		>;
+	};
+
+	pinctrl_pwm4: pwm4grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_CMD__PWM4_OUT	0x030b1
+		>;
+	};
+
+	pinctrl_rv4162: rv4162grp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CLE__GPIO6_IO07	0x1b0b0
+		>;
+	};
+
+	pinctrl_sgtl5000: sgtl5000grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_0__CCM_CLKO1		0x000b0
+			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x130b0
+			MX6QDL_PAD_EIM_DA2__GPIO3_IO02		0x130b0
+			MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24	0x130b0
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA	0x1b0b1
+			MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__UART2_TX_DATA	0x1b0b1
+			MX6QDL_PAD_EIM_D27__UART2_RX_DATA	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D24__UART3_TX_DATA	0x1b0b1
+			MX6QDL_PAD_EIM_D25__UART3_RX_DATA	0x1b0b1
+			MX6QDL_PAD_EIM_D23__UART3_CTS_B		0x1b0b1
+			MX6QDL_PAD_EIM_D31__UART3_RTS_B		0x1b0b1
+		>;
+	};
+
+	pinctrl_usbh1: usbh1grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x030b0
+		>;
+	};
+
+	pinctrl_usbotg: usbotggrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_1__USB_OTG_ID		0x17059
+			MX6QDL_PAD_KEY_COL4__USB_OTG_OC		0x1b0b0
+			/* power enable, high active */
+			MX6QDL_PAD_EIM_D22__GPIO3_IO22		0x030b0
+		>;
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10071
+			MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17071
+			MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17071
+			MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17071
+			MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17071
+			MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17071
+		>;
+	};
+
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_CLK__SD3_CLK		0x10071
+			MX6QDL_PAD_SD3_CMD__SD3_CMD		0x17071
+			MX6QDL_PAD_SD3_DAT0__SD3_DATA0		0x17071
+			MX6QDL_PAD_SD3_DAT1__SD3_DATA1		0x17071
+			MX6QDL_PAD_SD3_DAT2__SD3_DATA2		0x17071
+			MX6QDL_PAD_SD3_DAT3__SD3_DATA3		0x17071
+			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00		0x1b0b0
+		>;
+	};
+
+	pinctrl_usdhc4: usdhc4grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
+			MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+			MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
+			MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
+			MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
+			MX6QDL_PAD_SD4_DAT3__SD4_DATA3		0x17059
+			MX6QDL_PAD_SD4_DAT4__SD4_DATA4		0x17059
+			MX6QDL_PAD_SD4_DAT5__SD4_DATA5		0x17059
+			MX6QDL_PAD_SD4_DAT6__SD4_DATA6		0x17059
+			MX6QDL_PAD_SD4_DAT7__SD4_DATA7		0x17059
+		>;
+	};
+
+	pinctrl_wlan_vmmc: wlan_vmmcgrp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x100b0
+			MX6QDL_PAD_NANDF_CS2__GPIO6_IO15	0x030b0
+			MX6QDL_PAD_NANDF_CS3__GPIO6_IO16	0x030b0
+			MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT	0x000b0
+		>;
+	};
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
+&ldb {
+	status = "okay";
+
+	lvds-channel at 0 {
+		fsl,data-mapping = "spwg";
+		fsl,data-width = <18>;
+		status = "okay";
+
+		port at 4 {
+			reg = <4>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_in_lvds0>;
+			};
+		};
+	};
+
+	lvds-channel at 1 {
+		fsl,data-mapping = "spwg";
+		fsl,data-width = <18>;
+		status = "okay";
+
+		port at 4 {
+			reg = <4>;
+
+			lvds1_out: endpoint {
+				remote-endpoint = <&panel_in_lvds1>;
+			};
+		};
+	};
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+	reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3>;
+	status = "okay";
+};
+
+&pwm4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm4>;
+	status = "okay";
+};
+
+&ssi1 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&usbh1 {
+	vbus-supply = <&reg_usb_h1_vbus>;
+	status = "okay";
+};
+
+&usbotg {
+	vbus-supply = <&reg_usb_otg_vbus>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	disable-over-current;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	bus-width = <4>;
+	non-removable;
+	vmmc-supply = <&reg_wlan_vmmc>;
+	cap-power-off-card;
+	keep-power-in-suspend;
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wlcore: wlcore at 2 {
+		compatible = "ti,wl1271";
+		reg = <2>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+		ref-clock-frequency = <38400000>;
+	};
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	vmmc-supply = <&reg_3p3v>;
+	status = "okay";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	non-removable;
+	vmmc-supply = <&reg_1p8v>;
+	keep-power-in-suspend;
+	status = "okay";
+};
-- 
2.9.3

^ permalink raw reply related

* [PATCH 0/5] ARM: dts: imx: update Boundary Devices boards support
From: Gary Bisson @ 2016-10-25 21:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

This series includes several patches to update the support for our platforms.

Here are the main goals of this series:
1- Adding support for our latest SOM (SOM2)
2- Fix panel naming consistency across the boards
  -> This way our U-Boot bootscript[1] can easily set the panel compatible.
3- Fix USB PHY reset for some boards
  -> U-Boot used to always set the reset pin whether usb was used or not.
     Anyway, the kernel should not be dependent on the bootloader.

Let me know if you have any question.

Regards,
Gary

[1] https://github.com/boundarydevices/u-boot-imx6/blob/boundary-v2016.03/board/boundary/nitrogen6x/6x_bootscript-mainline.txt

Gary Bisson (5):
  ARM: dts: imx: add Boundary Devices Nitrogen6_SOM2 support
  ARM: dts: imx6qdl-sabrelite: rename panel nodes
  ARM: dts: imx6qdl-sabrelite: add missing USB PHY reset control
  ARM: dts: imx6qdl-nitrogen6x: rename panel nodes
  ARM: dts: imx6qdl-nitrogen6x: add missing USB PHY reset control

 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/imx6q-nitrogen6_som2.dts    |  53 ++
 arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi | 770 ++++++++++++++++++++++++++
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi     |  24 +-
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi      |  24 +-
 5 files changed, 868 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi

-- 
2.9.3

^ permalink raw reply

* [PATCH V5 1/2] ACPI: Add support for ResourceSource/IRQ domain mapping
From: agustinv at codeaurora.org @ 2016-10-25 20:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4506c0f4-165a-e84b-73e2-d3cca9c8b9d7@arm.com>

Hi Marc, Lorenzo,

On 2016-10-20 13:51, Marc Zyngier wrote:
> On 20/10/16 17:48, Lorenzo Pieralisi wrote:
>> Hi Agustin,
>> 
>> On Tue, Oct 18, 2016 at 01:41:48PM -0400, Agustin Vega-Frias wrote:
>>> This allows irqchip drivers to associate an ACPI DSDT device to
>>> an IRQ domain and provides support for using the ResourceSource
>>> in Extended IRQ Resources to find the domain and map the IRQs
>>> specified on that domain.
>>> 
>>> Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
>>> ---
>>>  drivers/acpi/Makefile             |   1 +
>>>  drivers/acpi/irqdomain.c          | 141 
>>> ++++++++++++++++++++++++++++++++++++++
>>>  drivers/acpi/resource.c           |  21 +++---
>>>  include/asm-generic/vmlinux.lds.h |   1 +
>>>  include/linux/acpi.h              |  71 +++++++++++++++++++
>>>  include/linux/irqchip.h           |  17 ++++-
>>>  6 files changed, 240 insertions(+), 12 deletions(-)
>>>  create mode 100644 drivers/acpi/irqdomain.c
>>> 
>>> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
>>> index 9ed0878..880401b 100644
>>> --- a/drivers/acpi/Makefile
>>> +++ b/drivers/acpi/Makefile
>>> @@ -57,6 +57,7 @@ acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
>>>  acpi-y				+= acpi_lpat.o
>>>  acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o
>>>  acpi-$(CONFIG_ACPI_WATCHDOG)	+= acpi_watchdog.o
>>> +acpi-$(CONFIG_IRQ_DOMAIN)	+= irqdomain.o
>>> 
>>>  # These are (potentially) separate modules
>>> 
>>> diff --git a/drivers/acpi/irqdomain.c b/drivers/acpi/irqdomain.c
>>> new file mode 100644
>>> index 0000000..c53b9f4
>>> --- /dev/null
>>> +++ b/drivers/acpi/irqdomain.c
>>> @@ -0,0 +1,141 @@
>>> +/*
>>> + * ACPI ResourceSource/IRQ domain mapping support
>>> + *
>>> + * Copyright (c) 2016, The Linux Foundation. All rights reserved.
>>> + *
>>> + * This program is free software; you can redistribute it and/or 
>>> modify
>>> + * it under the terms of the GNU General Public License version 2 
>>> and
>>> + * only version 2 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + */
>>> +#include <linux/acpi.h>
>>> +#include <linux/irq.h>
>>> +#include <linux/irqdomain.h>
>>> +
>>> +/**
>>> + * acpi_irq_domain_ensure_probed() - Check if the device has 
>>> registered
>>> + *                                   an IRQ domain and probe as 
>>> necessary
>>> + *
>>> + * @device: Device to check and probe
>>> + *
>>> + * Returns: 0 on success, -ENODEV otherwise
>> 
>> This is not correct (ie it depends on what
>> 
>> struct acpi_dsdt_probe_entry.probe
>> 
>> returns) and I would like to take this nit as an opportunity
>> to take a step back and ask you a question below.
>> 
>>> + */
>>> +static int acpi_irq_domain_ensure_probed(struct acpi_device *device)
>>> +{
>>> +	struct acpi_dsdt_probe_entry *entry;
>>> +
>>> +	if (irq_find_matching_fwnode(&device->fwnode, DOMAIN_BUS_ANY) != 0)
>>> +		return 0;
>>> +
>>> +	for (entry = &__dsdt_acpi_probe_table;
>>> +	     entry < &__dsdt_acpi_probe_table_end; entry++)
>>> +		if (strcmp(entry->_hid, acpi_device_hid(device)) == 0)
>>> +			return entry->probe(device);
>> 
>> Through this approch we are forcing an irqchip (that by the way it
>> has a physical node ACPI companion by being a DSDT device object so it
>> could be managed by a platform driver) to be probed. The question is: 
>> is
>> there a reason (apart from the current ACPI resource parsing API) why
>> this can't be implemented through deferred probing and the device
>> dependencies framework Rafael is working on:
>> 
>> http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1246897.html
>> 
>> The DT layer, through the of_irq_get() API, supports probe deferral
>> and what I am asking you is if there is any blocking point (again,
>> apart from the current ACPI API) to implement the same mechanism.
>> 
>> I have not reviewed the previous versions so I am certainly missing
>> some of the bits and pieces already discussed, apologies for that.
> 
> Also, this function scares me to no end: lack of locking and recursion
> are the main things that worry me. My vote would be to implement
> something based on Rafael's approach (which conveniently solves all 
> kind
> of other issues).
> 

I have looked at the latest version of Rafael's patchset for device 
functional
dependency tracking and in its current form it does not address the 
issues
we see with dependencies on irqchips under ACPI boot.

The problem is that the conversion of ACPI IRQ resources to Linux IRQ 
resources
for most DSDT devices occurs before the device is even added and is not 
retried
when a device is re-probed after returning -EPROBE_DEFER. The call chain 
in most
cases is:

     acpi_init()
         acpi_scan_init()
             acpi_bus_scan()
                 acpi_bus_attach()
                     acpi_default_enumeration()
                         acpi_create_platform_device()
                             acpi_dev_get_resources() /* Resources are 
converted here */
                             platform_device_register_full()
                                 platform_device_add()
                                     device_add()

What I would like to propose, and I would like feedback before I go down 
that road,
is to handle this in a way similar to DT, meaning that instead of doing 
on demand
probing of the irqchip devices described in the DSDT probe table I 
introduce, we do
that in an init function (e.g. acpi_bus_init_irq).

Thoughts?

Thanks.

> I'll review this patch series in a more in-depth way soon, but I wanted
> to chime in and add my own weight to Lorenzo's proposal.
> 
> Thanks,
> 
> 	M.
> --
> Jazz is not dead. It just smells funny...

-- 
Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm 
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a 
Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH 3/4] dt-bindings: Update domain-idle-state binding to use correct compatibles
From: Kevin Hilman @ 2016-10-25 20:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477409199-52182-4-git-send-email-lina.iyer@linaro.org>

Lina Iyer <lina.iyer@linaro.org> writes:

> Update domain-idle-state binding to use "domain-idle-state" compatible
> from Documentation/devicetree/bindings/arm/idle-states.txt.
>
> Cc: <devicetree@vger.kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
>  Documentation/devicetree/bindings/power/power_domain.txt | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)

With no current users for this, I don't see the point of adding a
compatible now.

IMO, this should wait and be added with the identified user we can
discuss it then.

Kevin

^ permalink raw reply

* [PATCH v2 0/4] ARM: imx31: clock initialization fixes
From: Stephen Boyd @ 2016-10-25 20:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161023122844.GR30578@tiger>

On 10/23, Shawn Guo wrote:
> On Mon, Sep 26, 2016 at 03:03:39AM +0300, Vladimir Zapolskiy wrote:
> > The change is tested on qemu kzm target and mx31lite board, while both
> > targets don't have DTS in upstream, I had to write simple DTS files for
> > them, because the proposed change is for i.MX31 targets with OF support.
> > 
> > i.MX31/OF/clock initialization seems to be broken currently, if
> > the series is not applied I can not get a working clock source during
> > early boot stage on a board with DTB supplied.
> > 
> > Changes from v1 to v2, thanks to Uwe and Stephen for review:
> > * added one more new fix in imx31.dtsi which moves CCM device node
> >   to AIPS2 bus,
> > * included to the series a fix of CCM interrupts in imx31.dtsi,
> >   the change was sent as a separate patch, the change is included
> >   to avoid a patch application dependency,
> > * as suggested by Uwe reworded one of the commits removing "stack
> >   corruption" mentioning, the overwritten value is passed in a register,
> > * as suggested by Uwe squashed clk-imx31.c and imx31-dt.c changes
> >   to avoid a runtime problem if only one of two patches are applied
> > 
> > Vladimir Zapolskiy (4):
> >   ARM: dts: imx31: fix clock control module interrupts description
> >   ARM: dts: imx31: move CCM device node to AIPS2 bus devices
> >   clk: imx31: fix rewritten input argument of mx31_clocks_init()
> >   ARM: clk: imx31: properly init clocks for machines with DT
> > 
> >  .../devicetree/bindings/clock/imx31-clock.txt      |  2 +-
> >  arch/arm/boot/dts/imx31.dtsi                       | 14 +++---
> >  arch/arm/mach-imx/common.h                         |  1 -
> >  arch/arm/mach-imx/imx31-dt.c                       |  6 ---
> >  drivers/clk/imx/clk-imx31.c                        | 52 +++++++++++-----------
> 
> Hi Stephen,
> 
> Can I have you ACK on the clk file, so that we can merge the series from
> arm-soc tree?  Thanks.
> 

Done.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH v2 4/4] ARM: clk: imx31: properly init clocks for machines with DT
From: Stephen Boyd @ 2016-10-25 20:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474848223-19728-5-git-send-email-vz@mleia.com>

On 09/26, Vladimir Zapolskiy wrote:
> Clock initialization for i.MX31 powered machines with DT support
> should be done by a call of an init function registered with
> CLK_OF_DECLARE() in common clock framework.
> 
> The change converts exported mx31_clocks_init_dt() into a static
> initialization function registered by CLK_OF_DECLARE().
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---

Acked-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH v2 3/4] clk: imx31: fix rewritten input argument of mx31_clocks_init()
From: Stephen Boyd @ 2016-10-25 20:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474848223-19728-4-git-send-email-vz@mleia.com>

On 09/26, Vladimir Zapolskiy wrote:
> Function mx31_clocks_init() is called during clock intialization on
> legacy boards with reference clock frequency passed as its input
> argument, this can be verified by examination of the function
> declaration found in arch/arm/mach-imx/common.h and actual function
> users which include that header file.
> 
> Inside CCF driver the function ignores its input argument, by chance
> the used value in the function body is the same as input arguments on
> side of all callers.
> 
> Fixes: d9388c843237 ("clk: imx31: Do not call mxc_timer_init twice when booting with DT")
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---

Acked-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [RFC v2] ARM: memory: da8xx-ddrctl: new driver
From: Kevin Hilman @ 2016-10-25 20:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7hy41ctipa.fsf@baylibre.com>

Kevin Hilman <khilman@baylibre.com> writes:

> Bartosz Golaszewski <bgolaszewski@baylibre.com> writes:
>
>> Create a new driver for the da8xx DDR2/mDDR controller and implement
>> support for writing to the Peripheral Bus Burst Priority Register.
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>>  .../memory-controllers/ti-da8xx-ddrctl.txt         |  20 +++
>>  drivers/memory/Kconfig                             |   8 +
>>  drivers/memory/Makefile                            |   1 +
>>  drivers/memory/da8xx-ddrctl.c                      | 175 +++++++++++++++++++++
>>  4 files changed, 204 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
>>  create mode 100644 drivers/memory/da8xx-ddrctl.c
>>
>> diff --git
>> a/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
>> b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
>> new file mode 100644
>> index 0000000..7e271dd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
>> @@ -0,0 +1,20 @@
>> +* Device tree bindings for Texas Instruments da8xx DDR2/mDDR memory controller
>> +
>> +The DDR2/mDDR memory controller present on Texas Instruments da8xx SoCs features
>> +a set of registers which allow to tweak the controller's behavior.
>> +
>> +Documentation:
>> +OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
>> +
>> +Required properties:
>> +
>> +- compatible:		"ti,da850-ddr-controller" - for da850 SoC based boards
>> +- reg:			a tuple containing the base address of the memory
>> +			controller and the size of the memory area to map
>> +
>> +Example for da850 shown below.
>> +
>> +ddrctl {
>> +	compatible = "ti,da850-ddr-controller";
>> +	reg = <0xB0000000 0x100>;
>> +};
>
> Axel's series for the USB PHY reminded me that the PHY also has some
> config registers in this same area, and his series creates a syscon for
> a similar range of registers.
>
> Could you create a syscon for the SYSCFG0 registers, which would then
> be used by ths driver and your other drivers/bus driver?  Then the
> binding  would just reference the sysconf via phandle, and your driver
> can use syscon_regmap_lookup_by_phandle()

Nevermind. I though that the config register in this driver was also in
SYSCFG0, but I see now that it's in the reg region of the DDR controller
itself, so no syscon is needed.

Kevin

^ permalink raw reply

* [PATCH 1/3] drivers: iommu: arm-smmu: constify iommu_gather_ops structures
From: Julia Lawall @ 2016-10-25 20:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477418772-12184-2-git-send-email-bhumirks@gmail.com>



On Tue, 25 Oct 2016, Bhumika Goyal wrote:

> Check for iommu_gather_ops structures that are only stored in the tlb
> field of an io_pgtable_cfg structure. The tlb field is of type
> const struct iommu_gather_ops *, so iommu_gather_ops structures
> having this property can be declared as const.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>

Acked-by: Julia Lawall <julia.lawall@lip6.fr>

> ---
>  drivers/iommu/arm-smmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index c841eb7..a5bc8fb 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -640,7 +640,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
>  	}
>  }
>
> -static struct iommu_gather_ops arm_smmu_gather_ops = {
> +static const struct iommu_gather_ops arm_smmu_gather_ops = {
>  	.tlb_flush_all	= arm_smmu_tlb_inv_context,
>  	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
>  	.tlb_sync	= arm_smmu_tlb_sync,
> --
> 1.9.1
>
>

^ permalink raw reply

* [PATCH 2/3] drivers: iommu: arm-smmu-v3: constify iommu_gather_ops structures
From: Julia Lawall @ 2016-10-25 20:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477418772-12184-3-git-send-email-bhumirks@gmail.com>



On Tue, 25 Oct 2016, Bhumika Goyal wrote:

> Check for iommu_gather_ops structures that are only stored in the tlb
> field of an io_pgtable_cfg structure. The tlb field is of type
> const struct iommu_gather_ops *, so iommu_gather_ops structures
> having this property can be declared as const.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>

Acked-by: Julia Lawall <julia.lawall@lip6.fr>

> ---
>  drivers/iommu/arm-smmu-v3.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 15c01c3..51d8be4 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -1358,7 +1358,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
>  	} while (size -= granule);
>  }
>
> -static struct iommu_gather_ops arm_smmu_gather_ops = {
> +static const struct iommu_gather_ops arm_smmu_gather_ops = {
>  	.tlb_flush_all	= arm_smmu_tlb_inv_context,
>  	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
>  	.tlb_sync	= arm_smmu_tlb_sync,
> --
> 1.9.1
>
>

^ permalink raw reply

* [PATCH 3/3] drivers: iommu: io-pgtable-arm: use const and __initconst for iommu_gather_ops structures
From: Julia Lawall @ 2016-10-25 20:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477418772-12184-4-git-send-email-bhumirks@gmail.com>



On Tue, 25 Oct 2016, Bhumika Goyal wrote:

> Check for iommu_gather_ops structures that are only stored in the tlb
> field of an io_pgtable_cfg structure. The tlb field is of type
> const struct iommu_gather_ops *, so iommu_gather_ops structures
> having this property can be declared as const. Also, replace __initdata
> with __initconst.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>

Acked-by: Julia Lawall <julia.lawall@lip6.fr>

> ---
>  drivers/iommu/io-pgtable-arm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index f5c90e1..412e21d 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -916,7 +916,7 @@ static void dummy_tlb_sync(void *cookie)
>  	WARN_ON(cookie != cfg_cookie);
>  }
>
> -static struct iommu_gather_ops dummy_tlb_ops __initdata = {
> +static const struct iommu_gather_ops dummy_tlb_ops __initconst = {
>  	.tlb_flush_all	= dummy_tlb_flush_all,
>  	.tlb_add_flush	= dummy_tlb_add_flush,
>  	.tlb_sync	= dummy_tlb_sync,
> --
> 1.9.1
>
>

^ permalink raw reply

* [PATCH 4/4] ARM: dts: da850: Add the usb otg device node
From: David Lechner @ 2016-10-25 19:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477406345-27192-5-git-send-email-abailon@baylibre.com>

On 10/25/2016 09:39 AM, Alexandre Bailon wrote:
> This adds the device tree node for the usb otg
> controller present in the da850 family of SoC's.
> This also enables the otg usb controller for the lcdk board.
>
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>  arch/arm/boot/dts/da850-lcdk.dts |  8 ++++++++
>  arch/arm/boot/dts/da850.dtsi     | 15 +++++++++++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
> index 7b8ab21..dca9735 100644
> --- a/arch/arm/boot/dts/da850-lcdk.dts
> +++ b/arch/arm/boot/dts/da850-lcdk.dts
> @@ -158,6 +158,14 @@
>  	rx-num-evt = <32>;
>  };
>
> +&usb_phy {
> +	status = "okay";
> +	};
> +
> +&usb20 {
> +	status = "okay";
> +};
> +
>  &aemif {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_pins>;
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index f79e1b9..b11d395 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -372,6 +372,21 @@
>  					>;
>  			status = "disabled";
>  		};
> +		usb_phy: usb-phy {
> +			compatible = "ti,da830-usb-phy";
> +			#phy-cells = <1>;
> +			status = "disabled";
> +		};
> +		usb20: usb20 at 200000 {

This should be usb0: usb at 200000

> +			compatible = "ti,da830-musb";
> +			reg = <0x200000 0x10000>;
> +			interrupts = <58>;
> +			interrupt-names = "mc";
> +			dr_mode = "otg";
> +			phys = <&usb_phy 0>;
> +			phy-names = "usb-phy";
> +			status = "disabled";
> +		};
>  		gpio: gpio at 226000 {
>  			compatible = "ti,dm6441-gpio";
>  			gpio-controller;
>

^ permalink raw reply

* Applied "ASoC: s3c24xx_uda134x: Move global variables to driver's data structure" to the asoc tree
From: Mark Brown @ 2016-10-25 19:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1470317928-25365-9-git-send-email-s.nawrocki@samsung.com>

The patch

   ASoC: s3c24xx_uda134x: Move global variables to driver's data structure

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 892ccf0f2173a9ede5448411e9475616fb21fb51 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Tue, 25 Oct 2016 12:57:57 +0200
Subject: [PATCH] ASoC: s3c24xx_uda134x: Move global variables to driver's data
 structure

Gather all driver's private variables in common data structure
and allocate the data structure dynamically.

Also unused ENFORCE_RATES symbol and local variable (leftovers
from an erroneous rebase) are removed.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/samsung/s3c24xx_uda134x.c | 79 ++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 36 deletions(-)

diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 7853fbe6ccc9..81a78940967c 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -19,9 +19,15 @@
 #include <sound/s3c24xx_uda134x.h>
 
 #include "regs-iis.h"
-
 #include "s3c24xx-i2s.h"
 
+struct s3c24xx_uda134x {
+	struct clk *xtal;
+	struct clk *pclk;
+	struct mutex clk_lock;
+	int clk_users;
+};
+
 /* #define ENFORCE_RATES 1 */
 /*
   Unfortunately the S3C24XX in master mode has a limited capacity of
@@ -36,15 +42,6 @@
   possible an error will be returned.
 */
 
-static struct clk *xtal;
-static struct clk *pclk;
-/* this is need because we don't have a place where to keep the
- * pointers to the clocks in each substream. We get the clocks only
- * when we are actually using them so we don't block stuff like
- * frequency change or oscillator power-off */
-static int clk_users;
-static DEFINE_MUTEX(clk_lock);
-
 static unsigned int rates[33 * 2];
 #ifdef ENFORCE_RATES
 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
@@ -57,26 +54,24 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct s3c24xx_uda134x *priv = snd_soc_card_get_drvdata(rtd->card);
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-#ifdef ENFORCE_RATES
-	struct snd_pcm_runtime *runtime = substream->runtime;
-#endif
 	int ret = 0;
 
-	mutex_lock(&clk_lock);
+	mutex_lock(&priv->clk_lock);
 
-	if (clk_users == 0) {
-		xtal = clk_get(rtd->dev, "xtal");
-		if (IS_ERR(xtal)) {
+	if (priv->clk_users == 0) {
+		priv->xtal = clk_get(rtd->dev, "xtal");
+		if (IS_ERR(priv->xtal)) {
 			dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
-			ret = PTR_ERR(xtal);
+			ret = PTR_ERR(priv->xtal);
 		} else {
-			pclk = clk_get(cpu_dai->dev, "iis");
-			if (IS_ERR(pclk)) {
+			priv->pclk = clk_get(cpu_dai->dev, "iis");
+			if (IS_ERR(priv->pclk)) {
 				dev_err(rtd->dev, "%s cannot get pclk\n",
 					__func__);
-				clk_put(xtal);
-				ret = PTR_ERR(pclk);
+				clk_put(priv->xtal);
+				ret = PTR_ERR(priv->pclk);
 			}
 		}
 		if (!ret) {
@@ -85,18 +80,19 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
 			for (i = 0; i < 2; i++) {
 				int fs = i ? 256 : 384;
 
-				rates[i*33] = clk_get_rate(xtal) / fs;
+				rates[i*33] = clk_get_rate(priv->xtal) / fs;
 				for (j = 1; j < 33; j++)
-					rates[i*33 + j] = clk_get_rate(pclk) /
+					rates[i*33 + j] = clk_get_rate(priv->pclk) /
 						(j * fs);
 			}
 		}
 	}
-	clk_users += 1;
-	mutex_unlock(&clk_lock);
+	priv->clk_users += 1;
+	mutex_unlock(&priv->clk_lock);
+
 	if (!ret) {
 #ifdef ENFORCE_RATES
-		ret = snd_pcm_hw_constraint_list(runtime, 0,
+		ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
 						 SNDRV_PCM_HW_PARAM_RATE,
 						 &hw_constraints_rates);
 		if (ret < 0)
@@ -109,15 +105,18 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
 
 static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
 {
-	mutex_lock(&clk_lock);
-	clk_users -= 1;
-	if (clk_users == 0) {
-		clk_put(xtal);
-		xtal = NULL;
-		clk_put(pclk);
-		pclk = NULL;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct s3c24xx_uda134x *priv = snd_soc_card_get_drvdata(rtd->card);
+
+	mutex_lock(&priv->clk_lock);
+	priv->clk_users -= 1;
+	if (priv->clk_users == 0) {
+		clk_put(priv->xtal);
+		priv->xtal = NULL;
+		clk_put(priv->pclk);
+		priv->pclk = NULL;
 	}
-	mutex_unlock(&clk_lock);
+	mutex_unlock(&priv->clk_lock);
 }
 
 static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
@@ -228,10 +227,18 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
 static int s3c24xx_uda134x_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
+	struct s3c24xx_uda134x *priv;
 	int ret;
 
-	platform_set_drvdata(pdev, card);
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mutex_init(&priv->clk_lock);
+
 	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+	snd_soc_card_set_drvdata(card, priv);
 
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
 	if (ret)
-- 
2.8.1

^ permalink raw reply related

* [PATCH 3/3] ARM: dts: socfpga: Enable QSPI on the Cyclone5 sockit
From: Dinh Nguyen @ 2016-10-25 18:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5e0adad1-8ef2-029f-cfcd-4a07c962fda2@opensource.altera.com>

On 10/25/2016 10:38 AM, Graham Moore wrote:
> On 10/20/2016 09:12 AM, Dinh Nguyen wrote:
>>
>>
>> On 10/20/2016 02:19 AM, Steffen Trumtrar wrote:
>>
>>>> +        cdns,tslch-ns = <4>;
>>>> +
>>>> +        partition at qspi-boot {
>>>> +            /* 8MB for raw data. */
>>>> +            label = "Flash 0 Raw Data";
>>>> +            reg = <0x0 0x800000>;
>>>> +        };
>>>> +
>>>> +        partition at qspi-rootfs {
>>>> +            /* 120MB for jffs2 data. */
>>>> +            label = "Flash 0 jffs2 Filesystem";
>>>> +            reg = <0x800000 0x7800000>;
>>>> +        };
>>>> +    };
>>>> +};
>>>> +
>>>
>>> What is the current preferred way of handling the partitions?
>>> This doesn't fit my Sockit configuration for example. So I would always
>>> have to patch the devicetree.
>>
>> I'm not 100% sure on this. Graham, do you have any insight?
>>>
> 
> Well, strictly speaking, these partitions are only for the socdk, the
> Altera dev kit.  Our sample designs and file systems expect this layout.
> 
> Therefore, these partitions are not required for any other dev kits, and
> can probably be left out.
> 
> Or, Steffen, if you have a standard layout you'd like to see, then put
> that in there.
> 
> I think some people will have to patch the layout regardless.
> 

Ok, I'll remove the partitions from the none Altera boards.

Dinh

^ permalink raw reply

* [PATCH] exynos-drm: Fix display manager failing to start without IOMMU problem
From: Shuah Khan @ 2016-10-25 18:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <580F9D0D.7000104@math.uni-bielefeld.de>

On 10/25/2016 11:57 AM, Tobias Jakobi wrote:
> Hello Shuah,
> 
> 
> Shuah Khan wrote:
>> On 10/19/2016 04:27 PM, Shuah Khan wrote:
>>> On 10/19/2016 08:16 AM, Inki Dae wrote:
>>>> Hi Shuah,
>>>>
>>>> 2016-10-13 8:11 GMT+09:00 Shuah Khan <shuahkh@osg.samsung.com>:
>>>>> Hi Inki,
>>>>>
>>>>> On 08/15/2016 10:40 PM, Inki Dae wrote:
>>>>>
>>>>>>>
>>>>>>> okay the very first commit that added IOMMU support
>>>>>>> introduced the code that rejects non-contig gem memory
>>>>>>> type without IOMMU.
>>>>>>>
>>>>>>> commit 0519f9a12d0113caab78980c48a7902d2bd40c2c
>>>>>>> Author: Inki Dae <inki.dae@samsung.com>
>>>>>>> Date:   Sat Oct 20 07:53:42 2012 -0700
>>>>>>>
>>>>>>>     drm/exynos: add iommu support for exynos drm framework
>>>>>>>
>>>>>
>>>>> I haven't given up on this yet. I am still seeing the following failure:
>>>>>
>>>>> Additional debug messages I added:
>>>>> [   15.287403] exynos_drm_gem_create_ioctl() 1
>>>>> [   15.287419] exynos_drm_gem_create() flags 1
>>>>>
>>>>> [   15.311511] [drm:exynos_drm_framebuffer_init] *ERROR* Non-contiguous GEM memory is not supported.
>>>>>
>>>>> Additional debug message I added:
>>>>> [   15.318981] [drm:exynos_user_fb_create] *ERROR* failed to initialize framebuffer
>>>>>
>>>>> This is what happens:
>>>>>
>>>>> 1. exynos_drm_gem_create_ioctl() gets called with EXYNOS_BO_NONCONTIG request
>>>>> 2. exynos_drm_gem_create(0 goes ahead and creates the GEM buffers
>>>>> 3. exynos_user_fb_create() tries to associate GEM to fb and fails during
>>>>>    check_fb_gem_memory_type()
>>>>>
>>>>> At this point, there is no recovery and lightdm fails
>>>>>
>>>>> xf86-video-armsoc/src/drmmode_exynos/drmmode_exynos.c assumes contiguous
>>>>> allocations are not supported in some exynos drm versions: The following
>>>>> commit introduced this change:
>>>>>
>>>>> https://git.linaro.org/arm/xorg/driver/xf86-video-armsoc.git/commitdiff/3be1f6273441fe95dd442f44064387322e16b7e9
>>>>>
>>>>> excerpts from the diff:-       if (create_gem->buf_type == ARMSOC_BO_SCANOUT)
>>>>> -               create_exynos.flags = EXYNOS_BO_CONTIG;
>>>>> -       else
>>>>> -               create_exynos.flags = EXYNOS_BO_NONCONTIG;
>>>>> +
>>>>> +       /* Contiguous allocations are not supported in some exynos drm versions.
>>>>> +        * When they are supported all allocations are effectively contiguous
>>>>> +        * anyway, so for simplicity we always request non contiguous buffers.
>>>>> +        */
>>>>> +       create_exynos.flags = EXYNOS_BO_NONCONTIG;
>>>>>
>>>>
>>>> Above comment, "Contiguous allocations are not supported in some
>>>> exynos drm versions.", seems wrong assumption.
>>>> The root cause, contiguous allocation is not supported, would be that
>>>> they used Linux kernel which didn't have CMA region enough - as
>>>> default 16MB, or didn't declare CMA region enough for the DMA device.
>>>> So I think they should not force to flag EXYNOS_BO_NONCONTIG and they
>>>> should manage the error case if the allocation failed.
>>>
>>> This assumption doesn't sound correct and forcing NONCONTIG isn't right
>>> either. 
>>>
>>>>
>>>>> There might have been logic on exynos_drm that forced Contig when it coudn't
>>>>> support NONCONTIG. At least, that is what this comment suggests. This assumption
>>>>> doesn't appear to be a good one and not sure if this change was made to fix a bug.
>>>>>
>>>>> After the IOMMU support, this assumption is no longer true. Hence, with IOMMU
>>>>> support, latest kernels have a mismatch with the installed xf86-video-armsoc
>>>>>
>>>>> This is what I am running into. This leads to the following question:
>>>>>
>>>>> 1. How do we ensure exynos_drm kernel changes don't break user-space
>>>>>    specifically xf86-video-armsoc
>>>>> 2. This seems to have gone undetected for a while. I see a change in
>>>>>    exynos_drm_gem_dumb_create() that is probably addressing this type
>>>>>    of breakage. Commit 122beea84bb90236b1ae545f08267af58591c21b adds
>>>>>    handling for IOMMU NONCONTIG case.
>>>>
>>>> Seems this patch has a problem. This patch forces to flag NONCONTIG if
>>>> iommu is enabled. The flag should be depend on the argument from
>>>> user-space.
>>>> I.e., if user-space requested a gem allocation with CONTIG flag, then
>>>> Exynos drm driver should allocate contiguous memory even though iommu
>>>> is enabled.
>>>>
>>>>>
>>>>> Anyway, I am interested in getting the exynos_drm kernel side code
>>>>> and xf86-video-armsoc in sync to resolve the issue.
>>>>>
>>>>> Could you recommend a going forward plan?
>>>>
>>>> My opinion are,
>>>>
>>>> 1. Do not force to flag EXYNOS_BO_NONCONTIG at xf86-video-armsoc
>>
>> Okay more on this. I fixed xf86-video-armso to ask for EXYNOS_BO_CONTIG
>> for ARMSOC_BO_SCANOUT and EXYNOS_BO_NONCONTIG in all other cases.
>>
>> Revert of the commit: 3be1f6273441fe95dd442f44064387322e16b7e9
>>
>> With this change, now display manager starts just fine. However, it turns
>> out xf86-video-armsoc is obsoleted in favor of xf86-video-modesetting. The
>> last update to xf86-video-armsoc git was 3 years ago.
> IIRC xf86-video-armsoc was created to facilitate integration with the
> proprietary Mali userspace blob. I don't think that can be done with the
> modesetting DDX.
> 
> 
> 
>> I am not sure where to send the fix and doesn't look like it is being
>> maintained actively. I can pursue it further and try to get this into
>> xf86-video-armsoc provided I can find the maintainer for this seemingly
>> inactive project.
> I was wondering if anyone has actually complained about this issue?

I sent email to the last person that modified the xf86-video-armsoc.
I will pursue fix to this.

> 
> 
> 
>> I brought in the latest xf86-video-modesetting bits from
>>
>> https://cgit.freedesktop.org/xorg/driver/xf86-video-modesetting
>>
>> I removed xf86-video-armsoc and installed xf86-video-modesetting and that
>> worked just fine. xf86-video-modesetting uses dumb_create interface instead
>> of DRM_IOCTL_EXYNOS_GEM_CREATE.
>>
>> dumb_create interface eliminates the need for DRM_IOCTL_EXYNOS_GEM_CREATE
>> in userspace. libdrm-2.4.71 does call DRM_IOCTL_EXYNOS_GEM_CREATE.
>>
>> The question is do we still need to continue to support the custom gem
>> create interface DRM_IOCTL_EXYNOS_GEM_CREATE?
> I'd say yes. With just the dumb_create interface it is not possible to
> change the type of buffer you get. And if you want to support any kind
> of hw acceleration in the DDX, you probably want to control at least the
> caching behaviour of the buffer.

Right. Okay that makes sense.

> 
> 
> 
>> Some drm drivers seem to support it and some don't.
> Not sure I understand this. I don't think any other DRM driver except
> for exynos supports this ioctl. But all drivers have their own ioctls to
> request memory (DRM_IOCTL_ETNAVIV_GEM_NEW, DRM_IOCTL_VC4_CREATE_BO, etc.)
> 
> 
> 
>>  Unfortunately, if userspace requests noncontig
>> for scanout, we will continue to see problems with display manager when
>> iommu is disabled. dumb create hides all of that, are there good reasons
>> to continue to support it in exynos drm?
> In addition to the stuff I said above, you can use it for render nodes.
> That doesn't work for dumb_create.
> 
> 
>> Exposing CONTIG and NONCONTIG to userspace appears to be causing problems
>> when exynos drm determines it can't support non-contig GEM buffers in fb
>> init after userspace allocates them.
> Might be missing something here, but this whole thing just looks like a
> bug in xf86-video-armsoc. No matter from which perspective you look, the
> commit that changed all allocations to noncontig was plain wrong.
> 
> My guess: This was done to paper over some bug in some vendor kernel for
> a product using an Exynos SoC.
> 

Yeah. The right fix in this case is fixing xf86-video-armsoc as you explained
dump_create is too generic for some use-cases.

thanks,
-- Shuah

^ permalink raw reply

* [PATCH v2 2/2] power: bq27xxx_battery: add poll interval property query
From: Matt Ranostay @ 2016-10-25 18:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161024201443.GB5989@amd>

On Mon, Oct 24, 2016 at 1:14 PM, Pavel Machek <pavel@ucw.cz> wrote:
> On Mon 2016-10-24 12:58:25, Matt Ranostay wrote:
>> Pavel + Sebastian this is the patchset that need I some input on :)
>
> Better then previous one.
>
> But my version of bq27xxx_battery.c already contains this:

This is for allowing udev rule to set the properties as well.
otherwise a kinda crude RUN = " echo value >
/sys/module/bq27xxx_battery/parameters/poll_interval" is required.

>
> static const struct kernel_param_ops param_ops_poll_interval = {
>         .get = param_get_uint,
>         .set = poll_interval_param_set,
> };
>
> ...so it should be possible to set poll interval already.
>
>                                                                         Pavel
>
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* [PATCH v3] drivers: psci: PSCI checker module
From: Paul E. McKenney @ 2016-10-25 18:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161025154535.GA3107@red-moon>

On Tue, Oct 25, 2016 at 04:45:35PM +0100, Lorenzo Pieralisi wrote:
> [ +Paul, James ]
> 
> Left most of the patch content in place so that they can follow it even
> if they weren't CC'ed.
> 
> On Thu, Oct 20, 2016 at 03:51:15PM +0100, Kevin Brodsky wrote:
> > On arm and arm64, PSCI is one of the possible firmware interfaces
> > used for power management. This includes both turning CPUs on and off,
> > and suspending them (entering idle states).
> > 
> > This patch adds a PSCI checker module that enables basic testing of
> > PSCI operations during startup. There are two main tests: CPU
> > hotplugging and suspending.
> > 
> > In the hotplug tests, the hotplug API is used to turn off and on again
> > all CPUs in the system, and then all CPUs in each cluster, checking
> > the consistency of the return codes.
> > 
> > In the suspend tests, a high-priority thread is created on each core
> > and uses low-level cpuidle functionalities to enter suspend, in all
> > the possible states and multiple times. This should allow a maximum
> > number of CPUs to enter the same sleep state at the same or slightly
> > different time.
> > 
> > In essence, the suspend tests use a principle similar to that of the
> > intel_powerclamp driver (drivers/thermal/intel_powerclamp.c), but the
> > threads are only kept for the duration of the test (they are already
> > gone when userspace is started).
> > 
> > While in theory power management PSCI functions (CPU_{ON,OFF,SUSPEND})
> > could be directly called, this proved too difficult as it would imply
> > the duplication of all the logic used by the kernel to allow for a
> > clean shutdown/bringup/suspend of the CPU (the deepest sleep states
> > implying potentially the shutdown of the CPU).
> > 
> > Note that this file cannot be compiled as a loadable module, since it
> > uses a number of non-exported identifiers (essentially for
> > PSCI-specific checks and direct use of cpuidle) and relies on the
> > absence of userspace to avoid races when calling hotplug and cpuidle
> > functions.
> > 
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Kevin Hilman <khilman@kernel.org>
> > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Sudeep Holla <sudeep.holla@arm.com>
> > Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> > ---
> 
> [...]
> 
> > +static int find_clusters(const struct cpumask *cpus,
> > +			 const struct cpumask **clusters)
> > +{
> > +	unsigned int nb = 0;
> > +	cpumask_var_t tmp;
> > +
> > +	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
> > +		return -ENOMEM;
> > +	cpumask_copy(tmp, cpus);
> > +
> > +	while (!cpumask_empty(tmp)) {
> > +		const struct cpumask *cluster =
> > +			topology_core_cpumask(cpumask_any(tmp));
> > +
> > +		clusters[nb++] = cluster;
> > +		cpumask_andnot(tmp, tmp, cluster);
> > +	}
> > +
> > +	free_cpumask_var(tmp);
> > +	return nb;
> > +}
> > +
> > +/*
> > + * offlined_cpus is a temporary array but passing it as an argument avoids
> > + * multiple allocations.
> > + */
> > +static unsigned int down_and_up_cpus(const struct cpumask *cpus,
> > +				     struct cpumask *offlined_cpus)
> > +{
> > +	int cpu;
> > +	int err = 0;
> > +
> > +	cpumask_clear(offlined_cpus);
> > +
> > +	/* Try to power down all CPUs in the mask. */
> > +	for_each_cpu(cpu, cpus) {
> > +		int ret = cpu_down(cpu);
> > +
> > +		/*
> > +		 * cpu_down() checks the number of online CPUs before the TOS
> > +		 * resident CPU.
> > +		 */
> > +		if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
> > +			if (ret != -EBUSY) {
> > +				pr_err("Unexpected return code %d while trying "
> > +				       "to power down last online CPU %d\n",
> > +				       ret, cpu);
> > +				++err;
> > +			}
> > +		} else if (cpu == tos_resident_cpu) {
> > +			if (ret != -EPERM) {
> > +				pr_err("Unexpected return code %d while trying "
> > +				       "to power down TOS resident CPU %d\n",
> > +				       ret, cpu);
> > +				++err;
> > +			}
> > +		} else if (ret != 0) {
> > +			pr_err("Error occurred (%d) while trying "
> > +			       "to power down CPU %d\n", ret, cpu);
> > +			++err;
> > +		}
> > +
> > +		if (ret == 0)
> > +			cpumask_set_cpu(cpu, offlined_cpus);
> > +	}
> > +
> > +	/* Try to power up all the CPUs that have been offlined. */
> > +	for_each_cpu(cpu, offlined_cpus) {
> > +		int ret = cpu_up(cpu);
> > +
> > +		if (ret != 0) {
> > +			pr_err("Error occurred (%d) while trying "
> > +			       "to power up CPU %d\n", ret, cpu);
> > +			++err;
> > +		} else {
> > +			cpumask_clear_cpu(cpu, offlined_cpus);
> > +		}
> > +	}
> > +
> > +	/*
> > +	 * Something went bad at some point and some CPUs could not be turned
> > +	 * back on.
> > +	 */
> > +	WARN_ON(!cpumask_empty(offlined_cpus) ||
> > +		num_online_cpus() != nb_available_cpus);
> > +
> > +	return err;
> > +}
> > +
> > +static int hotplug_tests(void)
> > +{
> > +	int err;
> > +	cpumask_var_t offlined_cpus;
> > +	int i, nb_cluster;
> > +	const struct cpumask **clusters;
> > +	char *page_buf;
> > +
> > +	err = -ENOMEM;
> > +	if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
> > +		return err;
> > +	/* We may have up to nb_available_cpus clusters. */
> > +	clusters = kmalloc_array(nb_available_cpus, sizeof(*clusters),
> > +				 GFP_KERNEL);
> > +	if (!clusters)
> > +		goto out_free_cpus;
> > +	page_buf = (char *)__get_free_page(GFP_KERNEL);
> > +	if (!page_buf)
> > +		goto out_free_clusters;
> > +
> > +	err = 0;
> > +	nb_cluster = find_clusters(cpu_online_mask, clusters);
> > +
> > +	/*
> > +	 * Of course the last CPU cannot be powered down and cpu_down() should
> > +	 * refuse doing that.
> > +	 */
> > +	pr_info("Trying to turn off and on again all CPUs\n");
> > +	err += down_and_up_cpus(cpu_online_mask, offlined_cpus);
> > +
> > +	/*
> > +	 * Take down CPUs by cluster this time. When the last CPU is turned
> > +	 * off, the cluster itself should shut down.
> > +	 */
> > +	for (i = 0; i < nb_cluster; ++i) {
> > +		int cluster_id =
> > +			topology_physical_package_id(cpumask_any(clusters[i]));
> > +		ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
> > +						      clusters[i]);
> > +		/* Remove trailing newline. */
> > +		page_buf[len - 1] = '\0';
> > +		pr_info("Trying to turn off and on again cluster %d "
> > +			"(CPUs %s)\n", cluster_id, page_buf);
> > +		err += down_and_up_cpus(clusters[i], offlined_cpus);
> > +	}
> > +
> > +	free_page((unsigned long)page_buf);
> > +out_free_clusters:
> > +	kfree(clusters);
> > +out_free_cpus:
> > +	free_cpumask_var(offlined_cpus);
> > +	return err;
> > +}
> > +
> > +static void dummy_callback(unsigned long ignored) {}
> > +
> > +static int suspend_cpu(int index, bool broadcast)
> > +{
> > +	int ret;
> > +
> > +	arch_cpu_idle_enter();
> > +
> > +	if (broadcast) {
> > +		/*
> > +		 * The local timer will be shut down, we need to enter tick
> > +		 * broadcast.
> > +		 */
> > +		ret = tick_broadcast_enter();
> > +		if (ret) {
> > +			/*
> > +			 * In the absence of hardware broadcast mechanism,
> > +			 * this CPU might be used to broadcast wakeups, which
> > +			 * may be why entering tick broadcast has failed.
> > +			 * There is little the kernel can do to work around
> > +			 * that, so enter WFI instead (idle state 0).
> > +			 */
> > +			cpu_do_idle();
> > +			ret = 0;
> > +			goto out_arch_exit;
> > +		}
> > +	}
> > +
> > +	/*
> > +	 * Replicate the common ARM cpuidle enter function
> > +	 * (arm_enter_idle_state).
> > +	 */
> > +	ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
> > +
> > +	if (broadcast)
> > +		tick_broadcast_exit();
> > +
> > +out_arch_exit:
> > +	arch_cpu_idle_exit();
> > +
> > +	return ret;
> > +}
> > +
> > +static int suspend_test_thread(void *arg)
> > +{
> > +	int cpu = (long)arg;
> > +	int i, nb_suspend = 0, nb_shallow_sleep = 0, nb_err = 0;
> > +	struct sched_param sched_priority = { .sched_priority = MAX_RT_PRIO-1 };
> > +	struct cpuidle_device *dev;
> > +	struct cpuidle_driver *drv;
> > +	/* No need for an actual callback, we just want to wake up the CPU. */
> > +	struct timer_list wakeup_timer =
> > +		TIMER_INITIALIZER(dummy_callback, 0, 0);
> > +
> > +	/* Wait for the main thread to give the start signal. */
> > +	wait_for_completion(&suspend_threads_started);
> > +
> > +	/* Set maximum priority to preempt all other threads on this CPU. */
> > +	if (sched_setscheduler_nocheck(current, SCHED_FIFO, &sched_priority))
> > +		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
> > +			cpu);
> > +
> > +	dev = this_cpu_read(cpuidle_devices);
> > +	drv = cpuidle_get_cpu_driver(dev);
> > +
> > +	pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
> > +		cpu, drv->state_count - 1);
> > +
> > +	for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
> > +		int index;
> > +		/*
> > +		 * Test all possible states, except 0 (which is usually WFI and
> > +		 * doesn't use PSCI).
> > +		 */
> > +		for (index = 1; index < drv->state_count; ++index) {
> > +			struct cpuidle_state *state = &drv->states[index];
> > +			bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
> > +			int ret;
> > +
> > +			/*
> > +			 * Set the timer to wake this CPU up in some time (which
> > +			 * should be largely sufficient for entering suspend).
> > +			 * If the local tick is disabled when entering suspend,
> > +			 * suspend_cpu() takes care of switching to a broadcast
> > +			 * tick, so the timer will still wake us up.
> > +			 */
> > +			mod_timer(&wakeup_timer, jiffies +
> > +				  usecs_to_jiffies(state->target_residency));
> > +
> > +			/* IRQs must be disabled during suspend operations. */
> > +			local_irq_disable();
> > +
> > +			ret = suspend_cpu(index, broadcast);
> > +
> > +			/*
> > +			 * We have woken up. Re-enable IRQs to handle any
> > +			 * pending interrupt, do not wait until the end of the
> > +			 * loop.
> > +			 */
> > +			local_irq_enable();
> > +
> > +			if (ret == index) {
> > +				++nb_suspend;
> > +			} else if (ret >= 0) {
> > +				/* We did not enter the expected state. */
> > +				++nb_shallow_sleep;
> > +			} else {
> > +				pr_err("Failed to suspend CPU %d: error %d "
> > +				       "(requested state %d, cycle %d)\n",
> > +				       cpu, ret, index, i);
> > +				++nb_err;
> > +			}
> > +		}
> > +	}
> > +
> > +	/*
> > +	 * Disable the timer to make sure that the timer will not trigger
> > +	 * later.
> > +	 */
> > +	del_timer(&wakeup_timer);
> > +
> > +	if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
> > +		complete(&suspend_threads_done);
> > +
> > +	/* Give up on RT scheduling and wait for termination. */
> > +	sched_priority.sched_priority = 0;
> > +	if (sched_setscheduler_nocheck(current, SCHED_NORMAL, &sched_priority))
> > +		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
> > +			cpu);
> > +	for (;;) {
> > +		/* Needs to be set first to avoid missing a wakeup. */
> > +		set_current_state(TASK_INTERRUPTIBLE);
> > +		if (kthread_should_stop()) {
> > +			__set_current_state(TASK_RUNNING);
> > +			break;
> > +		}
> > +		schedule();
> > +	}
> > +
> > +	pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
> > +		cpu, nb_suspend, nb_shallow_sleep, nb_err);
> > +
> > +	return nb_err;
> > +}
> > +
> > +static int suspend_tests(void)
> > +{
> > +	int i, cpu, err = 0;
> > +	struct task_struct **threads;
> > +	int nb_threads = 0;
> > +
> > +	threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
> > +				GFP_KERNEL);
> > +	if (!threads)
> > +		return -ENOMEM;
> > +
> > +	for_each_online_cpu(cpu) {
> > +		struct task_struct *thread;
> > +		/* Check that cpuidle is available on that CPU. */
> > +		struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
> > +		struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
> > +
> > +		if (cpuidle_not_available(drv, dev)) {
> > +			pr_warn("cpuidle not available on CPU %d, ignoring\n",
> > +				cpu);
> > +			continue;
> > +		}
> > +
> > +		thread = kthread_create_on_cpu(suspend_test_thread,
> > +					       (void *)(long)cpu, cpu,
> > +					       "psci_suspend_test");
> > +		if (IS_ERR(thread))
> > +			pr_err("Failed to create kthread on CPU %d\n", cpu);
> > +		else
> > +			threads[nb_threads++] = thread;
> > +	}
> > +	if (nb_threads < 1) {
> > +		kfree(threads);
> > +		return -ENODEV;
> > +	}
> > +
> > +	atomic_set(&nb_active_threads, nb_threads);
> > +
> > +	/*
> > +	 * Stop cpuidle to prevent the idle tasks from entering a deep sleep
> > +	 * mode, as it might interfere with the suspend threads on other CPUs.
> > +	 * This does not prevent the suspend threads from using cpuidle (only
> > +	 * the idle tasks check this status).
> > +	 */
> > +	cpuidle_pause();
> > +
> > +	/*
> > +	 * Wake up the suspend threads. To avoid the main thread being preempted
> > +	 * before all the threads have been unparked, the suspend threads will
> > +	 * wait for the completion of suspend_threads_started.
> > +	 */
> > +	for (i = 0; i < nb_threads; ++i)
> > +		wake_up_process(threads[i]);
> > +	complete_all(&suspend_threads_started);
> > +
> > +	wait_for_completion(&suspend_threads_done);
> > +
> > +	cpuidle_resume();
> > +
> > +	/* Stop and destroy all threads, get return status. */
> > +	for (i = 0; i < nb_threads; ++i)
> > +		err += kthread_stop(threads[i]);
> > +
> > +	kfree(threads);
> > +	return err;
> > +}
> > +
> > +static int __init psci_checker(void)
> > +{
> > +	int ret;
> > +
> > +	/*
> > +	 * Since we're in an initcall, we assume that all the CPUs that all
> > +	 * CPUs that can be onlined have been onlined.
> > +	 *
> > +	 * The tests assume that hotplug is enabled but nobody else is using it,
> > +	 * otherwise the results will be unpredictable. However, since there
> > +	 * is no userspace yet in initcalls, that should be fine.
> 
> I do not think it is. If you run a kernel with, say,
> CONFIG_LOCK_TORTURE_TEST, cpus may disappear from the radar while
> running the PSCI checker test itself; that at least would confuse the
> checker, and that's just an example.
> 
> I added Paul to check what are the assumptions behind the torture test
> hotplug tests, in particular if there are any implicit assumptions for
> it to work (ie it is the only kernel test hotplugging cpus in and out
> (?)), what I know is that the PSCI checker assumptions are not correct.

Both CONFIG_LOCK_TORTURE_TEST and CONFIG_RCU_TORTURE_TEST can and will
hotplug CPUs.  The locktorture.onoff_holdoff and rcutorture.onoff_holdoff
kernel parameters can delay the start of CPU-hotplug testing, and in
my testing I set this delay to 30 seconds after boot.

One approach would be to make your test refuse to run if either of
the lock/RCU torture tests was running.  Or do what Lorenzo suggests
below.  The torture tests aren't crazy enough to offline the last CPU.
Though they do try, just for effect, in cases where the last CPU is
marked cpu_is_hotpluggable().  ;-)

						Thanx, Paul

> There is something simple you can do to get this "fixed".
> 
> You can use the new API James implemented for hibernate,
> that allows you to disable (ie PSCI CPU OFF) all "secondary" cpus
> other than the primary one passed in as parameter:
> 
> freeze_secondary_cpus(int primary);
> 
> that function will _cpu_down() all online cpus other than "primary"
> in one go, without any interference allowed from other bits of the
> kernel. It requires an enable_nonboot_cpus() counterpart, and you
> can do that for every online cpus you detect (actually you can even
> avoid using the online cpu mask and use the present mask to carry
> out the test). If there is a resident trusted OS you can just
> trigger the test with primary == tos_resident_cpu, since all
> others are bound to fail (well, you can run them and check they
> do fail, it is a checker after all).
> 
> You would lose the capability of hotplugging a "cluster" at a time, but
> I do not think it is a big problem, the test above would cover it
> and more importantly, it is safe to execute.
> 
> Or we can augment the torture test API to restrict the cpumask
> it actually uses to offline/online cpus (I am referring to
> torture_onoff(), kernel/torture.c).
> 
> Further comments appreciated since I am not sure I grokked the
> assumption the torture tests make about hotplugging cpus in and out,
> I will go through the commits logs again to find more info.
> 
> Thanks !
> Lorenzo
> 
> > +	 */
> > +	nb_available_cpus = num_online_cpus();
> > +
> > +	/* Check PSCI operations are set up and working. */
> > +	ret = psci_ops_check();
> > +	if (ret)
> > +		return ret;
> > +
> > +	pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
> > +
> > +	pr_info("Starting hotplug tests\n");
> > +	ret = hotplug_tests();
> > +	if (ret == 0)
> > +		pr_info("Hotplug tests passed OK\n");
> > +	else if (ret > 0)
> > +		pr_err("%d error(s) encountered in hotplug tests\n", ret);
> > +	else {
> > +		pr_err("Out of memory\n");
> > +		return ret;
> > +	}
> > +
> > +	pr_info("Starting suspend tests (%d cycles per state)\n",
> > +		NUM_SUSPEND_CYCLE);
> > +	ret = suspend_tests();
> > +	if (ret == 0)
> > +		pr_info("Suspend tests passed OK\n");
> > +	else if (ret > 0)
> > +		pr_err("%d error(s) encountered in suspend tests\n", ret);
> > +	else {
> > +		switch (ret) {
> > +		case -ENOMEM:
> > +			pr_err("Out of memory\n");
> > +			break;
> > +		case -ENODEV:
> > +			pr_warn("Could not start suspend tests on any CPU\n");
> > +			break;
> > +		}
> > +	}
> > +
> > +	pr_info("PSCI checker completed\n");
> > +	return ret < 0 ? ret : 0;
> > +}
> > +late_initcall(psci_checker);
> > -- 
> > 2.10.0
> > 
> 

^ permalink raw reply

* [PATCH 4/9] pinctrl: meson: allow gpio to request irq
From: Linus Walleij @ 2016-10-25 18:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477409478.2482.113.camel@baylibre.com>

On Tue, Oct 25, 2016 at 5:31 PM, Jerome Brunet <jbrunet@baylibre.com> wrote:
> On Tue, 2016-10-25 at 15:47 +0100, Marc Zyngier wrote:

>> Is gpio_to_irq() supposed to allocate an interrupt? Or merely to
>> report the existence of a mapping?

It should provide an IRQ corresponding to the gpio line, if possible.

However the semantic is such, that it is not necessary to call to_irq()
before using an IRQ: the irqchip and gpiochip abstractions should be
orthogonal.

This goes especially when using device tree or ACPI, where you
may reference an IRQ from something modeled as irqchip, which
is simultaneously a gpiochip.

> Linus, please correct me if I'm wrong,
> .to_irq gets the linux gpio number and returns the linux virtual irq
> numbers, 0 if there is no interrupt.

Yes. But it may *or may not* be called before using the IRQ.

So it should look up or try to create a mapping on request, but not
assume to have been called before using some line as IRQ.

The only thing you should assume to be called before an interrupt
is put to use is the stuff in irqchip. So you have to do your
dynamic irqdomain mapping elsewhere than .to_irq().

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 4/9] pinctrl: meson: allow gpio to request irq
From: Linus Walleij @ 2016-10-25 18:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <bbc268c8-35c3-206a-46b1-62cebef174b2@arm.com>

On Tue, Oct 25, 2016 at 4:47 PM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On 25/10/16 15:22, Jerome Brunet wrote:

>> There is a few problems to guarantee that gpio == hwirq.
>> 1. We have 2 instances of pinctrl, to guarantee that the linux gpio
>> number == hwirq, we would have to guarantee the order in which they are
>> probed. At least this my understanding
>
> Maybe I wasn't clear enough, and my use of gpio is probably wrong. So
> Linux has a gpio number, which is obviously an abstract number (just
> like the Linux irq number). But the pad number, in the context of given
> SoC, is constant. So we have:
>
>         pad->gpio
>         hwirq->irq
>
> Why can't you have pad == hwirq, always? This is already what you have
> in the irqchip driver. This would simplify a lot of things.

My thought as well.

We usually refer to the local numberspace on the GPIO controller
as "offsets", so line offsets 0...31 on a gpiochip with 31 lines.

The ngpio in struct gpio_chip is the number of lines on that controller,
and should nominally map 1:1 to hwirq sources.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 3/3] drivers: iommu: io-pgtable-arm: use const and __initconst for iommu_gather_ops structures
From: Bhumika Goyal @ 2016-10-25 18:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477418772-12184-1-git-send-email-bhumirks@gmail.com>

Check for iommu_gather_ops structures that are only stored in the tlb
field of an io_pgtable_cfg structure. The tlb field is of type
const struct iommu_gather_ops *, so iommu_gather_ops structures
having this property can be declared as const. Also, replace __initdata
with __initconst.

Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
 drivers/iommu/io-pgtable-arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f5c90e1..412e21d 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -916,7 +916,7 @@ static void dummy_tlb_sync(void *cookie)
 	WARN_ON(cookie != cfg_cookie);
 }
 
-static struct iommu_gather_ops dummy_tlb_ops __initdata = {
+static const struct iommu_gather_ops dummy_tlb_ops __initconst = {
 	.tlb_flush_all	= dummy_tlb_flush_all,
 	.tlb_add_flush	= dummy_tlb_add_flush,
 	.tlb_sync	= dummy_tlb_sync,
-- 
1.9.1

^ permalink raw reply related


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