Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: dts: socfpga: add missing interrupt-parent
From: Arnd Bergmann @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel

The PMU node has no working interrupt, as shown by this dtc warning:

arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dtb: Warning (interrupts_property): Missing interrupt-parent for /pmu

This adds an interrupt-parent property so we can correct parse
that interrupt number.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
If this looks ok, I'd apply it directly to the fixes branch
for 4.15, as the warning is one that was introduced in this
release.
---
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
index 7c9bdc7ab50b..9db19314c60c 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -66,6 +66,7 @@
 				     <&cpu1>,
 				     <&cpu2>,
 				     <&cpu3>;
+		interrupt-parent = <&intc>;
 	};
 
 	psci {
-- 
2.9.0

^ permalink raw reply related

* [PATCH v2 1/7] ARM: imx: add timer stop flag to ARM power off state
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel

When the CPU is in ARM power off state the ARM architected
timers are stopped. The flag is already present in the higher
power WAIT mode.

This allows to use the ARM generic timer on i.MX 6UL/6ULL SoC.
Without the flag the kernel freezes when the timer enters the
first time ARM power off mode.

Note: The default timer on i.MX6SX is the i.MX GPT timer which is
not disabled during CPU idle. However, the timer is not affected
by the CPUIDLE_FLAG_TIMER_STOP flag. The flag only affects CPU
local timers.

Cc: Anson Huang <anson.huang@nxp.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
---
 arch/arm/mach-imx/cpuidle-imx6sx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index c5a5c3a70ab1..d0f14b761ff7 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -89,6 +89,7 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = {
 			 */
 			.exit_latency = 300,
 			.target_residency = 500,
+			.flags = CPUIDLE_FLAG_TIMER_STOP,
 			.enter = imx6sx_enter_wait,
 			.name = "LOW-POWER-IDLE",
 			.desc = "ARM power off",
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 2/7] ARM: dts: imx6ul: update i.MX 6UltraLite iomux headers
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

From: Fugang Duan <fugang.duan@nxp.com>

Add previously missing daisy chain configurations and several
additional pinmux options.

Synchronized with NXP Linux 4.9.11_1.0.0 release.

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 arch/arm/boot/dts/imx6ul-pinfunc.h | 169 +++++++++++++++++++++----------------
 1 file changed, 97 insertions(+), 72 deletions(-)

diff --git a/arch/arm/boot/dts/imx6ul-pinfunc.h b/arch/arm/boot/dts/imx6ul-pinfunc.h
index 0034eeb84542..9538b0ed5c11 100644
--- a/arch/arm/boot/dts/imx6ul-pinfunc.h
+++ b/arch/arm/boot/dts/imx6ul-pinfunc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright 2014 - 2015 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,14 +34,14 @@
 #define MX6UL_PAD_JTAG_MOD__ENET1_REF_CLK_25M		0x0044 0x02d0 0x0000 3 0
 #define MX6UL_PAD_JTAG_MOD__CCM_PMIC_RDY		0x0044 0x02d0 0x04c0 4 0
 #define MX6UL_PAD_JTAG_MOD__GPIO1_IO10			0x0044 0x02d0 0x0000 5 0
-#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00		0x0044 0x02d0 0x0000 6 0
+#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00		0x0044 0x02d0 0x0610 6 0
 #define MX6UL_PAD_JTAG_TMS__SJC_TMS			0x0048 0x02d4 0x0000 0 0
 #define MX6UL_PAD_JTAG_TMS__GPT2_CAPTURE1		0x0048 0x02d4 0x0598 1 0
-#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK			0x0048 0x02d4 0x0000 2 0
+#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK			0x0048 0x02d4 0x05f0 2 0
 #define MX6UL_PAD_JTAG_TMS__CCM_CLKO1			0x0048 0x02d4 0x0000 3 0
 #define MX6UL_PAD_JTAG_TMS__CCM_WAIT			0x0048 0x02d4 0x0000 4 0
 #define MX6UL_PAD_JTAG_TMS__GPIO1_IO11			0x0048 0x02d4 0x0000 5 0
-#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01		0x0048 0x02d4 0x0000 6 0
+#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01		0x0048 0x02d4 0x0614 6 0
 #define MX6UL_PAD_JTAG_TMS__EPIT1_OUT			0x0048 0x02d4 0x0000 8 0
 #define MX6UL_PAD_JTAG_TDO__SJC_TDO			0x004c 0x02d8 0x0000 0 0
 #define MX6UL_PAD_JTAG_TDO__GPT2_CAPTURE2		0x004c 0x02d8 0x059c 1 0
@@ -63,12 +63,14 @@
 #define MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA		0x0054 0x02e0 0x05f4 2 0
 #define MX6UL_PAD_JTAG_TCK__PWM7_OUT			0x0054 0x02e0 0x0000 4 0
 #define MX6UL_PAD_JTAG_TCK__GPIO1_IO14			0x0054 0x02e0 0x0000 5 0
+#define MX6UL_PAD_JTAG_TCK__REF_CLK_32K			0x0054 0x02e0 0x0000 6 0
 #define MX6UL_PAD_JTAG_TCK__SIM2_POWER_FAIL		0x0054 0x02e0 0x0000 8 0
 #define MX6UL_PAD_JTAG_TRST_B__SJC_TRSTB		0x0058 0x02e4 0x0000 0 0
 #define MX6UL_PAD_JTAG_TRST_B__GPT2_COMPARE3		0x0058 0x02e4 0x0000 1 0
 #define MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA		0x0058 0x02e4 0x0000 2 0
 #define MX6UL_PAD_JTAG_TRST_B__PWM8_OUT			0x0058 0x02e4 0x0000 4 0
 #define MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15		0x0058 0x02e4 0x0000 5 0
+#define MX6UL_PAD_JTAG_TRST_B__REF_CLK_24M		0x0058 0x02e4 0x0000 6 0
 #define MX6UL_PAD_JTAG_TRST_B__CAAM_RNG_OSC_OBS		0x0058 0x02e4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO00__I2C2_SCL			0x005c 0x02e8 0x05ac 0 1
 #define MX6UL_PAD_GPIO1_IO00__GPT1_CAPTURE1		0x005c 0x02e8 0x058c 1 0
@@ -94,22 +96,24 @@
 #define MX6UL_PAD_GPIO1_IO02__ENET1_REF_CLK_25M		0x0064 0x02f0 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO02__USDHC1_WP			0x0064 0x02f0 0x066c 4 0
 #define MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x0064 0x02f0 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00		0x0064 0x02f0 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00		0x0064 0x02f0 0x0610 6 1
 #define MX6UL_PAD_GPIO1_IO02__SRC_ANY_PU_RESET		0x0064 0x02f0 0x0000 7 0
 #define MX6UL_PAD_GPIO1_IO02__UART1_DCE_TX		0x0064 0x02f0 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO02__UART1_DTE_RX		0x0064 0x02f0 0x0624 8 0
 #define MX6UL_PAD_GPIO1_IO03__I2C1_SDA			0x0068 0x02f4 0x05a8 0 1
 #define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3		0x0068 0x02f4 0x0000 1 0
 #define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC		0x0068 0x02f4 0x0660 2 0
+#define MX6UL_PAD_GPIO1_IO03__REF_CLK_32K		0x0068 0x02f4 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B		0x0068 0x02f4 0x0668 4 0
 #define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x0068 0x02f4 0x0000 5 0
-#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_eXT_CLK		0x0068 0x02f4 0x0000 6 0
+#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_EXT_CLK		0x0068 0x02f4 0x0000 6 0
 #define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK		0x0068 0x02f4 0x0000 7 0
-#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX		0x0068 0x02f4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX		0x0068 0x02f4 0x0624 8 1
+#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX		0x0068 0x02f4 0x0000 8 0
 #define MX6UL_PAD_GPIO1_IO04__ENET1_REF_CLK1		0x006c 0x02f8 0x0574 0 1
 #define MX6UL_PAD_GPIO1_IO04__PWM3_OUT			0x006c 0x02f8 0x0000 1 0
 #define MX6UL_PAD_GPIO1_IO04__USB_OTG1_PWR		0x006c 0x02f8 0x0000 2 0
+#define MX6UL_PAD_GPIO1_IO04__REF_CLK_24M		0x006c 0x02f8 0x0000 3 0
 #define MX6UL_PAD_GPIO1_IO04__USDHC1_RESET_B		0x006c 0x02f8 0x0000 4 0
 #define MX6UL_PAD_GPIO1_IO04__GPIO1_IO04		0x006c 0x02f8 0x0000 5 0
 #define MX6UL_PAD_GPIO1_IO04__ENET2_1588_EVENT0_IN	0x006c 0x02f8 0x0000 6 0
@@ -200,7 +204,7 @@
 #define MX6UL_PAD_UART2_TX_DATA__CSI_DATA06		0x0094 0x0320 0x04dc 3 0
 #define MX6UL_PAD_UART2_TX_DATA__GPT1_CAPTURE1		0x0094 0x0320 0x058c 4 1
 #define MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x0094 0x0320 0x0000 5 0
-#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0		0x0094 0x0320 0x0000 8 0
+#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0		0x0094 0x0320 0x0560 8 0
 #define MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX		0x0098 0x0324 0x062c 0 1
 #define MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX		0x0098 0x0324 0x0000 0 0
 #define MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03		0x0098 0x0324 0x0000 1 0
@@ -232,7 +236,7 @@
 #define MX6UL_PAD_UART3_TX_DATA__UART3_DTE_RX		0x00a4 0x0330 0x0634 0 0
 #define MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02		0x00a4 0x0330 0x0000 1 0
 #define MX6UL_PAD_UART3_TX_DATA__SIM1_PORT0_PD		0x00a4 0x0330 0x0000 2 0
-#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01		0x00a4 0x0330 0x0000 3 0
+#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01		0x00a4 0x0330 0x04d4 3 0
 #define MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS		0x00a4 0x0330 0x0000 4 0
 #define MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS		0x00a4 0x0330 0x0628 4 2
 #define MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24		0x00a4 0x0330 0x0000 5 0
@@ -242,7 +246,7 @@
 #define MX6UL_PAD_UART3_RX_DATA__UART3_DTE_TX		0x00a8 0x0334 0x0000 0 0
 #define MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03		0x00a8 0x0334 0x0000 1 0
 #define MX6UL_PAD_UART3_RX_DATA__SIM2_PORT0_PD		0x00a8 0x0334 0x0000 2 0
-#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00		0x00a8 0x0334 0x0000 3 0
+#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00		0x00a8 0x0334 0x04d0 3 0
 #define MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS		0x00a8 0x0334 0x0628 4 3
 #define MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS		0x00a8 0x0334 0x0000 4 0
 #define MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25		0x00a8 0x0334 0x0000 5 0
@@ -251,7 +255,7 @@
 #define MX6UL_PAD_UART3_CTS_B__UART3_DTE_RTS		0x00ac 0x0338 0x0630 0 0
 #define MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK		0x00ac 0x0338 0x0000 1 0
 #define MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX		0x00ac 0x0338 0x0000 2 0
-#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10		0x00ac 0x0338 0x0000 3 0
+#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10		0x00ac 0x0338 0x04ec 3 0
 #define MX6UL_PAD_UART3_CTS_B__ENET1_1588_EVENT1_IN	0x00ac 0x0338 0x0000 4 0
 #define MX6UL_PAD_UART3_CTS_B__GPIO1_IO26		0x00ac 0x0338 0x0000 5 0
 #define MX6UL_PAD_UART3_CTS_B__EPIT2_OUT		0x00ac 0x0338 0x0000 8 0
@@ -259,7 +263,7 @@
 #define MX6UL_PAD_UART3_RTS_B__UART3_DTE_CTS		0x00b0 0x033c 0x0000 0 0
 #define MX6UL_PAD_UART3_RTS_B__ENET2_TX_ER		0x00b0 0x033c 0x0000 1 0
 #define MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX		0x00b0 0x033c 0x0584 2 0
-#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11		0x00b0 0x033c 0x0000 3 0
+#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11		0x00b0 0x033c 0x04f0 3 0
 #define MX6UL_PAD_UART3_RTS_B__ENET1_1588_EVENT1_OUT	0x00b0 0x033c 0x0000 4 0
 #define MX6UL_PAD_UART3_RTS_B__GPIO1_IO27		0x00b0 0x033c 0x0000 5 0
 #define MX6UL_PAD_UART3_RTS_B__WDOG1_WDOG_B		0x00b0 0x033c 0x0000 8 0
@@ -267,7 +271,7 @@
 #define MX6UL_PAD_UART4_TX_DATA__UART4_DTE_RX		0x00b4 0x0340 0x063c 0 0
 #define MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02		0x00b4 0x0340 0x0000 1 0
 #define MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x00b4 0x0340 0x05a4 2 1
-#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12		0x00b4 0x0340 0x0000 3 0
+#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12		0x00b4 0x0340 0x04f4 3 0
 #define MX6UL_PAD_UART4_TX_DATA__CSU_CSU_ALARM_AUT02	0x00b4 0x0340 0x0000 4 0
 #define MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28		0x00b4 0x0340 0x0000 5 0
 #define MX6UL_PAD_UART4_TX_DATA__ECSPI2_SCLK		0x00b4 0x0340 0x0544 8 1
@@ -275,23 +279,23 @@
 #define MX6UL_PAD_UART4_RX_DATA__UART4_DTE_TX		0x00b8 0x0344 0x0000 0 0
 #define MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03		0x00b8 0x0344 0x0000 1 0
 #define MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x00b8 0x0344 0x05a8 2 2
-#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13		0x00b8 0x0344 0x0000 3 0
+#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13		0x00b8 0x0344 0x04f8 3 0
 #define MX6UL_PAD_UART4_RX_DATA__CSU_CSU_ALARM_AUT01	0x00b8 0x0344 0x0000 4 0
 #define MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29		0x00b8 0x0344 0x0000 5 0
-#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0		0x00b8 0x0344 0x0000 8 0
+#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0		0x00b8 0x0344 0x0550 8 1
 #define MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30		0x00bc 0x0348 0x0000 5 0
 #define MX6UL_PAD_UART5_TX_DATA__ECSPI2_MOSI		0x00bc 0x0348 0x054c 8 0
 #define MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX		0x00bc 0x0348 0x0000 0 0
 #define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX		0x00bc 0x0348 0x0644 0 4
 #define MX6UL_PAD_UART5_TX_DATA__ENET2_CRS		0x00bc 0x0348 0x0000 1 0
 #define MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x00bc 0x0348 0x05ac 2 2
-#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14		0x00bc 0x0348 0x0000 3 0
+#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14		0x00bc 0x0348 0x04fc 3 0
 #define MX6UL_PAD_UART5_TX_DATA__CSU_CSU_ALARM_AUT00	0x00bc 0x0348 0x0000 4 0
 #define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX		0x00c0 0x034c 0x0644 0 5
 #define MX6UL_PAD_UART5_RX_DATA__UART5_DTE_TX		0x00c0 0x034c 0x0000 0 0
 #define MX6UL_PAD_UART5_RX_DATA__ENET2_COL		0x00c0 0x034c 0x0000 1 0
 #define MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x00c0 0x034c 0x05b0 2 2
-#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15		0x00c0 0x034c 0x0000 3 0
+#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15		0x00c0 0x034c 0x0500 3 0
 #define MX6UL_PAD_UART5_RX_DATA__CSU_CSU_INT_DEB	0x00c0 0x034c 0x0000 4 0
 #define MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31		0x00c0 0x034c 0x0000 5 0
 #define MX6UL_PAD_UART5_RX_DATA__ECSPI2_MISO		0x00c0 0x034c 0x0548 8 1
@@ -299,59 +303,61 @@
 #define MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS		0x00c4 0x0350 0x0638 1 0
 #define MX6UL_PAD_ENET1_RX_DATA0__UART4_DTE_CTS		0x00c4 0x0350 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT		0x00c4 0x0350 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16		0x00c4 0x0350 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16		0x00c4 0x0350 0x0504 3 0
 #define MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX		0x00c4 0x0350 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00		0x00c4 0x0350 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00		0x00c4 0x0350 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00		0x00c4 0x0350 0x05d0 6 0
 #define MX6UL_PAD_ENET1_RX_DATA0__USDHC1_LCTL		0x00c4 0x0350 0x0000 8 0
 #define MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01		0x00c8 0x0354 0x0000 0 0
 #define MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS		0x00c8 0x0354 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_DATA1__UART4_DTE_RTS		0x00c8 0x0354 0x0638 1 1
 #define MX6UL_PAD_ENET1_RX_DATA1__PWM2_OUT		0x00c8 0x0354 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17		0x00c8 0x0354 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17		0x00c8 0x0354 0x0508 3 0
 #define MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX		0x00c8 0x0354 0x0584 4 1
 #define MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x00c8 0x0354 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00		0x00c8 0x0354 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00		0x00c8 0x0354 0x05c4 6 0
 #define MX6UL_PAD_ENET1_RX_DATA1__USDHC2_LCTL		0x00c8 0x0354 0x0000 8 0
 #define MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN		0x00cc 0x0358 0x0000 0 0
 #define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS		0x00cc 0x0358 0x0640 1 3
 #define MX6UL_PAD_ENET1_RX_EN__UART5_DTE_CTS		0x00cc 0x0358 0x0000 1 0
-#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18		0x00cc 0x0358 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_EN__REF_CLK_32K		0x00cc 0x0358 0x0000 2 0
+#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18		0x00cc 0x0358 0x050c 3 0
 #define MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX		0x00cc 0x0358 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x00cc 0x0358 0x0000 5 0
-#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01		0x00cc 0x0358 0x0000 6 0
+#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01		0x00cc 0x0358 0x05d4 6 0
 #define MX6UL_PAD_ENET1_RX_EN__USDHC1_VSELECT		0x00cc 0x0358 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00		0x00d0 0x035c 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_DATA0__UART5_DCE_CTS		0x00d0 0x035c 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS		0x00d0 0x035c 0x0640 1 4
-#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19		0x00d0 0x035c 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA0__REF_CLK_24M		0x00d0 0x035c 0x0000 2 0
+#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19		0x00d0 0x035c 0x0510 3 0
 #define MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX		0x00d0 0x035c 0x0588 4 1
 #define MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x00d0 0x035c 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01		0x00d0 0x035c 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01		0x00d0 0x035c 0x05c8 6 0
 #define MX6UL_PAD_ENET1_TX_DATA0__USDHC2_VSELECT	0x00d0 0x035c 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01		0x00d4 0x0360 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_DATA1__UART6_DCE_CTS		0x00d4 0x0360 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_DATA1__UART6_DTE_RTS		0x00d4 0x0360 0x0648 1 2
 #define MX6UL_PAD_ENET1_TX_DATA1__PWM5_OUT		0x00d4 0x0360 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20		0x00d4 0x0360 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20		0x00d4 0x0360 0x0514 3 0
 #define MX6UL_PAD_ENET1_TX_DATA1__ENET2_MDIO		0x00d4 0x0360 0x0580 4 1
 #define MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x00d4 0x0360 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02		0x00d4 0x0360 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02		0x00d4 0x0360 0x05d8 6 0
 #define MX6UL_PAD_ENET1_TX_DATA1__WDOG1_WDOG_RST_B_DEB	0x00d4 0x0360 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN		0x00d8 0x0364 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_EN__UART6_DCE_RTS		0x00d8 0x0364 0x0648 1 3
 #define MX6UL_PAD_ENET1_TX_EN__UART6_DTE_CTS		0x00d8 0x0364 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_EN__PWM6_OUT			0x00d8 0x0364 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21		0x00d8 0x0364 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21		0x00d8 0x0364 0x0518 3 0
 #define MX6UL_PAD_ENET1_TX_EN__ENET2_MDC		0x00d8 0x0364 0x0000 4 0
 #define MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05		0x00d8 0x0364 0x0000 5 0
-#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02		0x00d8 0x0364 0x0000 6 0
+#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02		0x00d8 0x0364 0x05cc 6 0
 #define MX6UL_PAD_ENET1_TX_EN__WDOG2_WDOG_RST_B_DEB	0x00d8 0x0364 0x0000 8 0
 #define MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK		0x00dc 0x0368 0x0000 0 0
 #define MX6UL_PAD_ENET1_TX_CLK__UART7_DCE_CTS		0x00dc 0x0368 0x0000 1 0
 #define MX6UL_PAD_ENET1_TX_CLK__UART7_DTE_RTS		0x00dc 0x0368 0x0650 1 0
 #define MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT		0x00dc 0x0368 0x0000 2 0
-#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22		0x00dc 0x0368 0x0000 3 0
+#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22		0x00dc 0x0368 0x051c 3 0
 #define MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1		0x00dc 0x0368 0x0574 4 2
 #define MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x00dc 0x0368 0x0000 5 0
 #define MX6UL_PAD_ENET1_TX_CLK__KPP_ROW03		0x00dc 0x0368 0x0000 6 0
@@ -360,7 +366,7 @@
 #define MX6UL_PAD_ENET1_RX_ER__UART7_DCE_RTS		0x00e0 0x036c 0x0650 1 1
 #define MX6UL_PAD_ENET1_RX_ER__UART7_DTE_CTS		0x00e0 0x036c 0x0000 1 0
 #define MX6UL_PAD_ENET1_RX_ER__PWM8_OUT			0x00e0 0x036c 0x0000 2 0
-#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23		0x00e0 0x036c 0x0000 3 0
+#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23		0x00e0 0x036c 0x0520 3 0
 #define MX6UL_PAD_ENET1_RX_ER__EIM_CRE			0x00e0 0x036c 0x0000 4 0
 #define MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07		0x00e0 0x036c 0x0000 5 0
 #define MX6UL_PAD_ENET1_RX_ER__KPP_COL03		0x00e0 0x036c 0x0000 6 0
@@ -377,7 +383,7 @@
 #define MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01		0x00e8 0x0374 0x0000 0 0
 #define MX6UL_PAD_ENET2_RX_DATA1__UART6_DCE_RX		0x00e8 0x0374 0x064c 1 2
 #define MX6UL_PAD_ENET2_RX_DATA1__UART6_DTE_TX		0x00e8 0x0374 0x0000 1 0
-#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_cLK	0x00e8 0x0374 0x0000 2 0
+#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_CLK	0x00e8 0x0374 0x0000 2 0
 #define MX6UL_PAD_ENET2_RX_DATA1__I2C3_SDA		0x00e8 0x0374 0x05b8 3 1
 #define MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC		0x00e8 0x0374 0x0000 4 0
 #define MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x00e8 0x0374 0x0000 5 0
@@ -400,6 +406,7 @@
 #define MX6UL_PAD_ENET2_TX_DATA0__EIM_EB_B02		0x00f0 0x037c 0x0000 4 0
 #define MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x00f0 0x037c 0x0000 5 0
 #define MX6UL_PAD_ENET2_TX_DATA0__KPP_COL05		0x00f0 0x037c 0x0000 6 0
+#define MX6UL_PAD_ENET2_TX_DATA0__REF_CLK_24M		0x00f0 0x037c 0x0000 8 0
 #define MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01		0x00f4 0x0380 0x0000 0 0
 #define MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX		0x00f4 0x0380 0x0000 1 0
 #define MX6UL_PAD_ENET2_TX_DATA1__UART8_DTE_RX		0x00f4 0x0380 0x065c 1 0
@@ -412,7 +419,7 @@
 #define MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN		0x00f8 0x0384 0x0000 0 0
 #define MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX		0x00f8 0x0384 0x065c 1 1
 #define MX6UL_PAD_ENET2_TX_EN__UART8_DTE_TX		0x00f8 0x0384 0x0000 1 0
-#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_cLK		0x00f8 0x0384 0x0000 2 0
+#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_CLK		0x00f8 0x0384 0x0000 2 0
 #define MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI		0x00f8 0x0384 0x056c 3 0
 #define MX6UL_PAD_ENET2_TX_EN__EIM_ACLK_FREERUN		0x00f8 0x0384 0x0000 4 0
 #define MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x00f8 0x0384 0x0000 5 0
@@ -431,7 +438,7 @@
 #define MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS		0x0100 0x038c 0x0658 1 1
 #define MX6UL_PAD_ENET2_RX_ER__UART8_DTE_CTS		0x0100 0x038c 0x0000 1 0
 #define MX6UL_PAD_ENET2_RX_ER__SIM2_PORT0_SVEN		0x0100 0x038c 0x0000 2 0
-#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0		0x0100 0x038c 0x0000 3 0
+#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0		0x0100 0x038c 0x0570 3 0
 #define MX6UL_PAD_ENET2_RX_ER__EIM_ADDR25		0x0100 0x038c 0x0000 4 0
 #define MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x0100 0x038c 0x0000 5 0
 #define MX6UL_PAD_ENET2_RX_ER__KPP_COL07		0x0100 0x038c 0x0000 6 0
@@ -440,7 +447,7 @@
 #define MX6UL_PAD_LCD_CLK__LCDIF_WR_RWN			0x0104 0x0390 0x0000 1 0
 #define MX6UL_PAD_LCD_CLK__UART4_DCE_TX			0x0104 0x0390 0x0000 2 0
 #define MX6UL_PAD_LCD_CLK__UART4_DTE_RX			0x0104 0x0390 0x063c 2 2
-#define MX6UL_PAD_LCD_CLK__SAI3_MCLK			0x0104 0x0390 0x0000 3 0
+#define MX6UL_PAD_LCD_CLK__SAI3_MCLK			0x0104 0x0390 0x0600 3 0
 #define MX6UL_PAD_LCD_CLK__EIM_CS2_B			0x0104 0x0390 0x0000 4 0
 #define MX6UL_PAD_LCD_CLK__GPIO3_IO00			0x0104 0x0390 0x0000 5 0
 #define MX6UL_PAD_LCD_CLK__WDOG1_WDOG_RST_B_DEB		0x0104 0x0390 0x0000 8 0
@@ -464,7 +471,7 @@
 #define MX6UL_PAD_LCD_VSYNC__LCDIF_BUSY			0x0110 0x039c 0x05dc 1 1
 #define MX6UL_PAD_LCD_VSYNC__UART4_DCE_RTS		0x0110 0x039c 0x0638 2 3
 #define MX6UL_PAD_LCD_VSYNC__UART4_DTE_CTS		0x0110 0x039c 0x0000 2 0
-#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA		0x0110 0x039c 0x0000 3 0
+#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA		0x0110 0x039c 0x0604 3 0
 #define MX6UL_PAD_LCD_VSYNC__WDOG2_WDOG_B		0x0110 0x039c 0x0000 4 0
 #define MX6UL_PAD_LCD_VSYNC__GPIO3_IO03			0x0110 0x039c 0x0000 5 0
 #define MX6UL_PAD_LCD_VSYNC__ECSPI2_SS2			0x0110 0x039c 0x0000 8 0
@@ -477,13 +484,15 @@
 #define MX6UL_PAD_LCD_RESET__ECSPI2_SS3			0x0114 0x03a0 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x0118 0x03a4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA00__PWM1_OUT			0x0118 0x03a4 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA00__CA7_MX6UL_TRACE0		0x0118 0x03a4 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA00__ENET1_1588_EVENT2_IN	0x0118 0x03a4 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA00__I2C3_SDA			0x0118 0x03a4 0x05b8 4 2
 #define MX6UL_PAD_LCD_DATA00__GPIO3_IO05		0x0118 0x03a4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA00__SRC_BT_CFG00		0x0118 0x03a4 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK			0x0118 0x03a4 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK			0x0118 0x03a4 0x05e0 8 1
 #define MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x011c 0x03a8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA01__PWM2_OUT			0x011c 0x03a8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA01__CA7_MX6UL_TRACE1		0x011c 0x03a8 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA01__ENET1_1588_EVENT2_OUT	0x011c 0x03a8 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA01__I2C3_SCL			0x011c 0x03a8 0x05b4 4 2
 #define MX6UL_PAD_LCD_DATA01__GPIO3_IO06		0x011c 0x03a8 0x0000 5 0
@@ -491,6 +500,7 @@
 #define MX6UL_PAD_LCD_DATA01__SAI1_TX_SYNC		0x011c 0x03a8 0x05ec 8 0
 #define MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x0120 0x03ac 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA02__PWM3_OUT			0x0120 0x03ac 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA02__CA7_MX6UL_TRACE2		0x0120 0x03ac 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA02__ENET1_1588_EVENT3_IN	0x0120 0x03ac 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA02__I2C4_SDA			0x0120 0x03ac 0x05c0 4 2
 #define MX6UL_PAD_LCD_DATA02__GPIO3_IO07		0x0120 0x03ac 0x0000 5 0
@@ -498,14 +508,16 @@
 #define MX6UL_PAD_LCD_DATA02__SAI1_TX_BCLK		0x0120 0x03ac 0x05e8 8 0
 #define MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x0124 0x03b0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA03__PWM4_OUT			0x0124 0x03b0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA03__CA7_MX6UL_TRACE3		0x0124 0x03b0 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA03__ENET1_1588_EVENT3_OUT	0x0124 0x03b0 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA03__I2C4_SCL			0x0124 0x03b0 0x05bc 4 2
 #define MX6UL_PAD_LCD_DATA03__GPIO3_IO08		0x0124 0x03b0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA03__SRC_BT_CFG03		0x0124 0x03b0 0x0000 6 0
-#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA		0x0124 0x03b0 0x0000 8 0
+#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA		0x0124 0x03b0 0x05e4 8 0
 #define MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x0128 0x03b4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA04__UART8_DCE_CTS		0x0128 0x03b4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA04__UART8_DTE_RTS		0x0128 0x03b4 0x0658 1 2
+#define MX6UL_PAD_LCD_DATA04__CA7_MX6UL_TRACE4		0x0128 0x03b4 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA04__ENET2_1588_EVENT2_IN	0x0128 0x03b4 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA04__SPDIF_SR_CLK		0x0128 0x03b4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA04__GPIO3_IO09		0x0128 0x03b4 0x0000 5 0
@@ -514,6 +526,7 @@
 #define MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x012c 0x03b8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA05__UART8_DCE_RTS		0x012c 0x03b8 0x0658 1 3
 #define MX6UL_PAD_LCD_DATA05__UART8_DTE_CTS		0x012c 0x03b8 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA05__CA7_MX6UL_TRACE5		0x012c 0x03b8 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA05__ENET2_1588_EVENT2_OUT	0x012c 0x03b8 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA05__SPDIF_OUT			0x012c 0x03b8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA05__GPIO3_IO10		0x012c 0x03b8 0x0000 5 0
@@ -522,6 +535,7 @@
 #define MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x0130 0x03bc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS		0x0130 0x03bc 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA06__UART7_DTE_RTS		0x0130 0x03bc 0x0650 1 2
+#define MX6UL_PAD_LCD_DATA06__CA7_MX6UL_TRACE6		0x0130 0x03bc 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA06__ENET2_1588_EVENT3_IN	0x0130 0x03bc 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA06__SPDIF_LOCK		0x0130 0x03bc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA06__GPIO3_IO11		0x0130 0x03bc 0x0000 5 0
@@ -530,6 +544,7 @@
 #define MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x0134 0x03c0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS		0x0134 0x03c0 0x0650 1 3
 #define MX6UL_PAD_LCD_DATA07__UART7_DTE_CTS		0x0134 0x03c0 0x0000 1 0
+#define MX6UL_PAD_LCD_DATA07__CA7_MX6UL_TRACE7		0x0134 0x03c0 0x0000 2 0
 #define MX6UL_PAD_LCD_DATA07__ENET2_1588_EVENT3_OUT	0x0134 0x03c0 0x0000 3 0
 #define MX6UL_PAD_LCD_DATA07__SPDIF_EXT_CLK		0x0134 0x03c0 0x061c 4 0
 #define MX6UL_PAD_LCD_DATA07__GPIO3_IO12		0x0134 0x03c0 0x0000 5 0
@@ -537,56 +552,64 @@
 #define MX6UL_PAD_LCD_DATA07__ECSPI1_SS3		0x0134 0x03c0 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x0138 0x03c4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA08__SPDIF_IN			0x0138 0x03c4 0x0618 1 2
-#define MX6UL_PAD_LCD_DATA08__CSI_DATA16		0x0138 0x03c4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA08__CA7_MX6UL_TRACE8		0x0138 0x03c4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA08__CSI_DATA16		0x0138 0x03c4 0x0504 3 1
 #define MX6UL_PAD_LCD_DATA08__EIM_DATA00		0x0138 0x03c4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA08__GPIO3_IO13		0x0138 0x03c4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA08__SRC_BT_CFG08		0x0138 0x03c4 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX		0x0138 0x03c4 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x013c 0x03c8 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK			0x013c 0x03c8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA09__CSI_DATA17		0x013c 0x03c8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK			0x013c 0x03c8 0x0600 1 1
+#define MX6UL_PAD_LCD_DATA09__CA7_MX6UL_TRACE9		0x013c 0x03c8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA09__CSI_DATA17		0x013c 0x03c8 0x0508 3 1
 #define MX6UL_PAD_LCD_DATA09__EIM_DATA01		0x013c 0x03c8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA09__GPIO3_IO14		0x013c 0x03c8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA09__SRC_BT_CFG09		0x013c 0x03c8 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX		0x013c 0x03c8 0x0584 8 2
 #define MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x0140 0x03cc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA10__SAI3_RX_SYNC		0x0140 0x03cc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA10__CSI_DATA18		0x0140 0x03cc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA10__CA7_MX6UL_TRACE10		0x0140 0x03cc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA10__CSI_DATA18		0x0140 0x03cc 0x050c 3 1
 #define MX6UL_PAD_LCD_DATA10__EIM_DATA02		0x0140 0x03cc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA10__GPIO3_IO15		0x0140 0x03cc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA10__SRC_BT_CFG10		0x0140 0x03cc 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX		0x0140 0x03cc 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x0144 0x03d0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA11__SAI3_RX_BCLK		0x0144 0x03d0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA11__CSI_DATA19		0x0144 0x03d0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA11__CA7_MX6UL_TRACE11		0x0144 0x03d0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA11__CSI_DATA19		0x0144 0x03d0 0x0510 3 1
 #define MX6UL_PAD_LCD_DATA11__EIM_DATA03		0x0144 0x03d0 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA11__GPIO3_IO16		0x0144 0x03d0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA11__SRC_BT_CFG11		0x0144 0x03d0 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX		0x0144 0x03d0 0x0588 8 2
 #define MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x0148 0x03d4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC		0x0148 0x03d4 0x060c 1 1
-#define MX6UL_PAD_LCD_DATA12__CSI_DATA20		0x0148 0x03d4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA12__CA7_MX6UL_TRACE12		0x0148 0x03d4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA12__CSI_DATA20		0x0148 0x03d4 0x0514 3 1
 #define MX6UL_PAD_LCD_DATA12__EIM_DATA04		0x0148 0x03d4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA12__GPIO3_IO17		0x0148 0x03d4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA12__SRC_BT_CFG12		0x0148 0x03d4 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA12__ECSPI1_RDY		0x0148 0x03d4 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x014c 0x03d8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK		0x014c 0x03d8 0x0608 1 1
-#define MX6UL_PAD_LCD_DATA13__CSI_DATA21		0x014c 0x03d8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA13__CA7_MX6UL_TRACE13		0x014c 0x03d8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA13__CSI_DATA21		0x014c 0x03d8 0x0518 3 1
 #define MX6UL_PAD_LCD_DATA13__EIM_DATA05		0x014c 0x03d8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA13__GPIO3_IO18		0x014c 0x03d8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA13__SRC_BT_CFG13		0x014c 0x03d8 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA13__USDHC2_RESET_B		0x014c 0x03d8 0x0000 8 0
 #define MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x0150 0x03dc 0x0000 0 0
-#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA		0x0150 0x03dc 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA14__CSI_DATA22		0x0150 0x03dc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA		0x0150 0x03dc 0x0604 1 1
+#define MX6UL_PAD_LCD_DATA14__CA7_MX6UL_TRACE14		0x0150 0x03dc 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA14__CSI_DATA22		0x0150 0x03dc 0x051c 3 1
 #define MX6UL_PAD_LCD_DATA14__EIM_DATA06		0x0150 0x03dc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA14__GPIO3_IO19		0x0150 0x03dc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA14__SRC_BT_CFG14		0x0150 0x03dc 0x0000 6 0
 #define MX6UL_PAD_LCD_DATA14__USDHC2_DATA4		0x0150 0x03dc 0x068c 8 0
 #define MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x0154 0x03e0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA		0x0154 0x03e0 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA15__CSI_DATA23		0x0154 0x03e0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA15__CA7_MX6UL_TRACE15		0x0154 0x03e0 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA15__CSI_DATA23		0x0154 0x03e0 0x0520 3 1
 #define MX6UL_PAD_LCD_DATA15__EIM_DATA07		0x0154 0x03e0 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA15__GPIO3_IO20		0x0154 0x03e0 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA15__SRC_BT_CFG15		0x0154 0x03e0 0x0000 6 0
@@ -594,7 +617,8 @@
 #define MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x0158 0x03e4 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA16__UART7_DCE_TX		0x0158 0x03e4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA16__UART7_DTE_RX		0x0158 0x03e4 0x0654 1 2
-#define MX6UL_PAD_LCD_DATA16__CSI_DATA01		0x0158 0x03e4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA16__CA7_MX6UL_TRACE_CLK	0x0158 0x03e4 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA16__CSI_DATA01		0x0158 0x03e4 0x04d4 3 1
 #define MX6UL_PAD_LCD_DATA16__EIM_DATA08		0x0158 0x03e4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA16__GPIO3_IO21		0x0158 0x03e4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA16__SRC_BT_CFG24		0x0158 0x03e4 0x0000 6 0
@@ -602,7 +626,8 @@
 #define MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x015c 0x03e8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA17__UART7_DCE_RX		0x015c 0x03e8 0x0654 1 3
 #define MX6UL_PAD_LCD_DATA17__UART7_DTE_TX		0x015c 0x03e8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA17__CSI_DATA00		0x015c 0x03e8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA17__CA7_MX6UL_TRACE_CTL	0x015c 0x03e8 0x0000 2 0
+#define MX6UL_PAD_LCD_DATA17__CSI_DATA00		0x015c 0x03e8 0x04d0 3 1
 #define MX6UL_PAD_LCD_DATA17__EIM_DATA09		0x015c 0x03e8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA17__GPIO3_IO22		0x015c 0x03e8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA17__SRC_BT_CFG25		0x015c 0x03e8 0x0000 6 0
@@ -610,7 +635,7 @@
 #define MX6UL_PAD_LCD_DATA18__LCDIF_DATA18		0x0160 0x03ec 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA18__PWM5_OUT			0x0160 0x03ec 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA18__CA7_MX6UL_EVENTO		0x0160 0x03ec 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA18__CSI_DATA10		0x0160 0x03ec 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA18__CSI_DATA10		0x0160 0x03ec 0x04ec 3 1
 #define MX6UL_PAD_LCD_DATA18__EIM_DATA10		0x0160 0x03ec 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA18__GPIO3_IO23		0x0160 0x03ec 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA18__SRC_BT_CFG26		0x0160 0x03ec 0x0000 6 0
@@ -622,7 +647,7 @@
 #define MX6UL_PAD_LCD_DATA19__LCDIF_DATA19		0x0164 0x03f0 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA19__PWM6_OUT			0x0164 0x03f0 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA19__WDOG1_WDOG_ANY		0x0164 0x03f0 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA19__CSI_DATA11		0x0164 0x03f0 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA19__CSI_DATA11		0x0164 0x03f0 0x04f0 3 1
 #define MX6UL_PAD_LCD_DATA20__EIM_DATA12		0x0168 0x03f4 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA20__GPIO3_IO25		0x0168 0x03f4 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA20__SRC_BT_CFG28		0x0168 0x03f4 0x0000 6 0
@@ -631,12 +656,12 @@
 #define MX6UL_PAD_LCD_DATA20__UART8_DCE_TX		0x0168 0x03f4 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA20__UART8_DTE_RX		0x0168 0x03f4 0x065c 1 2
 #define MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK		0x0168 0x03f4 0x0534 2 0
-#define MX6UL_PAD_LCD_DATA20__CSI_DATA12		0x0168 0x03f4 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA20__CSI_DATA12		0x0168 0x03f4 0x04f4 3 1
 #define MX6UL_PAD_LCD_DATA21__LCDIF_DATA21		0x016c 0x03f8 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA21__UART8_DCE_RX		0x016c 0x03f8 0x065c 1 3
 #define MX6UL_PAD_LCD_DATA21__UART8_DTE_TX		0x016c 0x03f8 0x0000 1 0
-#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0		0x016c 0x03f8 0x0000 2 0
-#define MX6UL_PAD_LCD_DATA21__CSI_DATA13		0x016c 0x03f8 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0		0x016c 0x03f8 0x0540 2 0
+#define MX6UL_PAD_LCD_DATA21__CSI_DATA13		0x016c 0x03f8 0x04f8 3 1
 #define MX6UL_PAD_LCD_DATA21__EIM_DATA13		0x016c 0x03f8 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA21__GPIO3_IO26		0x016c 0x03f8 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA21__SRC_BT_CFG29		0x016c 0x03f8 0x0000 6 0
@@ -644,7 +669,7 @@
 #define MX6UL_PAD_LCD_DATA22__LCDIF_DATA22		0x0170 0x03fc 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA22__MQS_RIGHT			0x0170 0x03fc 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI		0x0170 0x03fc 0x053c 2 0
-#define MX6UL_PAD_LCD_DATA22__CSI_DATA14		0x0170 0x03fc 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA22__CSI_DATA14		0x0170 0x03fc 0x04fc 3 1
 #define MX6UL_PAD_LCD_DATA22__EIM_DATA14		0x0170 0x03fc 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA22__GPIO3_IO27		0x0170 0x03fc 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA22__SRC_BT_CFG30		0x0170 0x03fc 0x0000 6 0
@@ -652,7 +677,7 @@
 #define MX6UL_PAD_LCD_DATA23__LCDIF_DATA23		0x0174 0x0400 0x0000 0 0
 #define MX6UL_PAD_LCD_DATA23__MQS_LEFT			0x0174 0x0400 0x0000 1 0
 #define MX6UL_PAD_LCD_DATA23__ECSPI1_MISO		0x0174 0x0400 0x0538 2 0
-#define MX6UL_PAD_LCD_DATA23__CSI_DATA15		0x0174 0x0400 0x0000 3 0
+#define MX6UL_PAD_LCD_DATA23__CSI_DATA15		0x0174 0x0400 0x0500 3 1
 #define MX6UL_PAD_LCD_DATA23__EIM_DATA15		0x0174 0x0400 0x0000 4 0
 #define MX6UL_PAD_LCD_DATA23__GPIO3_IO28		0x0174 0x0400 0x0000 5 0
 #define MX6UL_PAD_LCD_DATA23__SRC_BT_CFG31		0x0174 0x0400 0x0000 6 0
@@ -660,42 +685,42 @@
 #define MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B		0x0178 0x0404 0x0000 0 0
 #define MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x0178 0x0404 0x0670 1 2
 #define MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK		0x0178 0x0404 0x0000 2 0
-#define MX6UL_PAD_NAND_RE_B__KPP_ROW00			0x0178 0x0404 0x0000 3 0
+#define MX6UL_PAD_NAND_RE_B__KPP_ROW00			0x0178 0x0404 0x05d0 3 1
 #define MX6UL_PAD_NAND_RE_B__EIM_EB_B00			0x0178 0x0404 0x0000 4 0
 #define MX6UL_PAD_NAND_RE_B__GPIO4_IO00			0x0178 0x0404 0x0000 5 0
 #define MX6UL_PAD_NAND_RE_B__ECSPI3_SS2			0x0178 0x0404 0x0000 8 0
 #define MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B		0x017c 0x0408 0x0000 0 0
 #define MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x017c 0x0408 0x0678 1 2
 #define MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B		0x017c 0x0408 0x0000 2 0
-#define MX6UL_PAD_NAND_WE_B__KPP_COL00			0x017c 0x0408 0x0000 3 0
+#define MX6UL_PAD_NAND_WE_B__KPP_COL00			0x017c 0x0408 0x05c4 3 1
 #define MX6UL_PAD_NAND_WE_B__EIM_EB_B01			0x017c 0x0408 0x0000 4 0
 #define MX6UL_PAD_NAND_WE_B__GPIO4_IO01			0x017c 0x0408 0x0000 5 0
 #define MX6UL_PAD_NAND_WE_B__ECSPI3_SS3			0x017c 0x0408 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00		0x0180 0x040c 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x0180 0x040c 0x067c 1 2
 #define MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B		0x0180 0x040c 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA00__KPP_ROW01		0x0180 0x040c 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA00__KPP_ROW01		0x0180 0x040c 0x05d4 3 1
 #define MX6UL_PAD_NAND_DATA00__EIM_AD08			0x0180 0x040c 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA00__GPIO4_IO02		0x0180 0x040c 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA00__ECSPI4_RDY		0x0180 0x040c 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01		0x0184 0x0410 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x0184 0x0410 0x0680 1 2
 #define MX6UL_PAD_NAND_DATA01__QSPI_B_DQS		0x0184 0x0410 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA01__KPP_COL01		0x0184 0x0410 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA01__KPP_COL01		0x0184 0x0410 0x05c8 3 1
 #define MX6UL_PAD_NAND_DATA01__EIM_AD09			0x0184 0x0410 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA01__GPIO4_IO03		0x0184 0x0410 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA01__ECSPI4_SS1		0x0184 0x0410 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02		0x0188 0x0414 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x0188 0x0414 0x0684 1 1
 #define MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00		0x0188 0x0414 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA02__KPP_ROW02		0x0188 0x0414 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA02__KPP_ROW02		0x0188 0x0414 0x05d8 3 1
 #define MX6UL_PAD_NAND_DATA02__EIM_AD10			0x0188 0x0414 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA02__GPIO4_IO04		0x0188 0x0414 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA02__ECSPI4_SS2		0x0188 0x0414 0x0000 8 0
 #define MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03		0x018c 0x0418 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x018c 0x0418 0x0688 1 2
 #define MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01		0x018c 0x0418 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA03__KPP_COL02		0x018c 0x0418 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA03__KPP_COL02		0x018c 0x0418 0x05cc 3 1
 #define MX6UL_PAD_NAND_DATA03__EIM_AD11			0x018c 0x0418 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA03__GPIO4_IO05		0x018c 0x0418 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA03__ECSPI4_SS3		0x018c 0x0418 0x0000 8 0
@@ -726,7 +751,7 @@
 #define MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07		0x019c 0x0428 0x0000 0 0
 #define MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x019c 0x0428 0x0698 1 1
 #define MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B		0x019c 0x0428 0x0000 2 0
-#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0		0x019c 0x0428 0x0000 3 0
+#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0		0x019c 0x0428 0x0570 3 1
 #define MX6UL_PAD_NAND_DATA07__EIM_AD15			0x019c 0x0428 0x0000 4 0
 #define MX6UL_PAD_NAND_DATA07__GPIO4_IO09		0x019c 0x0428 0x0000 5 0
 #define MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS		0x019c 0x0428 0x0628 8 5
@@ -748,7 +773,7 @@
 #define MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B		0x01a8 0x0434 0x0000 0 0
 #define MX6UL_PAD_NAND_READY_B__USDHC1_DATA4		0x01a8 0x0434 0x0000 1 0
 #define MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00		0x01a8 0x0434 0x0000 2 0
-#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0		0x01a8 0x0434 0x0000 3 0
+#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0		0x01a8 0x0434 0x0560 3 1
 #define MX6UL_PAD_NAND_READY_B__EIM_CS1_B		0x01a8 0x0434 0x0000 4 0
 #define MX6UL_PAD_NAND_READY_B__GPIO4_IO12		0x01a8 0x0434 0x0000 5 0
 #define MX6UL_PAD_NAND_READY_B__UART3_DCE_TX		0x01a8 0x0434 0x0000 8 0
@@ -783,7 +808,7 @@
 #define MX6UL_PAD_NAND_DQS__PWM5_OUT			0x01b8 0x0444 0x0000 3 0
 #define MX6UL_PAD_NAND_DQS__EIM_WAIT			0x01b8 0x0444 0x0000 4 0
 #define MX6UL_PAD_NAND_DQS__GPIO4_IO16			0x01b8 0x0444 0x0000 5 0
-#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01		0x01b8 0x0444 0x0000 6 0
+#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01		0x01b8 0x0444 0x0614 6 1
 #define MX6UL_PAD_NAND_DQS__SPDIF_EXT_CLK		0x01b8 0x0444 0x061c 8 1
 #define MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x01bc 0x0448 0x0000 0 0
 #define MX6UL_PAD_SD1_CMD__GPT2_COMPARE1		0x01bc 0x0448 0x0000 1 0
@@ -791,11 +816,11 @@
 #define MX6UL_PAD_SD1_CMD__SPDIF_OUT			0x01bc 0x0448 0x0000 3 0
 #define MX6UL_PAD_SD1_CMD__EIM_ADDR19			0x01bc 0x0448 0x0000 4 0
 #define MX6UL_PAD_SD1_CMD__GPIO2_IO16			0x01bc 0x0448 0x0000 5 0
-#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00		0x01bc 0x0448 0x0000 6 0
+#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00		0x01bc 0x0448 0x0610 6 2
 #define MX6UL_PAD_SD1_CMD__USB_OTG1_PWR			0x01bc 0x0448 0x0000 8 0
 #define MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x01c0 0x044c 0x0000 0 0
 #define MX6UL_PAD_SD1_CLK__GPT2_COMPARE2		0x01c0 0x044c 0x0000 1 0
-#define MX6UL_PAD_SD1_CLK__SAI2_MCLK			0x01c0 0x044c 0x0000 2 0
+#define MX6UL_PAD_SD1_CLK__SAI2_MCLK			0x01c0 0x044c 0x05f0 2 1
 #define MX6UL_PAD_SD1_CLK__SPDIF_IN			0x01c0 0x044c 0x0618 3 3
 #define MX6UL_PAD_SD1_CLK__EIM_ADDR20			0x01c0 0x044c 0x0000 4 0
 #define MX6UL_PAD_SD1_CLK__GPIO2_IO17			0x01c0 0x044c 0x0000 5 0
@@ -878,10 +903,10 @@
 #define MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x01e8 0x0474 0x04c8 0 0
 #define MX6UL_PAD_CSI_DATA01__USDHC2_DATA1		0x01e8 0x0474 0x0680 1 0
 #define MX6UL_PAD_CSI_DATA01__SIM1_PORT1_SVEN		0x01e8 0x0474 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0		0x01e8 0x0474 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0		0x01e8 0x0474 0x0550 3 0
 #define MX6UL_PAD_CSI_DATA01__EIM_AD01			0x01e8 0x0474 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA01__GPIO4_IO22		0x01e8 0x0474 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK			0x01e8 0x0474 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK			0x01e8 0x0474 0x05e0 6 0
 #define MX6UL_PAD_CSI_DATA01__UART5_DCE_RX		0x01e8 0x0474 0x0644 8 1
 #define MX6UL_PAD_CSI_DATA01__UART5_DTE_TX		0x01e8 0x0474 0x0000 8 0
 #define MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x01ec 0x0478 0x04d8 0 1
@@ -913,7 +938,7 @@
 #define MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x01f8 0x0484 0x04e0 0 1
 #define MX6UL_PAD_CSI_DATA05__USDHC2_DATA5		0x01f8 0x0484 0x0690 1 2
 #define MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B		0x01f8 0x0484 0x0000 2 0
-#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0		0x01f8 0x0484 0x0000 3 0
+#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0		0x01f8 0x0484 0x0540 3 1
 #define MX6UL_PAD_CSI_DATA05__EIM_AD05			0x01f8 0x0484 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA05__GPIO4_IO26		0x01f8 0x0484 0x0000 5 0
 #define MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK		0x01f8 0x0484 0x05e8 6 1
@@ -924,7 +949,7 @@
 #define MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI		0x01fc 0x0488 0x053c 3 1
 #define MX6UL_PAD_CSI_DATA06__EIM_AD06			0x01fc 0x0488 0x0000 4 0
 #define MX6UL_PAD_CSI_DATA06__GPIO4_IO27		0x01fc 0x0488 0x0000 5 0
-#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA		0x01fc 0x0488 0x0000 6 0
+#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA		0x01fc 0x0488 0x05e4 6 1
 #define MX6UL_PAD_CSI_DATA06__USDHC1_RESET_B		0x01fc 0x0488 0x0000 8 0
 #define MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x0200 0x048c 0x04e8 0 1
 #define MX6UL_PAD_CSI_DATA07__USDHC2_DATA7		0x0200 0x048c 0x0698 1 2
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 3/7] ARM: dts: imx6ull: add additional pinfunc defines for i.MX 6ULL
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

From: Bai Ping <ping.bai@nxp.com>

On i.MX 6ULL, the pin MUX and CTRL register of BOOT_MODEx and TAMPERx
pins are available through IOMUXC_SNVS. Add additional pinfunc defines.

Signed-off-by: Bai Ping <ping.bai@nxp.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 arch/arm/boot/dts/imx6ull-pinfunc-snvs.h | 27 +++++++++++++++++++++++++++
 arch/arm/boot/dts/imx6ull.dtsi           |  1 +
 2 files changed, 28 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6ull-pinfunc-snvs.h

diff --git a/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
new file mode 100644
index 000000000000..fa900c15405d
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright (C) 2017 NXP
+ */
+
+#ifndef __DTS_IMX6ULL_PINFUNC_SNVS_H
+#define __DTS_IMX6ULL_PINFUNC_SNVS_H
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10                          0x0000 0x0044 0x0000 0x5 0x0
+#define MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11                          0x0004 0x0048 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00                        0x0008 0x004C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01                        0x000C 0x0050 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02                        0x0010 0x0054 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03                        0x0014 0x0058 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04                        0x0018 0x005C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05                        0x001C 0x0060 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06                        0x0020 0x0064 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07                        0x0024 0x0068 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08                        0x0028 0x006C 0x0000 0x5 0x0
+#define MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09                        0x002C 0x0070 0x0000 0x5 0x0
+
+#endif /* __DTS_IMX6ULL_PINFUNC_SNVS_H */
+
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index 0c182917b863..a58c01dc15c3 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -41,3 +41,4 @@
 
 #include "imx6ul.dtsi"
 #include "imx6ull-pinfunc.h"
+#include "imx6ull-pinfunc-snvs.h"
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 4/7] ARM: dts: imx6ul: add interrupt of virt-capable GIC
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

The Cortex-A7 and its GIC support virtualization extensions. To
make use of them the CPU private interrupt needs to be specified.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 1b14e4d39c26..993fbdbdd506 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -100,8 +100,10 @@
 
 	intc: interrupt-controller at a01000 {
 		compatible = "arm,gic-400", "arm,cortex-a7-gic";
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		#interrupt-cells = <3>;
 		interrupt-controller;
+		interrupt-parent = <&intc>;
 		reg = <0x00a01000 0x1000>,
 		      <0x00a02000 0x2000>,
 		      <0x00a04000 0x2000>,
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 5/7] ARM: dts: imx6ul: add ARM architected timer
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

Add per-core ARM architected timer. Unfortunately bootloaders (U-Boot)
currently do not make the necessary initialization. Also specifing the
clock manually using the clock-frequency property seems not to help.
Therefor leave the timer disabled by default for now.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 arch/arm/boot/dts/imx6ul.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 993fbdbdd506..4d76923e8f44 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -110,6 +110,16 @@
 		      <0x00a06000 0x2000>;
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		interrupt-parent = <&intc>;
+		status = "disabled";
+	};
+
 	ckil: clock-cli {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 6/7] ARM: dts: imx6ull: add IOMUXC SNVS instance
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

The i.MX 6ULL features another IOMUX Controller called IOMUXC
SNVS which allows to control BOOT_MODE and TAMPER pins. Add the
controller to the i.MX 6ULL specific imx6ull.dtsi device tree.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 arch/arm/boot/dts/imx6ull.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index a58c01dc15c3..bc2cd4fb8b12 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -42,3 +42,20 @@
 #include "imx6ul.dtsi"
 #include "imx6ull-pinfunc.h"
 #include "imx6ull-pinfunc-snvs.h"
+
+/ {
+	soc {
+		aips3: aips-bus at 2200000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x02200000 0x100000>;
+			ranges;
+
+			iomuxc_snvs: iomuxc-snvs at 2290000 {
+				compatible = "fsl,imx6ull-iomuxc-snvs";
+				reg = <0x02290000 0x4000>;
+			};
+		};
+	};
+};
-- 
2.15.1

^ permalink raw reply related

* [PATCH v2 7/7] ARM: dts: imx6ull: add UART8 support
From: Stefan Agner @ 2018-01-10 21:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110210453.19264-1-stefan@agner.ch>

In i.MX 6ULL UART8 is part of the AIPS-3 memory map instead of
AIPS-1. Clocks and interrupts remain the same.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
---
 arch/arm/boot/dts/imx6ull.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index bc2cd4fb8b12..571ddd71cdba 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -43,6 +43,9 @@
 #include "imx6ull-pinfunc.h"
 #include "imx6ull-pinfunc-snvs.h"
 
+/* Delete UART8 in AIPS-1 (i.MX6UL specific) */
+/delete-node/ &uart8;
+
 / {
 	soc {
 		aips3: aips-bus at 2200000 {
@@ -56,6 +59,17 @@
 				compatible = "fsl,imx6ull-iomuxc-snvs";
 				reg = <0x02290000 0x4000>;
 			};
+
+			uart8: serial at 2288000 {
+				compatible = "fsl,imx6ul-uart",
+					     "fsl,imx6q-uart";
+				reg = <0x02288000 0x4000>;
+				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6UL_CLK_UART8_IPG>,
+					 <&clks IMX6UL_CLK_UART8_SERIAL>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
2.15.1

^ permalink raw reply related

* [PATCH] arm64: dts: add #cooling-cells to CPU nodes
From: Arnd Bergmann @ 2018-01-10 21:06 UTC (permalink / raw)
  To: linux-arm-kernel

dtc complains about the lack of #coolin-cells properties for the
CPU nodes that are referred to as "cooling-device":

arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: Warning (cooling_device_property): Missing property '#cooling-cells' in node /cpus/cpu at 0 or bad phandle (referred from /thermal-zones/cpu_thermal/cooling-maps/map at 0:cooling-device[0])
arch/arm64/boot/dts/mediatek/mt8173-evb.dtb: Warning (cooling_device_property): Missing property '#cooling-cells' in node /cpus/cpu at 100 or bad phandle (referred from /thermal-zones/cpu_thermal/cooling-maps/map at 1:cooling-device[0])

Apparently this property must be '<2>' to match the binding.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
If this looks ok, I'd apply it directly to the fixes branch
for 4.15, as the warning is one that was introduced in this
release.
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index b477ad790071..9fbe4705ee88 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -155,6 +155,7 @@
 			reg = <0x000>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			#cooling-cells = <2>;
 			clocks = <&infracfg CLK_INFRA_CA53SEL>,
 				 <&apmixedsys CLK_APMIXED_MAINPLL>;
 			clock-names = "cpu", "intermediate";
@@ -179,6 +180,7 @@
 			reg = <0x100>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			#cooling-cells = <2>;
 			clocks = <&infracfg CLK_INFRA_CA57SEL>,
 				 <&apmixedsys CLK_APMIXED_MAINPLL>;
 			clock-names = "cpu", "intermediate";
-- 
2.9.0

^ permalink raw reply related

* [PATCH -next] clk: meson-axg: fix potential NULL dereference in axg_clkc_probe()
From: Stephen Boyd @ 2018-01-10 21:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515117059-176004-1-git-send-email-weiyongjun1@huawei.com>

On 01/05, Wei Yongjun wrote:
> platform_get_resource() may return NULL, add proper
> check to avoid potential NULL dereferencing.
> 
> This is detected by Coccinelle semantic patch.
> 
> @@
> expression pdev, res, n, t, e, e1, e2;
> @@
> 
> res = platform_get_resource(pdev, t, n);
> + if (!res)
> +   return -EINVAL;
> ... when != res == NULL
> e = devm_ioremap(e1, res->start, e2);

Can this script be put into scripts/coccinelle/? I'd like to be
able to run it instead of getting emails from you after patches
merge.

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

^ permalink raw reply

* [PATCH -next] clk: meson-axg: fix potential NULL dereference in axg_clkc_probe()
From: Stephen Boyd @ 2018-01-10 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515117059-176004-1-git-send-email-weiyongjun1@huawei.com>

On 01/05, Wei Yongjun wrote:
> platform_get_resource() may return NULL, add proper
> check to avoid potential NULL dereferencing.
> 
> This is detected by Coccinelle semantic patch.
> 
> @@
> expression pdev, res, n, t, e, e1, e2;
> @@
> 
> res = platform_get_resource(pdev, t, n);
> + if (!res)
> +   return -EINVAL;
> ... when != res == NULL
> e = devm_ioremap(e1, res->start, e2);
> 
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
> ---

Applied to clk-next

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

^ permalink raw reply

* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Jae Hyun Yoo @ 2018-01-10 21:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110202740.GA27703@kroah.com>

On 1/10/2018 12:27 PM, Greg KH wrote:
> On Wed, Jan 10, 2018 at 11:30:05AM -0800, Jae Hyun Yoo wrote:
>> On 1/10/2018 11:17 AM, Greg KH wrote:
>>> On Wed, Jan 10, 2018 at 11:14:34AM -0800, Jae Hyun Yoo wrote:
>>>> On 1/10/2018 2:17 AM, Greg KH wrote:
>>>>> On Tue, Jan 09, 2018 at 02:31:20PM -0800, Jae Hyun Yoo wrote:
>>>>>> From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> This patch set provides support for PECI of AST2400/2500 which can give us PECI
>>>>>> functionalities such as temperature monitoring, platform manageability,
>>>>>> processor diagnostics and failure analysis. Also provides generic peci.h and
>>>>>> peci_ioctl.h headers to provide compatibility to peci drivers that can be
>>>>>> implemented later e.g. Nuvoton's BMC SoC family.
>>>>>
>>>>> What is the "dev-4.10" in the subject for?  4.10 is really old and
>>>>> obsolete :(
>>>>>
>>>>> thanks,
>>>>>
>>>>> greg k-h
>>>>>
>>>>
>>>> I made this patch set on top of the v4.10 which OpenBmc project is currently
>>>> using. I'll rebase this patch set onto the current kernel.org mainline.
>>>
>>> What is "OpenBmc", and why are they using an obsolete and insecure
>>> kernel for their project?  That seems like a very foolish thing to do...
>>>
>>> thanks,
>>>
>>> greg k-h
>>>
>>
>> OpenBmc is an open source project to create a highly extensible framework
>> for BMC (Board Management Controller) software for data-center computer
>> systems:
>> https://github.com/openbmc
>>
>> Its current mainline is v4.10 but it is being kept upgrading so it will be
>> upgraded to the latest stable or long-term version soon.
> 
> Why hasn't it been updated in the year since 4.10 was released?  That's
> a _very_ long time to be running on a totally insecure kernel, and no
> new development should ever be done on old kernels, that's even crazier
> (as we can't go back in time and accept patches for new features to old
> releases...)
> 

Thanks for your pointing it out and I totally agree with you. Actually, 
we are preparing 4.13 update for now and an another update will be 
followed up. As I answered above, I'll rebase this patch set onto the 
latest kernel.org mainline. Sorry for my misunderstanding of upstream 
process.

> It sounds like the openbmc project needs to learn how to manage their
> kernels a whole lot better, who do I need to go poke about this?
>  > thanks,
> 
> greg k-h
> 

I've already cc'ed openbmc developers so they are also seeing this 
thread. Joel Stanley <joel@jms.id.au> is the openbmc kernel maintainer.

Thanks,
Jae

^ permalink raw reply

* [linux, dev-4.10, 6/6] drivers/hwmon: Add a driver for a generic PECI hwmon
From: Guenter Roeck @ 2018-01-10 21:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180109223126.13093-7-jae.hyun.yoo@linux.intel.com>

On Tue, Jan 09, 2018 at 02:31:26PM -0800, Jae Hyun Yoo wrote:
> This commit adds driver implementation for a generic PECI hwmon.
> 
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
> ---
>  drivers/hwmon/Kconfig      |   6 +
>  drivers/hwmon/Makefile     |   1 +
>  drivers/hwmon/peci-hwmon.c | 953 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 960 insertions(+)
>  create mode 100644 drivers/hwmon/peci-hwmon.c
> 
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 9256dd0..3a62c60 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1234,6 +1234,12 @@ config SENSORS_NCT7904
>  	  This driver can also be built as a module.  If so, the module
>  	  will be called nct7904.
>  
> +config SENSORS_PECI_HWMON
> +	tristate "PECI hwmon support"
> +	depends on ASPEED_PECI
> +	help
> +	  If you say yes here you get support for the generic PECI hwmon driver.
> +
>  config SENSORS_NSA320
>  	tristate "ZyXEL NSA320 and compatible fan speed and temperature sensors"
>  	depends on GPIOLIB && OF
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 98000fc..41d43a5 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -131,6 +131,7 @@ obj-$(CONFIG_SENSORS_NCT7802)	+= nct7802.o
>  obj-$(CONFIG_SENSORS_NCT7904)	+= nct7904.o
>  obj-$(CONFIG_SENSORS_NSA320)	+= nsa320-hwmon.o
>  obj-$(CONFIG_SENSORS_NTC_THERMISTOR)	+= ntc_thermistor.o
> +obj-$(CONFIG_SENSORS_PECI_HWMON)	+= peci-hwmon.o
>  obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
>  obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
>  obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
> diff --git a/drivers/hwmon/peci-hwmon.c b/drivers/hwmon/peci-hwmon.c
> new file mode 100644
> index 0000000..2d2a288
> --- /dev/null
> +++ b/drivers/hwmon/peci-hwmon.c
> @@ -0,0 +1,953 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Intel Corporation
> +
> +#include <linux/delay.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/syscalls.h>
> +#include <misc/peci.h>

misc, not linux ? That seems wrong.

> +
> +#define DEVICE_NAME "peci-hwmon"
> +#define HWMON_NAME "peci_hwmon"
> +
> +#define CPU_ID_MAX           8   /* Max CPU number configured by socket ID */
> +#define DIMM_NUMS_MAX        16  /* Max DIMM numbers (channel ranks x 2) */
> +#define CORE_NUMS_MAX        28  /* Max core numbers (max on SKX Platinum) */

I won't insist, but it would be better if this were dynamic,
otherwise we'll end up having to increase the defines in the future.

> +#define TEMP_TYPE_PECI       6   /* Sensor type 6: Intel PECI */
> +#define CORE_INDEX_OFFSET    100 /* sysfs filename start offset for core temp */
> +#define DIMM_INDEX_OFFSET    200 /* sysfs filename start offset for DIMM temp */

Did you test with the "sensors" command to ensure that this works,
with the large gaps in index values ?

Overall, I am not very happy with the indexing. Since each sensor as
a label, it might be better to just make it dynamic.

> +#define TEMP_NAME_HEADER_LEN 4   /* sysfs temp type header length */
> +#define OF_DIMM_NUMS_DEFAULT 16  /* default dimm-nums setting */
> +
> +#define CORE_TEMP_ATTRS      5
> +#define DIMM_TEMP_ATTRS      2
> +#define ATTR_NAME_LEN        24
> +
> +#define UPDATE_INTERVAL_MIN  HZ
> +
> +enum sign_t {
> +	POS,
> +	NEG
> +};
> +
> +struct cpuinfo_t {
> +	bool valid;
> +	u32  dib;
> +	u8   cpuid;
> +	u8   platform_id;
> +	u32  microcode;
> +	u8   logical_thread_nums;
> +};
> +
> +struct temp_data_t {
> +	bool valid;
> +	s32  value;
> +	unsigned long last_updated;
> +};
> +
> +struct temp_group_t {
> +	struct temp_data_t tjmax;
> +	struct temp_data_t tcontrol;
> +	struct temp_data_t tthrottle;
> +	struct temp_data_t dts_margin;
> +	struct temp_data_t die;
> +	struct temp_data_t core[CORE_NUMS_MAX];
> +	struct temp_data_t dimm[DIMM_NUMS_MAX];
> +};
> +
> +struct core_temp_attr_group_t {
> +	struct sensor_device_attribute sd_attrs[CORE_NUMS_MAX][CORE_TEMP_ATTRS];
> +	char attr_name[CORE_NUMS_MAX][CORE_TEMP_ATTRS][ATTR_NAME_LEN];
> +	struct attribute *attrs[CORE_NUMS_MAX][CORE_TEMP_ATTRS + 1];
> +	struct attribute_group attr_group[CORE_NUMS_MAX];
> +};
> +
> +struct dimm_temp_attr_group_t {
> +	struct sensor_device_attribute sd_attrs[DIMM_NUMS_MAX][DIMM_TEMP_ATTRS];
> +	char attr_name[DIMM_NUMS_MAX][DIMM_TEMP_ATTRS][ATTR_NAME_LEN];
> +	struct attribute *attrs[DIMM_NUMS_MAX][DIMM_TEMP_ATTRS + 1];
> +	struct attribute_group attr_group[DIMM_NUMS_MAX];
> +};
> +
> +struct peci_hwmon {
> +	struct device *dev;
> +	struct device *hwmon_dev;
> +	char name[NAME_MAX];
> +	const struct attribute_group **groups;
> +	struct cpuinfo_t cpuinfo;
> +	struct temp_group_t temp;
> +	u32 cpu_id;
> +	bool show_core;
> +	u32 core_nums;
> +	u32 dimm_nums;
> +	atomic_t core_group_created;
> +	struct core_temp_attr_group_t core;
> +	struct dimm_temp_attr_group_t dimm;
> +};
> +
> +enum label_t {
> +	L_DIE,
> +	L_DTS,
> +	L_TCONTROL,
> +	L_TTHROTTLE,
> +	L_MAX
> +};
> +
> +static const char *peci_label[L_MAX] = {
> +	"Die temperature\n",
> +	"DTS thermal margin to Tcontrol\n",
> +	"Tcontrol temperature\n",
> +	"Tthrottle temperature\n",

"temperature" is redundant for a temperature label.

> +};
> +
> +static DEFINE_MUTEX(peci_hwmon_lock);
> +
> +static int create_core_temp_group(struct peci_hwmon *priv, int core_no);

Please avoid forward declarations.

> +
> +

Please run your patches throuch checkpatch --strict and fix what it reports,
or provide a reason why you don't.

> +static int xfer_peci_msg(int cmd, void *pmsg)
> +{
> +	int rc;
> +
> +	mutex_lock(&peci_hwmon_lock);
> +	rc = peci_ioctl(NULL, cmd, (unsigned long)pmsg);
> +	mutex_unlock(&peci_hwmon_lock);
> +
> +	return rc;
> +}
> +
> +static int get_cpuinfo(struct peci_hwmon *priv)
> +{
> +	struct peci_get_dib_msg dib_msg;
> +	struct peci_rd_pkg_cfg_msg cfg_msg;
> +	int rc, i;
> +
> +	if (!priv->cpuinfo.valid) {
> +		dib_msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +
> +		rc = xfer_peci_msg(PECI_IOC_GET_DIB, (void *)&dib_msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->cpuinfo.dib = dib_msg.dib;
> +
> +		cfg_msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +		cfg_msg.index = MBX_INDEX_CPU_ID;
> +		cfg_msg.param = 0;
> +		cfg_msg.rx_len = 4;
> +
> +		rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&cfg_msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->cpuinfo.cpuid = cfg_msg.pkg_config[0];
> +
> +		cfg_msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +		cfg_msg.index = MBX_INDEX_CPU_ID;
> +		cfg_msg.param = 1;
> +		cfg_msg.rx_len = 4;
> +
> +		rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&cfg_msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->cpuinfo.platform_id = cfg_msg.pkg_config[0];
> +
> +		cfg_msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +		cfg_msg.index = MBX_INDEX_CPU_ID;
> +		cfg_msg.param = 3;
> +		cfg_msg.rx_len = 4;
> +
> +		rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&cfg_msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->cpuinfo.logical_thread_nums = cfg_msg.pkg_config[0] + 1;
> +
> +		cfg_msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +		cfg_msg.index = MBX_INDEX_CPU_ID;
> +		cfg_msg.param = 4;
> +		cfg_msg.rx_len = 4;
> +
> +		rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&cfg_msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->cpuinfo.microcode = (cfg_msg.pkg_config[3] << 24) |
> +					  (cfg_msg.pkg_config[2] << 16) |
> +					  (cfg_msg.pkg_config[1] << 8) |
> +					  cfg_msg.pkg_config[0];
> +
> +		priv->core_nums = priv->cpuinfo.logical_thread_nums / 2;

This seems to assume a 1:2 relationship between number of threads and
number of CPUs, which is incorrect.

> +
> +		if (priv->show_core &&
> +		    atomic_inc_return(&priv->core_group_created) == 1) {
> +			for (i = 0; i < priv->core_nums; i++) {
> +				rc = create_core_temp_group(priv, i);

This is messy. Sensor groups should be created before or during
hwmon registration, not at some arbitrary later time.

I don't know the logic behind this, but if it is supposed to track CPUs
coming online and going offline it is the wrong approach.

> +				if (rc != 0) {
> +					dev_err(priv->dev,
> +						"Failed to create core temp group\n");
> +					for (--i; i >= 0; i--) {
> +						sysfs_remove_group(
> +						     &priv->hwmon_dev->kobj,
> +						     &priv->core.attr_group[i]);
> +					}
> +					atomic_set(&priv->core_group_created,
> +						   0);
> +					return rc;
> +				}
> +			}
> +		}
> +
> +		priv->cpuinfo.valid = true;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_tjmax(struct peci_hwmon *priv)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	int rc;
> +
> +	rc = get_cpuinfo(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	if (!priv->temp.tjmax.valid) {
> +		msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +		msg.index = MBX_INDEX_TEMP_TARGET;
> +		msg.param = 0;
> +		msg.rx_len = 4;
> +
> +		rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +		if (rc < 0)
> +			return rc;
> +
> +		priv->temp.tjmax.value = (s32)msg.pkg_config[2] * 1000;
> +		priv->temp.tjmax.valid = true;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_tcontrol(struct peci_hwmon *priv)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	s32 tcontrol_margin;
> +	int rc;
> +
> +	if (priv->temp.tcontrol.valid &&
> +	    time_before(jiffies, priv->temp.tcontrol.last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +

Is the delay necessary ? Otherwise I would suggest to drop it.
It adds a lot of complexity to the driver. Also, if the user polls
values more often, that is presumably on purpose.

> +	rc = get_tjmax(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +	msg.index = MBX_INDEX_TEMP_TARGET;
> +	msg.param = 0;
> +	msg.rx_len = 4;
> +
> +	rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	tcontrol_margin = msg.pkg_config[1];
> +	tcontrol_margin = ((tcontrol_margin ^ 0x80) - 0x80) * 1000;
> +
> +	priv->temp.tcontrol.value = priv->temp.tjmax.value - tcontrol_margin;
> +
> +	if (!priv->temp.tcontrol.valid) {
> +		priv->temp.tcontrol.last_updated = INITIAL_JIFFIES;
> +		priv->temp.tcontrol.valid = true;
> +	} else {
> +		priv->temp.tcontrol.last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_tthrottle(struct peci_hwmon *priv)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	s32 tthrottle_offset;
> +	int rc;
> +
> +	if (priv->temp.tthrottle.valid &&
> +	    time_before(jiffies, priv->temp.tthrottle.last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +
> +	rc = get_tjmax(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +	msg.index = MBX_INDEX_TEMP_TARGET;
> +	msg.param = 0;
> +	msg.rx_len = 4;
> +
> +	rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	tthrottle_offset = (msg.pkg_config[3] & 0x2f) * 1000;
> +	priv->temp.tthrottle.value = priv->temp.tjmax.value - tthrottle_offset;
> +
> +	if (!priv->temp.tthrottle.valid) {
> +		priv->temp.tthrottle.last_updated = INITIAL_JIFFIES;
> +		priv->temp.tthrottle.valid = true;
> +	} else {
> +		priv->temp.tthrottle.last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_die_temp(struct peci_hwmon *priv)
> +{
> +	struct peci_get_temp_msg msg;
> +	int rc;
> +
> +	if (priv->temp.die.valid &&
> +	    time_before(jiffies, priv->temp.die.last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +
> +	rc = get_tjmax(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +
> +	rc = xfer_peci_msg(PECI_IOC_GET_TEMP, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	priv->temp.die.value = priv->temp.tjmax.value +
> +			       ((s32)msg.temp_raw * 1000 / 64);
> +
> +	if (!priv->temp.die.valid) {
> +		priv->temp.die.last_updated = INITIAL_JIFFIES;
> +		priv->temp.die.valid = true;
> +	} else {
> +		priv->temp.die.last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_dts_margin(struct peci_hwmon *priv)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	s32 dts_margin;
> +	int rc;
> +
> +	if (priv->temp.dts_margin.valid &&
> +	    time_before(jiffies, priv->temp.dts_margin.last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +
Are all those values expected to change dynamically, or are some static ?
Static values do not have to be re-read repeatedly but can be cached
permanently.

> +	rc = get_cpuinfo(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +	msg.index = MBX_INDEX_DTS_MARGIN;
> +	msg.param = 0;
> +	msg.rx_len = 4;
> +
> +	rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	dts_margin = (msg.pkg_config[1] << 8) | msg.pkg_config[0];
> +
> +	/*
> +	 * Processors return a value of DTS reading in 10.6 format
> +	 * (10 bits signed decimal, 6 bits fractional).
> +	 * Error codes:
> +	 *   0x8000: General sensor error
> +	 *   0x8001: Reserved
> +	 *   0x8002: Underflow on reading value
> +	 *   0x8003-0x81ff: Reserved
> +	 */
> +	if (dts_margin >= 0x8000 && dts_margin <= 0x81ff)
> +		return -1;
> +
> +	dts_margin = ((dts_margin ^ 0x8000) - 0x8000) * 1000 / 64;
> +
The above code is repeated several times. Please consider moving it
into a function to reduce duplication.

> +	priv->temp.dts_margin.value = dts_margin;
> +
> +	if (!priv->temp.dts_margin.valid) {
> +		priv->temp.dts_margin.last_updated = INITIAL_JIFFIES;
> +		priv->temp.dts_margin.valid = true;
> +	} else {
> +		priv->temp.dts_margin.last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_core_temp(struct peci_hwmon *priv, int core_index)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	s32 core_dts_margin;
> +	int rc;
> +
> +	if (priv->temp.core[core_index].valid &&
> +	    time_before(jiffies, priv->temp.core[core_index].last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +
> +	rc = get_tjmax(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +	msg.index = MBX_INDEX_PER_CORE_DTS_TEMP;
> +	msg.param = core_index;
> +	msg.rx_len = 4;
> +
> +	rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	core_dts_margin = (msg.pkg_config[1] << 8) | msg.pkg_config[0];
> +
> +	/*
> +	 * Processors return a value of the core DTS reading in 10.6 format
> +	 * (10 bits signed decimal, 6 bits fractional).
> +	 * Error codes:
> +	 *   0x8000: General sensor error
> +	 *   0x8001: Reserved
> +	 *   0x8002: Underflow on reading value
> +	 *   0x8003-0x81ff: Reserved
> +	 */
> +	if (core_dts_margin >= 0x8000 && core_dts_margin <= 0x81ff)
> +		return -1;
> +
> +	core_dts_margin = ((core_dts_margin ^ 0x8000) - 0x8000) * 1000 / 64;
> +
> +	priv->temp.core[core_index].value = priv->temp.tjmax.value +
> +					    core_dts_margin;
> +
> +	if (!priv->temp.core[core_index].valid) {
> +		priv->temp.core[core_index].last_updated = INITIAL_JIFFIES;
> +		priv->temp.core[core_index].valid = true;
> +	} else {
> +		priv->temp.core[core_index].last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_dimm_temp(struct peci_hwmon *priv, int dimm_index)
> +{
> +	struct peci_rd_pkg_cfg_msg msg;
> +	int channel_rank = dimm_index / 2;
> +	int dimm_order = dimm_index % 2;
> +	int rc;
> +
> +	if (priv->temp.core[dimm_index].valid &&
> +	    time_before(jiffies, priv->temp.core[dimm_index].last_updated +
> +				 UPDATE_INTERVAL_MIN))
> +		return 0;
> +
> +	rc = get_cpuinfo(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	msg.target = PECI_BASE_ADDR + priv->cpu_id;
> +	msg.index = MBX_INDEX_DDR_DIMM_TEMP;
> +	msg.param = channel_rank;
> +	msg.rx_len = 4;
> +
> +	rc = xfer_peci_msg(PECI_IOC_RD_PKG_CFG, (void *)&msg);
> +	if (rc < 0)
> +		return rc;
> +
> +	priv->temp.dimm[dimm_index].value = msg.pkg_config[dimm_order] * 1000;
> +
> +	if (!priv->temp.dimm[dimm_index].valid) {
> +		priv->temp.dimm[dimm_index].last_updated = INITIAL_JIFFIES;
> +		priv->temp.dimm[dimm_index].valid = true;
> +	} else {
> +		priv->temp.dimm[dimm_index].last_updated = jiffies;
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t show_info(struct device *dev,
> +			 struct device_attribute *attr,
> +			 char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_cpuinfo(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "dib         : 0x%08x\n"
> +			    "cpuid       : 0x%x\n"
> +			    "platform id : %d\n"
> +			    "stepping    : %d\n"
> +			    "microcode   : 0x%08x\n"
> +			    "logical thread nums : %d\n",
> +			    priv->cpuinfo.dib,
> +			    priv->cpuinfo.cpuid,
> +			    priv->cpuinfo.platform_id,
> +			    priv->cpuinfo.cpuid & 0xf,
> +			    priv->cpuinfo.microcode,
> +			    priv->cpuinfo.logical_thread_nums);
> +}

Please no non-standard attributes, much less attributes not following sysfs
attribute rules. If you want to display such information, consider using
debugfs. Besides, this information specifically appears to duplicate
the content of /proc/cpuid, which doesn't really add any value at all.

> +
> +static ssize_t show_tcontrol(struct device *dev,
> +			     struct device_attribute *attr,
> +			     char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_tcontrol(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.tcontrol.value);
> +}
> +
> +static ssize_t show_tcontrol_margin(struct device *dev,
> +				    struct device_attribute *attr,
> +				    char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int rc;
> +
> +	rc = get_tcontrol(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", sensor_attr->index == POS ?
> +				    priv->temp.tjmax.value -
> +				    priv->temp.tcontrol.value :
> +				    priv->temp.tcontrol.value -
> +				    priv->temp.tjmax.value);
> +}
> +
> +static ssize_t show_tthrottle(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_tthrottle(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.tthrottle.value);
> +}
> +
> +static ssize_t show_tjmax(struct device *dev,
> +			  struct device_attribute *attr,
> +			  char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_tjmax(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.tjmax.value);
> +}
> +
> +static ssize_t show_die_temp(struct device *dev,
> +			     struct device_attribute *attr,
> +			     char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_die_temp(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.die.value);
> +}
> +
> +static ssize_t show_dts_therm_margin(struct device *dev,
> +				     struct device_attribute *attr,
> +				     char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	int rc;
> +
> +	rc = get_dts_margin(priv);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.dts_margin.value);
> +}
> +
> +static ssize_t show_core_temp(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int core_index = sensor_attr->index;
> +	int rc;
> +
> +	rc = get_core_temp(priv, core_index);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.core[core_index].value);
> +}
> +
> +static ssize_t show_dimm_temp(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(dev);
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +	int dimm_index = sensor_attr->index;
> +	int rc;
> +
> +	rc = get_dimm_temp(priv, dimm_index);
> +	if (rc < 0)
> +		return rc;
> +
> +	return sprintf(buf, "%d\n", priv->temp.dimm[dimm_index].value);
> +}
> +
> +static ssize_t show_value(struct device *dev,
> +			  struct device_attribute *attr,
> +			  char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +
> +	return sprintf(buf, "%d\n", sensor_attr->index);
> +}
> +
> +static ssize_t show_label(struct device *dev,
> +			  struct device_attribute *attr,
> +			  char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +
> +	return sprintf(buf, peci_label[sensor_attr->index]);
> +}
> +
> +static ssize_t show_core_label(struct device *dev,
> +			       struct device_attribute *attr,
> +			       char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +
> +	return sprintf(buf, "Core #%d temperature\n", sensor_attr->index);
> +}

Your label strings are quite long. How does that look like with the
sensors command ?

Plus, again, "temperature" in a temperature label is redundant.

> +
> +static ssize_t show_dimm_label(struct device *dev,
> +			       struct device_attribute *attr,
> +			       char *buf)
> +{
> +	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
> +
> +	char channel = 'A' + (sensor_attr->index / 2);
> +	int index = sensor_attr->index % 2;
> +
> +	return sprintf(buf, "Channel Rank %c DDR DIMM #%d temperature\n",
> +		       channel, index);
> +}
> +
> +/* Die temperature */
> +static SENSOR_DEVICE_ATTR(temp1_label, 0444, show_label, NULL, L_DIE);
> +static SENSOR_DEVICE_ATTR(temp1_input, 0444, show_die_temp, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp1_max, 0444, show_tcontrol, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp1_crit, 0444, show_tjmax, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, 0444, show_tcontrol_margin, NULL,
> +			  POS);
> +
> +static struct attribute *die_temp_attrs[] = {
> +	&sensor_dev_attr_temp1_label.dev_attr.attr,
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_temp1_max.dev_attr.attr,
> +	&sensor_dev_attr_temp1_crit.dev_attr.attr,
> +	&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group die_temp_attr_group = {
> +	.attrs = die_temp_attrs,
> +};
> +
> +/* DTS thermal margin temperature */
> +static SENSOR_DEVICE_ATTR(temp2_label, 0444, show_label, NULL, L_DTS);
> +static SENSOR_DEVICE_ATTR(temp2_input, 0444, show_dts_therm_margin, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp2_min, 0444, show_value, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp2_lcrit, 0444, show_tcontrol_margin, NULL, NEG);
> +
> +static struct attribute *dts_margin_temp_attrs[] = {
> +	&sensor_dev_attr_temp2_label.dev_attr.attr,
> +	&sensor_dev_attr_temp2_input.dev_attr.attr,
> +	&sensor_dev_attr_temp2_min.dev_attr.attr,
> +	&sensor_dev_attr_temp2_lcrit.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group dts_margin_temp_attr_group = {
> +	.attrs = dts_margin_temp_attrs,
> +};
> +
> +/* Tcontrol temperature */
> +static SENSOR_DEVICE_ATTR(temp3_label, 0444, show_label, NULL, L_TCONTROL);
> +static SENSOR_DEVICE_ATTR(temp3_input, 0444, show_tcontrol, NULL, 0);
> +static SENSOR_DEVICE_ATTR(temp3_crit, 0444, show_tjmax, NULL, 0);
> +
> +static struct attribute *tcontrol_temp_attrs[] = {
> +	&sensor_dev_attr_temp3_label.dev_attr.attr,
> +	&sensor_dev_attr_temp3_input.dev_attr.attr,
> +	&sensor_dev_attr_temp3_crit.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group tcontrol_temp_attr_group = {
> +	.attrs = tcontrol_temp_attrs,
> +};
> +
> +/* Tthrottle temperature */
> +static SENSOR_DEVICE_ATTR(temp4_label, 0444, show_label, NULL, L_TTHROTTLE);
> +static SENSOR_DEVICE_ATTR(temp4_input, 0444, show_tthrottle, NULL, 0);
> +
> +static struct attribute *tthrottle_temp_attrs[] = {
> +	&sensor_dev_attr_temp4_label.dev_attr.attr,
> +	&sensor_dev_attr_temp4_input.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group tthrottle_temp_attr_group = {
> +	.attrs = tthrottle_temp_attrs,
> +};
> +
> +/* CPU info */
> +static SENSOR_DEVICE_ATTR(info, 0444, show_info, NULL, 0);
> +
> +static struct attribute *info_attrs[] = {
> +	&sensor_dev_attr_info.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group info_attr_group = {
> +	.attrs = info_attrs,
> +};
> +
> +const struct attribute_group *peci_hwmon_attr_groups[] = {
> +	&info_attr_group,
> +	&die_temp_attr_group,
> +	&dts_margin_temp_attr_group,
> +	&tcontrol_temp_attr_group,
> +	&tthrottle_temp_attr_group,
> +	NULL
> +};
> +
> +static ssize_t (*const core_show_fn[CORE_TEMP_ATTRS]) (struct device *dev,
> +		struct device_attribute *devattr, char *buf) = {
> +	show_core_label,
> +	show_core_temp,
> +	show_tcontrol,
> +	show_tjmax,
> +	show_tcontrol_margin,
> +};
> +
> +static const char *const core_suffix[CORE_TEMP_ATTRS] = {
> +	"label",
> +	"input",
> +	"max",
> +	"crit",
> +	"crit_hyst",
> +};
> +
> +static int create_core_temp_group(struct peci_hwmon *priv, int core_no)
> +{
> +	int i;
> +
> +	for (i = 0; i < CORE_TEMP_ATTRS; i++) {
> +		snprintf(priv->core.attr_name[core_no][i],
> +			 ATTR_NAME_LEN, "temp%d_%s",
> +			 CORE_INDEX_OFFSET + core_no, core_suffix[i]);
> +		sysfs_attr_init(
> +			    &priv->core.sd_attrs[core_no][i].dev_attr.attr);
> +		priv->core.sd_attrs[core_no][i].dev_attr.attr.name =
> +					       priv->core.attr_name[core_no][i];
> +		priv->core.sd_attrs[core_no][i].dev_attr.attr.mode = 0444;
> +		priv->core.sd_attrs[core_no][i].dev_attr.show = core_show_fn[i];
> +		if (i == 0 || i == 1) /* label or temp */
> +			priv->core.sd_attrs[core_no][i].index = core_no;
> +		priv->core.attrs[core_no][i] =
> +				 &priv->core.sd_attrs[core_no][i].dev_attr.attr;
> +	}
> +
> +	priv->core.attr_group[core_no].attrs = priv->core.attrs[core_no];
> +
> +	return sysfs_create_group(&priv->hwmon_dev->kobj,
> +				  &priv->core.attr_group[core_no]);
> +}
> +
> +static ssize_t (*const dimm_show_fn[DIMM_TEMP_ATTRS]) (struct device *dev,
> +		struct device_attribute *devattr, char *buf) = {
> +	show_dimm_label,
> +	show_dimm_temp,
> +};
> +
> +static const char *const dimm_suffix[DIMM_TEMP_ATTRS] = {
> +	"label",
> +	"input",
> +};
> +
> +static int create_dimm_temp_group(struct peci_hwmon *priv, int dimm_no)
> +{
> +	int i;
> +
> +	for (i = 0; i < DIMM_TEMP_ATTRS; i++) {
> +		snprintf(priv->dimm.attr_name[dimm_no][i],
> +			 ATTR_NAME_LEN, "temp%d_%s",
> +			 DIMM_INDEX_OFFSET + dimm_no, dimm_suffix[i]);
> +		sysfs_attr_init(&priv->dimm.sd_attrs[dimm_no][i].dev_attr.attr);
> +		priv->dimm.sd_attrs[dimm_no][i].dev_attr.attr.name =
> +					       priv->dimm.attr_name[dimm_no][i];
> +		priv->dimm.sd_attrs[dimm_no][i].dev_attr.attr.mode = 0444;
> +		priv->dimm.sd_attrs[dimm_no][i].dev_attr.show = dimm_show_fn[i];
> +		priv->dimm.sd_attrs[dimm_no][i].index = dimm_no;
> +		priv->dimm.attrs[dimm_no][i] =
> +				 &priv->dimm.sd_attrs[dimm_no][i].dev_attr.attr;
> +	}
> +
> +	priv->dimm.attr_group[dimm_no].attrs = priv->dimm.attrs[dimm_no];
> +
> +	return sysfs_create_group(&priv->hwmon_dev->kobj,
> +				  &priv->dimm.attr_group[dimm_no]);
> +}
> +
> +static int peci_hwmon_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct peci_hwmon *priv;
> +	struct device *hwmon;
> +	int rc, i;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(dev, priv);
> +	priv->dev = dev;
> +
> +	rc = of_property_read_u32(np, "cpu-id", &priv->cpu_id);

What entity determines cpu-id ?

> +	if (rc || priv->cpu_id >= CPU_ID_MAX) {
> +		dev_err(dev, "Invalid cpu-id configuration\n");
> +		return rc;
> +	}
> +
> +	rc = of_property_read_u32(np, "dimm-nums", &priv->dimm_nums);

This is an odd devicetree attribute. Normally the number of DIMMs
is dynamic. Isn't there a means to get all that information dynamically
instead of having to set it through devicetree ? What if someone adds
or removes a DIMM ? Who updates the devicetree ?

> +	if (rc || priv->dimm_nums > DIMM_NUMS_MAX) {
> +		dev_warn(dev, "Invalid dimm-nums : %u. Use default : %u\n",
> +			 priv->dimm_nums, OF_DIMM_NUMS_DEFAULT);
> +		priv->dimm_nums = OF_DIMM_NUMS_DEFAULT;
> +	}
> +
> +	priv->show_core = of_property_read_bool(np, "show-core");

This does not look like an appropriate devicetree attribute.

> +
> +	priv->groups = peci_hwmon_attr_groups;
> +

This assignment (and the ->groups variable) is quite pointless.

> +	snprintf(priv->name, NAME_MAX, HWMON_NAME ".cpu%d", priv->cpu_id);
> +
> +	hwmon = devm_hwmon_device_register_with_groups(dev,
> +						       priv->name,
> +						       priv, priv->groups);

Please rewrite the driver to use devm_hwmon_device_register_with_info(),
and avoid dynamic attributes.

> +
> +	rc = PTR_ERR_OR_ZERO(hwmon);
> +	if (rc != 0) {
> +		dev_err(dev, "Failed to register peci hwmon\n");
> +		return rc;
> +	}
> +
> +	priv->hwmon_dev = hwmon;

Something is logically wrong if you need to store hwmon_dev in the
private data structure. Specifically, creating attributes dynamically
after hwmon registration is wrong.

> +
> +	for (i = 0; i < priv->dimm_nums; i++) {
> +		rc = create_dimm_temp_group(priv, i);

No. See earlier comments. All attribute groups must be created during
registration (or before, but I am not inclined to accept a new driver
doing that).

> +		if (rc != 0) {
> +			dev_err(dev, "Failed to create dimm temp group\n");
> +			for (--i; i >= 0; i--) {
> +				sysfs_remove_group(&priv->hwmon_dev->kobj,
> +						   &priv->dimm.attr_group[i]);
> +			}
> +			return rc;
> +		}
> +	}
> +
> +	/*
> +	 * Try to create core temp group now. It will be created if CPU is
> +	 * curretnly online or it will be created after the first reading of
> +	 * cpuinfo from the online CPU otherwise.

This is not how CPUs are supposed to be detected, and it does not handle CPUs
taken offline. If the driver is instantiated as a CPU comes online, or as it
goes offline, the driver should use the appropriate kernel interfaces to
trigger that instantiation or removal. However, if so, it may be inappropriate
to associate CPU temperatures with other system temperatures in the same
instance of the driver; after all, those are all independent of each other.

Overall, I suspect that there should be a callback or some other mechanism
in the peci core to trigger instantiation and removal of this driver, and
I am not sure if any of the devicetree properties makes sense at all.

For example, if an instance of this driver is associated with a PECI
agent (with assorted CPU/DIMM temperature reporting), the instantiation
could be triggered as soon as the PECI core detects that the agent is
available, and the PECI core could report what exactly that instance
supports.

> +	 */
> +	if (priv->show_core)
> +		(void) get_cpuinfo(priv);
> +
> +	dev_info(dev, "peci hwmon for CPU#%d registered\n", priv->cpu_id);

Is this logging noise necessary ? Besides, some of it is redundant.

> +
> +	return rc;
> +}
> +
> +static int peci_hwmon_remove(struct platform_device *pdev)
> +{
> +	struct peci_hwmon *priv = dev_get_drvdata(&pdev->dev);
> +	int i;
> +
> +	if (atomic_read(&priv->core_group_created))
> +		for (i = 0; i < priv->core_nums; i++) {
> +			sysfs_remove_group(&priv->hwmon_dev->kobj,
> +					   &priv->core.attr_group[i]);
> +		}
> +
> +	for (i = 0; i < priv->dimm_nums; i++) {
> +		sysfs_remove_group(&priv->hwmon_dev->kobj,
> +				   &priv->dimm.attr_group[i]);
> +	}

If you need to call sysfs_remove_group from here,
something is conceptually wrong in your driver.

> +
> +	return 0;
> +}
> +
> +static const struct of_device_id peci_of_table[] = {
> +	{ .compatible = "peci-hwmon", },

This does not look like a reference to some piece of hardware.

> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, peci_of_table);
> +
> +static struct platform_driver peci_hwmon_driver = {
> +	.probe = peci_hwmon_probe,
> +	.remove = peci_hwmon_remove,
> +	.driver = {
> +		.name           = DEVICE_NAME,
> +		.of_match_table = peci_of_table,
> +	},
> +};
> +
> +module_platform_driver(peci_hwmon_driver);
> +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>");
> +MODULE_DESCRIPTION("PECI hwmon driver");
> +MODULE_LICENSE("GPL v2");

^ permalink raw reply

* [PATCH 2/2] soc: imx: gpc: Do not pass static memory as platform data
From: Andrey Smirnov @ 2018-01-10 21:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1f914ea33fef8ede0c81085bedf46ed5@agner.ch>

On Wed, Jan 10, 2018 at 12:49 PM, Stefan Agner <stefan@agner.ch> wrote:
> On 2018-01-10 17:16, Andrey Smirnov wrote:
>> Platform device core assumes the ownership of dev.platform_data as
>> well as that it is dynamically allocated and it will try to kfree it
>> as a part of platform_device_release(). Change the code to pass
>> kzalloc'ed chunk of memory instead of a pointer to a static memory to
>> avoid causing a BUG() when calling platform_device_put().
>
> I tried to get around that by setting platform_data to null before
> unregistring the device, see:
> https://marc.info/?l=linux-arm-kernel&m=151553216030129&w=2
>

Sorry should've commented in that thread: I saw that in your code, but
it felt to me like playing with fire a bit. IMHO calling
platform_device_put() should just work and not depend on certain field
being set to NULL prior.

>
> This solutions still seems to miss unregistering the platform devices,
> which shows when binding the driver again:
>

Absolutely, this patch solves a problem, not the problem :-) I think
solving the problem is orthogonal to this and warrants a separate
patch.

> root at colibri-imx6:~# echo 20dc000.gpc >
> /sys/bus/platform/drivers/imx-gpc/unbind
> [   80.702627] imx-pgc-pd imx-pgc-power-domain.0: Dropping the link to
> 20dc000.gpc
> [   80.710808] genpd_remove: unable to remove PU
> [   80.716408] imx-pgc-pd imx-pgc-power-domain.1: Dropping the link to
> 20dc000.gpc
> root at colibri-imx6:~# find /sys -name *pgc-power*
> /sys/devices/soc0/soc/2000000.aips-bus/20dc000.gpc/imx-pgc-power-domain.0
> /sys/devices/soc0/soc/2000000.aips-bus/20dc000.gpc/imx-pgc-power-domain.1
> /sys/bus/platform/devices/imx-pgc-power-domain.0
> /sys/bus/platform/devices/imx-pgc-power-domain.1
> root at colibri-imx6:~# echo 20dc000.gpc >
> /sys/bus/platform/drivers/imx-gpc/bind
> [   89.002754] ------------[ cut here ]------------
> [   89.007411] WARNING: CPU: 0 PID: 516 at fs/sysfs/dir.c:31
> sysfs_warn_dup+0x64/0x74
> [   89.015057] sysfs: cannot create duplicate filename
> '/devices/soc0/soc/2000000.aips-bus/20dc000.gpc/imx-pgc-power-domain.0'
>
>
>>
>> The problem can be reproduced by artificially enabling the error path
>> of platform_device_add() call (around line 452).
>>
>> Cc: Shawn Guo <shawnguo@kernel.org>
>> Cc: Stefan Agner <stefan@agner.ch>
>> Cc: Lucas Stach <l.stach@pengutronix.de>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
>> ---
>>
>> This patch is a follow up to fix one of the bugs discussed in
>> lkml.kernel.org/r/3f836677c6e98aaf01bc1ac8c3410083 at agner.ch
>>
>>  drivers/soc/imx/gpc.c | 9 ++++++++-
>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
>> index 47e7aa963dbb..ec8b79abebac 100644
>> --- a/drivers/soc/imx/gpc.c
>> +++ b/drivers/soc/imx/gpc.c
>> @@ -18,6 +18,7 @@
>>  #include <linux/pm_domain.h>
>>  #include <linux/regmap.h>
>>  #include <linux/regulator/consumer.h>
>> +#include <linux/slab.h>
>>
>>  #define GPC_CNTR             0x000
>>
>> @@ -428,13 +429,19 @@ static int imx_gpc_probe(struct platform_device *pdev)
>>                       if (domain_index >= of_id_data->num_domains)
>>                               continue;
>>
>> -                     domain = &imx_gpc_domains[domain_index];
>> +                     domain = kzalloc(sizeof(*domain), GFP_KERNEL);
>
> I guess you could use just kalloc here since you memcpy below.
>

Good point. Will change in v2.

Thanks,
Andrey Smirnov

^ permalink raw reply

* [PATCH v2 1/6] arm: Add BTB invalidation on switch_mm for Cortex-A9, A12 and A17
From: Nishanth Menon @ 2018-01-10 21:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <6662dd72-121c-0cfb-ea31-aeecad4c7d03@arm.com>

On 01/10/2018 11:57 AM, Marc Zyngier wrote:
> On 10/01/18 17:53, Tony Lindgren wrote:
>> * Marc Zyngier <marc.zyngier@arm.com> [180108 19:00]:
>>> In order to avoid aliasing attacks against the branch predictor,
>>> some implementations require to invalidate the BTB when switching
>>> from one user context to another.
>>>
>>> For this, we reuse the existing implementation for Cortex-A8, and
>>> apply it to A9, A12 and A17.
>>
>> I suspect we now must also make sure Cortex-A8 has the IBE bit
>> set unconditionally for this to work. Currently the assumption is
>> that IBE bit needs to be set only on the earlier CPU revisions
>> that suffer from ARM_ERRATA_430973.
>>
>>> --- a/arch/arm/mm/proc-v7-2level.S
>>> +++ b/arch/arm/mm/proc-v7-2level.S
>>> @@ -41,7 +41,7 @@
>>>    *	even on Cortex-A8 revisions not affected by 430973.
>>>    *	If IBE is not set, the flush BTAC/BTB won't do anything.
>>>    */
>>> -ENTRY(cpu_ca8_switch_mm)
>>> +ENTRY(cpu_v7_btbinv_switch_mm)
>>>   #ifdef CONFIG_MMU
>>>   	mov	r2, #0
>>>   	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
>>
>> So without IBE set, as the comments above say, the flush won't
>> do anything.
> 
> Indeed. Firmware/bootloaders must be updated to set IBE, just like on
> Cortex-A15. I'll add a note to that effect.
OK. in u-boot, I had helped on the following:
http://git.denx.de/?p=u-boot.git;a=commitdiff;h=5902f4ce0f2bd1411e40dc0ece3598a0fc19b2ae

maybe be build off that?

-- 
Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH v3 7/7] EDAC: Add driver for the Marvell Armada XP SDRAM and L2 cache ECC
From: Chris Packham @ 2018-01-10 21:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171116193145.s2nja2kfevjxlnt5@pd.tnic>

Hi Borislav,

On 17/11/17 08:32, Borislav Petkov wrote:
> On Fri, Nov 10, 2017 at 10:03:08AM +0100, Jan Luebbe wrote:
>> Add support for the ECC functionality as found in the DDR RAM and L2
>> cache controllers on the MV78230/MV78x60 SoCs. This driver has been
>> tested on the MV78460 (on a custom board with a DDR3 ECC DIMM).
>>
>> Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
> 
> ...
> 
>> diff --git a/drivers/edac/armada_xp_edac.c b/drivers/edac/armada_xp_edac.c
>> new file mode 100644
>> index 000000000000..cb9173b30aa9
>> --- /dev/null
>> +++ b/drivers/edac/armada_xp_edac.c
>> @@ -0,0 +1,658 @@
>> +/*
>> + * Copyright (C) 2017 Pengutronix, Jan Luebbe <kernel@pengutronix.de>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * 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/kernel.h>
>> +#include <linux/edac.h>
>> +#include <linux/of_platform.h>
>> +
>> +#include <asm/hardware/cache-l2x0.h>
> 
> I get this when I cross-build it:
> 
> drivers/edac/armada_xp_edac.c:19:37: fatal error: asm/hardware/cache-l2x0.h: No such file or directory
>   #include <asm/hardware/cache-l2x0.h>
>                                       ^
> compilation terminated.
> make[2]: *** [drivers/edac/armada_xp_edac.o] Error 1
> make[1]: *** [drivers/edac] Error 2
> make[1]: *** Waiting for unfinished jobs....
> make: *** [drivers] Error 2
> 
> 
> and that driver depends on ARCH_MVEBU which is arm64, AFAICT.
> 
> That header is
> 
> arch/arm/include/asm/hardware/cache-l2x0.h
> 
> however and not in arch/arm64/.
> 
> I could very well be missing something though...
> 

As Andrew said ARCH_MVEBU includes both 32-bit and 64-bit processors.

In terms of fixing this issue there are a few options. My first blunt 
tool approach is

-       depends on ARCH_MVEBU
+       depends on ARCH_MVEBU && !ARM64

But that's not a particularly common pattern outside of arch/arm

Another option would be

-       depends on ARCH_MVEBU
+       depends on MACH_MVEBU_V7

There seems to be plenty of precedent for depending on a MACH family in 
other drivers.

We could even go as far as wrapping header include and L2 cache parts 
with #ifdef CONFIG_CACHE_L2X0.

Do you have any preference for which option to take? I'm leaning towards 
MACH_MVEBU_V7.

^ permalink raw reply

* [PATCH net-next 2/2 v10] net: ethernet: Add a driver for Gemini gigabit ethernet
From: Linus Walleij @ 2018-01-10 22:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180110.154322.2235369645563224203.davem@davemloft.net>

On Wed, Jan 10, 2018 at 9:43 PM, David Miller <davem@davemloft.net> wrote:

> Actually I had to revert these two patches, this stuff doesn't even
> build.

Sorry about that, I did build it before sending out but I guess not on enough
architectures :(

I will iterate with the help of the zeroday build servers, my own machines
just don't suffice.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v5 01/44] dt-bindings: clock: Add new bindings for TI Davinci PLL clocks
From: Adam Ford @ 2018-01-10 22:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5aacc350-6236-2e4f-35bb-a681fc9d47e7@ti.com>

On Wed, Jan 10, 2018 at 12:52 PM, Sekhar Nori <nsekhar@ti.com> wrote:
> On Wednesday 10 January 2018 08:31 AM, David Lechner wrote:
>> On 01/09/2018 06:35 AM, Sekhar Nori wrote:
>>> On Monday 08 January 2018 09:59 PM, David Lechner wrote:
>>>> On 01/08/2018 08:00 AM, Sekhar Nori wrote:
>>>>> On Monday 08 January 2018 07:47 AM, David Lechner wrote:
>
>>>>>> diff --git
>>>>>> a/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>>>>> b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>>>>> new file mode 100644
>>>>>> index 0000000..99bf5da
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/clock/ti/davinci/pll.txt
>>>>>> @@ -0,0 +1,47 @@
>>>>>> +Binding for TI DaVinci PLL Controllers
>>>>>> +
>>>>>> +The PLL provides clocks to most of the components on the SoC. In
>>>>>> addition
>>>>>> +to the PLL itself, this controller also contains bypasses, gates,
>>>>>> dividers,
>>>>>> +an multiplexers for various clock signals.
>>>>>> +
>>>>>> +Required properties:
>>>>>> +- compatible: shall be one of:
>>>>>> +    - "ti,da850-pll0" for PLL0 on DA850/OMAP-L138/AM18XX
>>>>>> +    - "ti,da850-pll1" for PLL1 on DA850/OMAP-L138/AM18XX
>>>>>
>>>>> These PLLs are same IP so they should use the same compatible. You can
>>>>> initialize both PLLs for DA850 based on the same compatible.
>>>>>
>>>>
>>>> But they are not exactly the same. For example, PLL0 has 7 PLLDIV clocks
>>>> while
>>>> PLL1 only has 3. PLL0 has PREDIV while PLL1 does not. PLL0 has certain
>>>> SYSCLKs
>>>> that are fixed-ratio but PLL1 does not have any of these. There are even
>>>> more
>>>> differences, but these are the ones we are actually using.
>>>
>>> We need each element of the PLLC to be modeled individually as a clock
>>> node.
>>
>> I gave this a good think while I have been working on this series
>> and I came to the conclusion that we really don't need to do this.
>> These components are all internal to the PLL IP block, so the
>> compatible string is enough to tell us what we have. They only
>> thing we need really in the device tree bindings are the connections
>> that are external to the IP block.
>>
>>
>>> That is, PLL should only model the multiplier, the dividers
>>> including post and prediv should be modeled as divider clocks (hopefully
>>> being able to use the clk-divider.c library). The sysclks can be
>>> fixed-factor-clock type clocks.
>>>
>>> Without this flexible mechanism, we cannot (at least later) model things
>>> like DIV4.5 clock which is the only clock which derives from the output
>>> of PLL multiplier before the post divider is applied.
>>>
>>> Since with DT there are are no retakes, we need to get this right the
>>> first time and modifying later will not be an option.
>>>
>>
>> So, the full device tree binding would look something like this:
>>
>> +
>> +    pll0: clock-controller at 11000 {
>> +        compatible = "ti,da850-pll0";
>> +        reg = <0x11000 0x1000>;
>> +        clocks = <&ref_clk>, <&pll1_sysclk 3>, <&pll1_obsclk>;
>> +        clock-names = "oscin", pll1_sysclk3", "pll1_osbclk";
>> +        oscin-square-wave;
>> +
>> +        pll0_sysclk: sysclk {
>> +            #clock-cells = <1>;
>> +        };
>> +
>> +        pll0_auxclk: auxclk {
>> +            #clock-cells = <0>;
>> +        };
>> +
>> +        pll0_div45: div4.5 {
>> +            #clock-cells = <0>;
>> +        };
>> +
>> +        pll0_obsclk: obsclk {
>> +            #clock-cells = <0>;
>> +            assigned-clocks = <&pll0_sysclk 1>;
>> +            assigned-clock-names = "ocsrc";
>> +        };
>> +    };
>
> Well, I guess this will work as well. And I am probably biased towards
> the style I mentioned because AM335x and other TI OMAP processors
> follow that.
>
> To make it easy to review that we have all bases covered, can you model
> the all PLLC0 and PLLC1 (input and output) clocks for the next version?
>
>>
>> There are three clocks coming into the IP block and there are 11 clocks
>> going out (sysclk is 7 clocks). And you can specify the board-specific
>> configuration, like having the "oscin-square-wave" flag when a square wave
>> is used instead of a crystal oscillator and you can assign the multiplexer
>
> Ideally the OSCIN vs CLKIN selection should be another clock mux whose
> output is one of the input clocks to PLL controller. But I can see the
> difficulty in handling that as the mux itself is controlled by the PLL
> controller.
>
>> input that will be used by obsclk. (And, this binding is totally compatible
>> with the binding I have already proposed - although, I see now it would
>> be better to go ahead and add the clocks-names property.)
>
> Also, please add the oscin-square-wave to the binding definition too.
>
> For the benefit of others reviewing and not familiar with the hardware,
> the users guide for DA850 is here:
> http://www.ti.com/lit/ug/spruh77c/spruh77c.pdf
>

I am available tomorrow to build and test patches against the
da850-evm.  I just need to know which version(s) to test.

adam

> and the PLL block diagram is on page 143 (Figure 8-1).
>
> Thanks,
> Sekhar

^ permalink raw reply

* [GIT PULL] Allwinner clock changes for 4.16, round 2
From: Stephen Boyd @ 2018-01-10 22:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180108034901.GA5577@wens.csie.org>

On 01/08, Chen-Yu Tsai wrote:
> Hi Mike, Stephen,
> 
> Here are a few more clock changes for 4.16. The DE2 clock changes have
> been around for awhile. The A83T clock fix was found by Jernej while
> working on HDMI output for the SoC. We'd like to get these in so patches
> don't pile up on the mailing lists.
> 
> ChenYu
> 
> The following changes since commit e952ca3c6b2ffdfbf9618e4bd3e9aad1ff3f5eb4:
> 
>   clk: sunxi-ng: sun8i: a83t: Use sigma-delta modulation for audio PLL (2017-12-08 10:08:32 +0100)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-clk-for-4.16-2
> 
> for you to fetch changes up to 7dbc7f5f4904cfddc199af171ea095490a434f15:
> 
>   clk: sunxi-ng: a83t: Add M divider to TCON1 clock (2018-01-03 13:45:04 +0800)
> 
> ----------------------------------------------------------------
> Allwinner clock changes for 4.16, part 2
> 
> The hardware description for the DE2 clocks on the A64 and H5 SoCs is
> fixed, and support for these clocks on the H3 is added. Also, the
> description for the TCON1 clock on the A83T is fixed. All these are
> non-critical, as they have no users.

Thanks. Pulled into clk-next.

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

^ permalink raw reply

* [PATCH v2 0/6] ARM branch predictor hardening
From: Nishanth Menon @ 2018-01-10 22:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180108185533.9698-1-marc.zyngier@arm.com>

On 01/08/2018 12:55 PM, Marc Zyngier wrote:
[...]
> These patches are closely modelled against what we do on arm64,
> although simpler as we can rely on an architected instruction to
> perform the invalidation. The notable exception is Cortex-A15, where
> BTB invalidation behaves like a NOP, and the only way to shoot the
> predictor down is to invalidate the icache *and* to have ACTLR[0] set
> to 1 (which is a secure-only operation).

On u-boot side, we'd probably have to work off ->
http://git.denx.de/?p=u-boot.git;a=commitdiff;h=a615d0be6a73fc48a22e5662608260fe9b9149ff


[...]

-- 
Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH v3 7/7] EDAC: Add driver for the Marvell Armada XP SDRAM and L2 cache ECC
From: Chris Packham @ 2018-01-10 23:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171116193145.s2nja2kfevjxlnt5@pd.tnic>

Hi Borislav,

On 17/11/17 08:32, Borislav Petkov wrote:
> That struct name is too long. So long that it makes you break parameter
> names below.
> 
> For example, you don't need that lenghty prefix "armada_xp_mc_edac"
> prepended to static symbols. Same for the function names below.

Would you suggest dropping "armada_xp" altogether or just shortening to 
"axp"? What about dropping "edac" as well?

^ permalink raw reply

* [PATCH linux dev-4.10 3/6] drivers/misc: Add driver for Aspeed PECI and generic PECI headers
From: Jae Hyun Yoo @ 2018-01-10 23:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a3MaSEYnwk2_OadBSyKnBiwXsHw_RocvPDqL6oea9MuJA@mail.gmail.com>

On 1/10/2018 3:55 AM, Arnd Bergmann wrote:
> On Tue, Jan 9, 2018 at 11:31 PM, Jae Hyun Yoo
> <jae.hyun.yoo@linux.intel.com> wrote:
>> This commit adds driver implementation for Aspeed PECI. Also adds
>> generic peci.h and peci_ioctl.h files to provide compatibility
>> to peci drivers that can be implemented later e.g. Nuvoton's BMC
>> SoC family.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
> 
>> +#include <linux/clk.h>
>> +#include <linux/crc8.h>
>> +#include <linux/delay.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/jiffies.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/miscdevice.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/peci_ioctl.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/semaphore.h>
>> +#include <linux/types.h>
>> +#include <linux/uaccess.h>
> 
> semaphore.h is not used here and can be dropped.
> 

You are right. Will drop it.

>> +static struct aspeed_peci *aspeed_peci_priv;
> 
> Try to avoid instance variables like this one. You should always be able to find
> that pointer from whatever structure you were called with.
> 
> 

Okay. I will use driver_data instead.

>> +       timeout = wait_for_completion_interruptible_timeout(
>> +                                       &priv->xfer_complete,
>> +                                       msecs_to_jiffies(priv->cmd_timeout_ms));
>> +
>> +       dev_dbg(priv->dev, "INT_STS : 0x%08x\n", priv->sts);
>> +       if (!regmap_read(priv->regmap, AST_PECI_CMD, &peci_state))
>> +               dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
>> +                       PECI_CMD_STS_GET(peci_state));
>> +       else
>> +               dev_dbg(priv->dev, "PECI_STATE : read error\n");
>> +
>> +       if (timeout <= 0 || !(priv->sts & PECI_INT_CMD_DONE)) {
>> +               if (timeout <= 0) {
>> +                       dev_dbg(priv->dev, "Timeout waiting for a response!\n");
>> +                       rc = -ETIME;
>> +               } else {
>> +                       dev_dbg(priv->dev, "No valid response!\n");
>> +                       rc = -EFAULT;
>> +               }
>> +               return rc;
>> +       }
> 
> You don't seem to handle -ERESTARTSYS correct here. Either do it
> right, or drop the _interruptible part above.
> 

Will add a handling logic for the -ERESTARTSYS.

>> +typedef int (*ioctl_fn)(struct aspeed_peci *, void *);
>> +
>> +static ioctl_fn peci_ioctl_fn[PECI_CMD_MAX] = {
>> +       ioctl_xfer_msg,
>> +       ioctl_ping,
>> +       ioctl_get_dib,
>> +       ioctl_get_temp,
>> +       ioctl_rd_pkg_cfg,
>> +       ioctl_wr_pkg_cfg,
>> +       ioctl_rd_ia_msr,
>> +       NULL, /* Reserved */
>> +       ioctl_rd_pci_cfg,
>> +       NULL, /* Reserved */
>> +       ioctl_rd_pci_cfg_local,
>> +       ioctl_wr_pci_cfg_local,
>> +};
>> +
>> +
>> +long peci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>> +{
>> +       struct aspeed_peci *priv;
>> +       long ret = 0;
>> +       void __user *argp = (void __user *)arg;
>> +       int timeout = PECI_IDLE_CHECK_TIMEOUT;
>> +       u8 msg[sizeof(struct peci_xfer_msg)];
>> +       unsigned int peci_cmd, msg_size;
>> +       u32 cmd_sts;
>> +
>> +       /*
>> +        * Treat it as an inter module call when filp is null but only in case
>> +        * the private data is initialized.
>> +        */
>> +       if (filp)
>> +               priv = container_of(filp->private_data,
>> +                                   struct aspeed_peci, miscdev);
>> +       else
>> +               priv = aspeed_peci_priv;
> 
> Drop this.
> 

peci_ioctl is being called from peci_hwmon as an inter-module call so it 
is needed, but as you suggested in the other patch, I'll consider 
redesign it with adding a peci device class.

>> +       if (!priv)
>> +               return -ENXIO;
>> +
>> +       switch (cmd) {
>> +       case PECI_IOC_XFER:
>> +       case PECI_IOC_PING:
>> +       case PECI_IOC_GET_DIB:
>> +       case PECI_IOC_GET_TEMP:
>> +       case PECI_IOC_RD_PKG_CFG:
>> +       case PECI_IOC_WR_PKG_CFG:
>> +       case PECI_IOC_RD_IA_MSR:
>> +       case PECI_IOC_RD_PCI_CFG:
>> +       case PECI_IOC_RD_PCI_CFG_LOCAL:
>> +       case PECI_IOC_WR_PCI_CFG_LOCAL:
>> +               peci_cmd = _IOC_TYPE(cmd) - PECI_IOC_BASE;
>> +               msg_size = _IOC_SIZE(cmd);
>> +               break;
> 
> Having to keep the switch() statement and the array above seems a
> little fragile. Can you just do one or the other?
> 
> Regarding the command set, you have both a low-level PECI_IOC_XFER
> interface and a high-level interface. Can you explain why? I'd think that
> generally speaking it's better to have only one of the two.
> 

I was intended to provide generic peci command set, also the low level 
PECI_IOC_XFER to provide flexibility for a case when compose a custom 
peci command which cannot be covered by the high-level command set. As 
you said, all other commands can be implemented in the upper layer but 
the benefit of when this driver has the implementation is, it's easy to 
manage retry logic since peci is retrial based protocol intends to do 
not disturb a CPU if the CPU is doing more important task.

However, your thought also makes sense. I'll check the spec again 
whether the high-level command set can cover all cases. If so, I'll 
remove the low-level command.

>> +       /* Check command sts and bus idle state */
>> +       while (!regmap_read(priv->regmap, AST_PECI_CMD, &cmd_sts)
>> +              && (cmd_sts & (PECI_CMD_STS_MASK | PECI_CMD_PIN_MON))) {
>> +               if (timeout-- < 0) {
>> +                       dev_dbg(priv->dev, "Timeout waiting for idle state!\n");
>> +                       ret = -ETIME;
>> +                       goto out;
>> +               }
>> +               usleep_range(10000, 11000);
>> +       };
> 
> To implement timeout, it's better to replace the counter with a
> jiffies/time_before or ktime_get()/ktime_before() check, since usleep_range()
> is might sleep considerably longer than expected.
> 

Thanks for the suggestion. Will rewrite it using ktime_get()/ktime_before().

>> +EXPORT_SYMBOL_GPL(peci_ioctl);
> 
> No user of this, so drop it.
> 

peci_hwmon is using it.

>> +static int aspeed_peci_open(struct inode *inode, struct file *filp)
>> +{
>> +       struct aspeed_peci *priv =
>> +               container_of(filp->private_data, struct aspeed_peci, miscdev);
>> +
>> +       atomic_inc(&priv->ref_count);
>> +
>> +       dev_dbg(priv->dev, "ref_count : %d\n", atomic_read(&priv->ref_count));
>> +
>> +       return 0;
>> +}
>> +
>> +static int aspeed_peci_release(struct inode *inode, struct file *filp)
>> +{
>> +       struct aspeed_peci *priv =
>> +               container_of(filp->private_data, struct aspeed_peci, miscdev);
>> +
>> +       atomic_dec(&priv->ref_count);
>> +
>> +       dev_dbg(priv->dev, "ref_count : %d\n", atomic_read(&priv->ref_count));
>> +
>> +       return 0;
>> +}
> 
> Nothing uses that reference count, drop it.
> 

You are right. Will drop it.

>> new file mode 100644
>> index 0000000..66322c6
>> --- /dev/null
>> +++ b/include/misc/peci.h
>> @@ -0,0 +1,11 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Intel Corporation
>> +
>> +#ifndef __PECI_H
>> +#define __PECI_H
>> +
>> +#include <linux/peci_ioctl.h>
>> +
>> +long peci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
>> +
>> +#endif /* __PECI_H */
> 
> Not used anywhere.
> 

peci_hwmon is using it.

>> diff --git a/include/uapi/linux/peci_ioctl.h b/include/uapi/linux/peci_ioctl.h
>> new file mode 100644
>> index 0000000..8386848
>> --- /dev/null
>> +++ b/include/uapi/linux/peci_ioctl.h
>> @@ -0,0 +1,270 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Intel Corporation
>> +
>> +#ifndef __PECI_IOCTL_H
>> +#define __PECI_IOCTL_H
>> +
>> +#include <linux/ioctl.h>
>> +
>> +/* Base Address of 48d */
>> +#define PECI_BASE_ADDR  0x30  /* The PECI client's default address of 0x30 */
>> +#define PECI_OFFSET_MAX 8     /* Max numver of CPU clients */
>> +
>> +/* PCI Access */
>> +#define MAX_PCI_READ_LEN 24  /* Number of bytes of the PCI Space read */
>> +
>> +#define PCI_BUS0_CPU0      0x00
>> +#define PCI_BUS0_CPU1      0x80
>> +#define PCI_CPUBUSNO_BUS   0x00
>> +#define PCI_CPUBUSNO_DEV   0x08
>> +#define PCI_CPUBUSNO_FUNC  0x02
>> +#define PCI_CPUBUSNO       0xcc
>> +#define PCI_CPUBUSNO_1     0xd0
>> +#define PCI_CPUBUSNO_VALID 0xd4
> 
> I can't tell for sure, but this file seems to be mixing the kernel API with
> hardware specific macros that are not needed in user space. Can you move
> some of this file into the driver itself?
> 
> This might go back to the previous question about the high-level and
> low-level interfaces: if you can drop the low-level ioctl interface, more
> of this header can become private to the driver.
> 

As I answered above, I'll check the spec again and remove the low-level 
command if the high-level command set covers all cases.

>> +/* Package Identifier Read Parameter Value */
>> +#define PKG_ID_CPU_ID               0x0000  /* 0 - CPUID Info */
>> +#define PKG_ID_PLATFORM_ID          0x0001  /* 1 - Platform ID */
>> +#define PKG_ID_UNCORE_ID            0x0002  /* 2 - Uncore Device ID */
>> +#define PKG_ID_MAX_THREAD_ID        0x0003  /* 3 - Max Thread ID */
>> +#define PKG_ID_MICROCODE_REV        0x0004  /* 4 - CPU Microcode Update Revision */
>> +#define PKG_ID_MACHINE_CHECK_STATUS 0x0005  /* 5 - Machine Check Status */
>> +
>> +/* RdPkgConfig Index */
>> +#define MBX_INDEX_CPU_ID            0   /* Package Identifier Read */
>> +#define MBX_INDEX_VR_DEBUG          1   /* VR Debug */
>> +#define MBX_INDEX_PKG_TEMP_READ     2   /* Package Temperature Read */
>> +#define MBX_INDEX_ENERGY_COUNTER    3   /* Energy counter */
>> +#define MBX_INDEX_ENERGY_STATUS     4   /* DDR Energy Status */
>> +#define MBX_INDEX_WAKE_MODE_BIT     5   /* "Wake on PECI" Mode bit */
>> +#define MBX_INDEX_EPI               6   /* Efficient Performance Indication */
> 
> Who defines these constants? Are they specific to the aspeed BMC, to the HECI
> protocol, or to a particular version of the remote endpoint?
> 

These are common peci definitions, not the aspeed BMC specific.

>> +#pragma pack(push, 1)
>> +struct peci_xfer_msg {
>> +       unsigned char client_addr;
>> +       unsigned char tx_len;
>> +       unsigned char rx_len;
>> +       unsigned char tx_buf[MAX_BUFFER_SIZE];
>> +       unsigned char rx_buf[MAX_BUFFER_SIZE];
>> +};
>> +#pragma pack(pop)
>> +
>> +struct peci_ping_msg {
>> +       unsigned char target;
>> +};
>> +
>> +struct peci_get_dib_msg {
>> +       unsigned char target;
>> +       unsigned int  dib;
>> +};
>> +
>> +struct peci_get_temp_msg {
>> +       unsigned char target;
>> +       signed short  temp_raw;
>> +};
> 
> Aside from what Greg already said about the types, please be careful to
> also avoid implicit padding in the API data structures, including the end of the
> structure.
> 

Okay, I'll expand the pack() scope for all these definition.

>> +#define PECI_IOC_RD_PCI_CFG \
>> +       _IOWR(PECI_IOC_BASE + PECI_CMD_RD_PCI_CFG, 0, \
>> +               struct peci_rd_pci_cfg_msg)
>> +
>> +#define PECI_IOC_RD_PCI_CFG_LOCAL \
>> +       _IOWR(PECI_IOC_BASE + PECI_CMD_RD_PCI_CFG_LOCAL, 0, \
>> +               struct peci_rd_pci_cfg_local_msg)
>> +
>> +#define PECI_IOC_WR_PCI_CFG_LOCAL \
>> +       _IOWR(PECI_IOC_BASE + PECI_CMD_WR_PCI_CFG_LOCAL, 0, \
>> +               struct peci_wr_pci_cfg_local_msg)
> 
> Can you give some background on what these do? In particular, who
> is configuring whose PCI devices?
> 
>          Arnd
> 

These are commands to read/write a client CPU's PCI configuration which 
could be an end-point of the physical PECI interface connection. BMC 
controller will be a host and a CPU will be a client.

Thanks,
Jae

^ permalink raw reply

* [PATCH V6 Resend 00/13] drivers: Boot Constraint core
From: Rob Herring @ 2018-01-10 23:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1515554879.git.viresh.kumar@linaro.org>

On Tue, Jan 9, 2018 at 9:47 PM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> Hi Greg,
>
> I am re-sending V6 as you suggested. There is no change from the patches
> sent on 14/15th of December, apart from rebasing on driver-core-next.
>
> I have tested the Hisilicon patches (again) on hikey 9660 board, IMX
> stuff was earlier tested by Sascha (Pengutronix) on i.MX6 and Qualcomm
> stuff was earlier tested by Rajendra (Qualcomm) on Dragonboard 410C
> (This required some more patches related to display driver which
> Rajendra should be sending separately later on).
>
>
> Problem statement:
>
> Some devices are powered ON by the bootloader before the bootloader
> handovers control to Linux. It maybe important for those devices to keep
> working until the time a Linux device driver probes the device and
> reconfigure its resources.

Some devices are powered on by a bootloader, but only a small few have
to be maintained thru booting. Most you can just re-initialized.

> A typical example of that can be the LCD controller, which is used by
> the bootloaders to show image(s) while the platform is booting into
> Linux.  The LCD controller can be using some resources, like clk,
> regulators, etc, that are shared between several devices. These shared
> resources should be configured to satisfy need of all the users.  If
> another device's (X) driver gets probed before the LCD controller driver
> in this case, then it may end up disabling or reconfiguring these
> resources to ranges satisfying the current users (only device X) and
> that can make the LCD screen unstable.

We already have simple fb and a binding for it. It only handles clocks
I think, but could be extended to other things. I rather not extend
it, but it is there already and we don't need different solutions for
this.

> Another case can be a debug serial port enabled from the bootloader.

I looked at your case with HiKey some. As far as the PL011
driver/console is concerned, it should work as the clock is never
enabled/disabled and then probe deferred (IMO, doing any h/w init
before all resources are acquired is a driver error). The problem is
the AMBA bus enabling apb_pclk (which has a dedicated clk gate) and
then disabling it on deferred probe. The AMBA bus is fairly odd in
this regard. We could solve this just with an initcall to find
stdout-path node and enable all the clocks in the node and then a late
initcall to disable those clocks. Kind of hacky, but so is this
series.

Really, I think the clock framework is broken in that we leave clocks
in a mismatched state (reset state or whatever the bootloader decided)
until the end of booting. Then we are left with dealing with these
various platform specific issues. We should either not actually
disable clocks until the end of boot (just defer until we turn off all
unused clocks) or start requiring the clock drivers to turn off all
the clocks except the ones needed to continue booting (or otherwise
known to be constraints). The former should be easy to implement
because the code to turn off clocks is already there. We just need a
boot done flag and check that flag in disable function.

Rob

^ permalink raw reply

* [nomadik:gemini-ethernet 18/18] include/linux/module.h:129:42: error: redefinition of '__inittest'
From: kbuild test robot @ 2018-01-10 23:18 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git gemini-ethernet
head:   de0cb586c9e534c926cd7c74c92dc3d4104ea569
commit: de0cb586c9e534c926cd7c74c92dc3d4104ea569 [18/18] net: ethernet: Add a driver for Gemini gigabit ethernet
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout de0cb586c9e534c926cd7c74c92dc3d4104ea569
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:329:0,
                    from include/linux/kernel.h:14,
                    from include/linux/list.h:9,
                    from include/linux/module.h:9,
                    from drivers/net//ethernet/cortina/gemini.c:16:
   drivers/net//ethernet/cortina/gemini.c: In function 'geth_freeq_alloc_map_page':
>> drivers/net//ethernet/cortina/gemini.c:821:21: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]
     dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n",
                        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
>> drivers/net//ethernet/cortina/gemini.c:821:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n",
     ^~~~~~~
   drivers/net//ethernet/cortina/gemini.c: In function 'gmac_rx':
   drivers/net//ethernet/cortina/gemini.c:1410:50: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]
       dev_err(geth->dev, "could not find mapping %08x (page = %08x, page off = %08x)\n",
                                                  ~~~^
                                                  %08llx
>> drivers/net//ethernet/cortina/gemini.c:1410:63: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'long long unsigned int' [-Wformat=]
       dev_err(geth->dev, "could not find mapping %08x (page = %08x, page off = %08x)\n",
                                                               ~~~^
                                                               %08llx
   drivers/net//ethernet/cortina/gemini.c: In function 'gemini_ethernet_port_probe':
>> drivers/net//ethernet/cortina/gemini.c:2456:28: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=]
           "irq %d, DMA @ 0x%08x, GMAC @ 0x%08x\n",
                            ~~~^
                            %08llx
           port->irq, dmares->start,
                      ~~~~~~~~~~~~~
   drivers/net//ethernet/cortina/gemini.c:2456:43: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=]
           "irq %d, DMA @ 0x%08x, GMAC @ 0x%08x\n",
                                           ~~~^
                                           %08llx
   drivers/net//ethernet/cortina/gemini.c:2458:8:
           gmacres->start);
           ~~~~~~~~~~~~~~                      
   In file included from drivers/net//ethernet/cortina/gemini.c:16:0:
   drivers/net//ethernet/cortina/gemini.c: At top level:
>> include/linux/module.h:129:42: error: redefinition of '__inittest'
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
>> drivers/net//ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:129:42: note: previous definition of '__inittest' was here
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net//ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:131:6: error: redefinition of 'init_module'
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
>> drivers/net//ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:131:6: note: previous definition of 'init_module' was here
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net//ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:135:42: error: redefinition of '__exittest'
     static inline exitcall_t __maybe_unused __exittest(void)  \
                                             ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
>> drivers/net//ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:135:42: note: previous definition of '__exittest' was here
     static inline exitcall_t __maybe_unused __exittest(void)  \
                                             ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net//ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:137:7: error: redefinition of 'cleanup_module'
     void cleanup_module(void) __attribute__((alias(#exitfn)));
          ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
>> drivers/net//ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:137:7: note: previous definition of 'cleanup_module' was here
     void cleanup_module(void) __attribute__((alias(#exitfn)));
          ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net//ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/printk.h:329:0,
                    from include/linux/kernel.h:14,
                    from include/linux/list.h:9,
                    from include/linux/module.h:9,
                    from drivers/net/ethernet/cortina/gemini.c:16:
   drivers/net/ethernet/cortina/gemini.c: In function 'geth_freeq_alloc_map_page':
   drivers/net/ethernet/cortina/gemini.c:821:21: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]
     dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n",
                        ^
   include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg'
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
                                          ^~~
   drivers/net/ethernet/cortina/gemini.c:821:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n",
     ^~~~~~~
   drivers/net/ethernet/cortina/gemini.c: In function 'gmac_rx':
   drivers/net/ethernet/cortina/gemini.c:1410:50: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'dma_addr_t {aka long long unsigned int}' [-Wformat=]
       dev_err(geth->dev, "could not find mapping %08x (page = %08x, page off = %08x)\n",
                                                  ~~~^
                                                  %08llx
   drivers/net/ethernet/cortina/gemini.c:1410:63: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'long long unsigned int' [-Wformat=]
       dev_err(geth->dev, "could not find mapping %08x (page = %08x, page off = %08x)\n",
                                                               ~~~^
                                                               %08llx
   drivers/net/ethernet/cortina/gemini.c: In function 'gemini_ethernet_port_probe':
   drivers/net/ethernet/cortina/gemini.c:2456:28: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=]
           "irq %d, DMA @ 0x%08x, GMAC @ 0x%08x\n",
                            ~~~^
                            %08llx
           port->irq, dmares->start,
                      ~~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2456:43: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'resource_size_t {aka long long unsigned int}' [-Wformat=]
           "irq %d, DMA @ 0x%08x, GMAC @ 0x%08x\n",
                                           ~~~^
                                           %08llx
   drivers/net/ethernet/cortina/gemini.c:2458:8:
           gmacres->start);
           ~~~~~~~~~~~~~~                      
   In file included from drivers/net/ethernet/cortina/gemini.c:16:0:
   drivers/net/ethernet/cortina/gemini.c: At top level:
>> include/linux/module.h:129:42: error: redefinition of '__inittest'
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:129:42: note: previous definition of '__inittest' was here
     static inline initcall_t __maybe_unused __inittest(void)  \
                                             ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:131:6: error: redefinition of 'init_module'
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:131:6: note: previous definition of 'init_module' was here
     int init_module(void) __attribute__((alias(#initfn)));
         ^
   include/linux/device.h:1513:1: note: in expansion of macro 'module_init'
    module_init(__driver##_init); \
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:135:42: error: redefinition of '__exittest'
     static inline exitcall_t __maybe_unused __exittest(void)  \
                                             ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:135:42: note: previous definition of '__exittest' was here
     static inline exitcall_t __maybe_unused __exittest(void)  \
                                             ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
>> include/linux/module.h:137:7: error: redefinition of 'cleanup_module'
     void cleanup_module(void) __attribute__((alias(#exitfn)));
          ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2567:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_driver);
    ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/module.h:137:7: note: previous definition of 'cleanup_module' was here
     void cleanup_module(void) __attribute__((alias(#exitfn)));
          ^
   include/linux/device.h:1518:1: note: in expansion of macro 'module_exit'
    module_exit(__driver##_exit);
    ^~~~~~~~~~~
>> include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
     module_driver(__platform_driver, platform_driver_register, \
     ^~~~~~~~~~~~~
   drivers/net/ethernet/cortina/gemini.c:2495:1: note: in expansion of macro 'module_platform_driver'
    module_platform_driver(gemini_ethernet_port_driver);
    ^~~~~~~~~~~~~~~~~~~~~~

vim +/__inittest +129 include/linux/module.h

0fd972a7 Paul Gortmaker 2015-05-01  126  
0fd972a7 Paul Gortmaker 2015-05-01  127  /* Each module must use one module_init(). */
0fd972a7 Paul Gortmaker 2015-05-01  128  #define module_init(initfn)					\
1f318a8b Arnd Bergmann  2017-02-01 @129  	static inline initcall_t __maybe_unused __inittest(void)		\
0fd972a7 Paul Gortmaker 2015-05-01  130  	{ return initfn; }					\
0fd972a7 Paul Gortmaker 2015-05-01 @131  	int init_module(void) __attribute__((alias(#initfn)));
0fd972a7 Paul Gortmaker 2015-05-01  132  
0fd972a7 Paul Gortmaker 2015-05-01  133  /* This is only required if you want to be unloadable. */
0fd972a7 Paul Gortmaker 2015-05-01  134  #define module_exit(exitfn)					\
1f318a8b Arnd Bergmann  2017-02-01 @135  	static inline exitcall_t __maybe_unused __exittest(void)		\
0fd972a7 Paul Gortmaker 2015-05-01  136  	{ return exitfn; }					\
0fd972a7 Paul Gortmaker 2015-05-01 @137  	void cleanup_module(void) __attribute__((alias(#exitfn)));
0fd972a7 Paul Gortmaker 2015-05-01  138  

:::::: The code at line 129 was first introduced by commit
:::::: 1f318a8bafcfba9f0d623f4870c4e890fd22e659 modules: mark __inittest/__exittest as __maybe_unused

:::::: TO: Arnd Bergmann <arnd@arndb.de>
:::::: CC: Jessica Yu <jeyu@redhat.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 49802 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180111/ec884718/attachment-0001.gz>

^ permalink raw reply

* [PATCH linux dev-4.10 4/6] Documentation: dt-bindings: Add a generic PECI hwmon
From: Jae Hyun Yoo @ 2018-01-10 23:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK8P3a1qiD1sWj0oQ=WbvpEDhtcYbzCxjg7t1iPs45WamfUVgw@mail.gmail.com>

On 1/10/2018 4:20 AM, Arnd Bergmann wrote:
> On Tue, Jan 9, 2018 at 11:31 PM, Jae Hyun Yoo
> <jae.hyun.yoo@linux.intel.com> wrote:
>> This commit add a dt-bindings document for a generic PECI hwmon
>> driver.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
>> ---
>>   .../devicetree/bindings/hwmon/peci-hwmon.txt       | 33 ++++++++++++++++++++++
>>   1 file changed, 33 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/hwmon/peci-hwmon.txt
>>
>> diff --git a/Documentation/devicetree/bindings/hwmon/peci-hwmon.txt b/Documentation/devicetree/bindings/hwmon/peci-hwmon.txt
>> new file mode 100644
>> index 0000000..20b86f5
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/hwmon/peci-hwmon.txt
>> @@ -0,0 +1,33 @@
>> +* Generic PECI (Platform Environment Control Interface) hwmon driver.
>> +
>> +Dependency:
>> +- This driver uses a PECI misc driver as a controller interface so one of PECI
>> +  misc drivers which provides compatible ioctls has to be enabled.
> 
> The binding should only explain how we describe the hardware in an
> operating-system
> independent way, but not talk about how an OS is supposed to implement those
> drivers.
> 
> Having multiple drivers each provide an exported function is not possible
> in Linux: it immediately breaks building an 'allyesconfig' kernel, and prevents
> you from running the same kernel across multiple implementations, so that
> has to be redesigned anyway.
> 

Agreed, I'll consider redesigning of it.

>> +Required properties:
>> +- compatible: "peci-hwmon"
>> +- cpu-id: Should contain CPU socket ID
>> +       - 0 ~ 7
>> +
>> +Optional properties:
>> +- show-core: If this protperty is defined, core tmeperature attrubites will be
> 
> s/protperty/property/
> s/tmeperature/temperature/
> s/attrubites/attributes/
> 

Oops! I made this many typos in this single line. Thanks for your 
pointing it out. Will fix these.

>> +            enumerated.
>> +- dimm-nums: Should contain the number of DIMM slots that attached to each CPU
>> +            which is indicated by cpu-id.
>> +       0 ~ 16 (default: 16)
>> +            In case of 0, DIMM temperature attrubites will not be enumerated.
> 
> Is this only an initial list that you expect to be extended in the
> future, or is this
> a complete list of sensors that can ever be connected to PECI?
> 
> Should this be PECI version specific?
> 
>        Arnd
> 

The maximum supportable number of dimm slots is not PECI version 
specific but depends on CPU architecture. Currently IA supports up to 16 
slot as the maximum but it could vary in the future architecture.

Thanks,
Jae

^ permalink raw reply


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