Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv5 0/2] Variscite DART-6UL SoM support
From: Oliver Graute @ 2019-08-28 16:19 UTC (permalink / raw)
  To: shawnguo
  Cc: Mark Rutland, devicetree, narmstrong, Sascha Hauer, linux-kernel,
	oliver.graute, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel

Need feedback to the following patches which adds support for a DART-6UL Board

Need feedback howto document propertys and compatible the right way

Need feedback why ethernet RX is deaf

Product Page: https://www.variscite.com/product/evaluation-kits/dart-6ul-kits

Oliver Graute (2):
  ARM: dts: imx6ul: Add Variscite DART-6UL SoM support
  ARM: dts: Add support for i.MX6 UltraLite DART Variscite Customboard

 arch/arm/boot/dts/Makefile                         |   1 +
 .../boot/dts/imx6ul-imx6ull-var-dart-common.dtsi   | 445 +++++++++++++++++++++
 arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts    | 196 +++++++++
 3 files changed, 642 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6ul-imx6ull-var-dart-common.dtsi
 create mode 100644 arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts

-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCHv5 1/2] ARM: dts: imx6ul: Add Variscite DART-6UL SoM support
From: Oliver Graute @ 2019-08-28 16:19 UTC (permalink / raw)
  To: shawnguo
  Cc: Mark Rutland, devicetree, narmstrong, Sascha Hauer, linux-kernel,
	oliver.graute, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
In-Reply-To: <1567009160-21965-1-git-send-email-oliver.graute@gmail.com>

This patch adds support for the i.MX6UL variant of the Variscite DART-6UL
SoM Carrier-Board

Signed-off-by: Oliver Graute <oliver.graute@gmail.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Neil Armstrong <narmstrong@baylibre.com>
---
 .../boot/dts/imx6ul-imx6ull-var-dart-common.dtsi   | 445 +++++++++++++++++++++
 1 file changed, 445 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6ul-imx6ull-var-dart-common.dtsi

diff --git a/arch/arm/boot/dts/imx6ul-imx6ull-var-dart-common.dtsi b/arch/arm/boot/dts/imx6ul-imx6ull-var-dart-common.dtsi
new file mode 100644
index 00000000..f345d69
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-imx6ull-var-dart-common.dtsi
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/dts-v1/;
+
+#include "imx6ul.dtsi"
+/ {
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	touch_3v3_regulator: regulator-touch-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "touch_3v3_supply";
+		regulator-always-on;
+	};
+
+	reg_sd1_vmmc: regulator-sd1-vmmc {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_gpio_dvfs: regulator-gpio {
+		compatible = "regulator-gpio";
+		regulator-min-microvolt = <1300000>;
+		regulator-max-microvolt = <1400000>;
+		regulator-name = "gpio_dvfs";
+		regulator-type = "voltage";
+		gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		states = <1300000 0x1 1400000 0x0>;
+	};
+
+	rmii_ref_clk: clock-rmii-ref {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+		clock-output-names = "rmii-ref";
+	};
+
+};
+
+&adc1 {
+	vref-supply = <&touch_3v3_regulator>;
+	status = "okay";
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan1>;
+	status = "disabled";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan2>;
+	status = "disabled";
+};
+
+&cpu0 {
+	arm-supply = <&reg_arm>;
+	soc-supply = <&reg_soc>;
+};
+
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet1>;
+	phy-mode = "rmii";
+	status = "disabled";
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rmii";
+	status = "disabled";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy@1 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			micrel,rmii-reference-clock-select-25-mhz;
+			clocks = <&rmii_ref_clk>;
+			clock-names = "rmii-ref";
+			reg = <1>;
+		};
+
+		ethphy1: ethernet-phy@3 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			micrel,rmii-reference-clock-select-25-mhz;
+			clocks = <&rmii_ref_clk>;
+			clock-names = "rmii-ref";
+			reg = <3>;
+		};
+	};
+};
+
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	status = "okay";
+
+	partition@0 {
+		label = "spl";
+		reg = <0x00000000 0x00200000>;
+	};
+
+	partition@200000 {
+		label = "uboot";
+		reg = <0x00200000 0x00200000>;
+	};
+
+	partition@400000 {
+		label = "uboot-env";
+		reg = <0x00400000 0x00200000>;
+	};
+
+	partition@600000 {
+		label = "kernel";
+		reg = <0x00600000 0x00800000>;
+	};
+
+	partition@e00000 {
+		label = "rootfs";
+		reg = <0x00e00000 0x3f200000>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "disabled";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "disabled";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "disabled";
+};
+
+&sai2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+	assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+			  <&clks IMX6UL_CLK_SAI2>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+	assigned-clock-rates = <0>, <12288000>;
+	fsl,sai-mclk-direction-output;
+	status = "okay";
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&snvs_rtc {
+	status = "disabled";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	status = "disabled";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
+&usbotg1 {
+	disable-over-current;
+	status = "disabled";
+};
+
+&usbotg2 {
+	disable-over-current;
+	status = "disabled";
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	no-1-8-v;
+	keep-power-in-suspend;
+	vmmc-supply = <&reg_sd1_vmmc>;
+	non-removable;
+	status = "okay";
+};
+
+&usdhc2 {
+	status = "disabled";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	pinctrl_enet1: enet1grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN	0x1b0b0
+			MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00	0x1b0b0
+			MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01	0x1b0b0
+			MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1	0x4001b031
+		>;
+	};
+
+	pinctrl_enet2: enet2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b031
+			MX6UL_PAD_GPIO1_IO07__ENET2_MDC		0x1b0b0
+			MX6UL_PAD_GPIO1_IO06__ENET2_MDIO	0x1b0b0
+			MX6UL_PAD_JTAG_MOD__GPIO1_IO10		0x1b0b0
+		>;
+	};
+
+	pinctrl_flexcan1: flexcan1grp{
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX	0x1b020
+			MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX	0x1b020
+		>;
+	};
+
+	pinctrl_flexcan2: flexcan2grp{
+		fsl,pins = <
+			MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX	0x1b020
+			MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX	0x1b020
+		>;
+	};
+
+	pinctrl_gpio_leds: gpioledsgrp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_HSYNC__GPIO4_IO20		0x1b0b0
+			MX6UL_PAD_GPIO1_IO00__GPIO1_IO00	0x17059
+		>;
+	};
+
+	pinctrl_gpmi_nand: gpminandgrp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_CLE__RAWNAND_CLE		0xb0b1
+			MX6UL_PAD_NAND_ALE__RAWNAND_ALE		0xb0b1
+			MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B	0xb0b1
+			MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B	0xb000
+			MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B	0xb0b1
+			MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B	0xb0b1
+			MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B	0xb0b1
+			MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B	0xb0b1
+			MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00	0xb0b1
+			MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01	0xb0b1
+			MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02	0xb0b1
+			MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03	0xb0b1
+			MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04	0xb0b1
+			MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05	0xb0b1
+			MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06	0xb0b1
+			MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07	0xb0b1
+		>;
+	};
+
+	pinctrl_hog: hoggrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT    0x03029
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL	0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA	0x4001b8b0
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL	0x4001b8b0
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA	0x4001b8b0
+		>;
+	};
+
+	pinctrl_lcdif: lcdif {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02	0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03	0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04	0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05	0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06	0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07	0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10	0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11	0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12	0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13	0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14	0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15	0x79
+			MX6UL_PAD_LCD_DATA18__LCDIF_DATA18	0x79
+			MX6UL_PAD_LCD_DATA19__LCDIF_DATA19	0x79
+			MX6UL_PAD_LCD_DATA20__LCDIF_DATA20	0x79
+			MX6UL_PAD_LCD_DATA21__LCDIF_DATA21	0x79
+			MX6UL_PAD_LCD_DATA22__LCDIF_DATA22	0x79
+			MX6UL_PAD_LCD_DATA23__LCDIF_DATA23	0x79
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK		0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE	0x79
+		>;
+	};
+
+	pinctrl_pwm1: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__PWM1_OUT		0x110b0
+		>;
+	};
+
+	pinctrl_sai1: sai1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK	0x11088
+			MX6UL_PAD_CSI_DATA04__SAI1_TX_SYNC	0x17088
+			MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA	0x11088
+			MX6UL_PAD_CSI_DATA07__SAI1_TX_DATA	0x11088
+		>;
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK	0x17088
+			MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC	0x17088
+			MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA	0x11088
+			MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA	0x11088
+			MX6UL_PAD_JTAG_TMS__SAI2_MCLK		0x17088
+		>;
+	};
+
+	pinctrl_tsc: tscgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01	0xb0
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02	0xb0
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03	0xb0
+			MX6UL_PAD_GPIO1_IO04__GPIO1_IO04	0xb0
+		>;
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX	0x1b0b1
+			MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS	0x1b0b1
+			MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX	0x1b0b1
+			MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS	0x1b0b1
+			MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS	0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x17059
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x17059
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x17059
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x17059
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x17059
+			MX6UL_PAD_CSI_VSYNC__GPIO4_IO19		0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x100b9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170b9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170b9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170b9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170b9
+			MX6UL_PAD_CSI_VSYNC__GPIO4_IO19		0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x100f9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170f9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170f9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170f9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170f9
+			MX6UL_PAD_CSI_VSYNC__GPIO4_IO19		0x1b0b1
+		>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__WDOG1_WDOG_B	0x78b0
+		>;
+	};
+};
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCHv5 2/2] ARM: dts: Add support for i.MX6 UltraLite DART Variscite Customboard
From: Oliver Graute @ 2019-08-28 16:19 UTC (permalink / raw)
  To: shawnguo
  Cc: Mark Rutland, devicetree, narmstrong, Sascha Hauer, linux-kernel,
	oliver.graute, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
In-Reply-To: <1567009160-21965-1-git-send-email-oliver.graute@gmail.com>

This patch adds DeviceTree Source for the i.MX6 UltraLite DART NAND/WIFI

Signed-off-by: Oliver Graute <oliver.graute@gmail.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Neil Armstrong <narmstrong@baylibre.com>
---
 arch/arm/boot/dts/Makefile                      |   1 +
 arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts | 196 ++++++++++++++++++++++++
 2 files changed, 197 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index a24a6a1..a2a69e4 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -579,6 +579,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ul-tx6ul-0010.dtb \
 	imx6ul-tx6ul-0011.dtb \
 	imx6ul-tx6ul-mainboard.dtb \
+	imx6ul-var-6ulcustomboard.dtb \
 	imx6ull-14x14-evk.dtb \
 	imx6ull-colibri-eval-v3.dtb \
 	imx6ull-colibri-wifi-eval-v3.dtb \
diff --git a/arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts b/arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts
new file mode 100644
index 00000000..1861b34
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-var-6ulcustomboard.dts
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * Support for Variscite DART-6UL Module
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright (C) 2015-2016 Variscite Ltd. - http://www.variscite.com
+ * Copyright (C) 2018-2019 Oliver Graute <oliver.graute@gmail.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "imx6ul-imx6ull-var-dart-common.dtsi"
+
+/ {
+	model = "Variscite i.MX6 UltraLite Carrier-board";
+	compatible = "variscite,6ulcustomboard", "fsl,imx6ul";
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 20000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		status = "okay";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		user {
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_BACK>;
+			gpio-key,wakeup;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		d16-led {
+			gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "wm8731audio";
+		simple-audio-card,widgets =
+			"Headphone", "Headphone Jack",
+			"Line", "Line Jack",
+			"Microphone", "Mic Jack";
+		simple-audio-card,routing =
+			"Headphone Jack", "RHPOUT",
+			"Headphone Jack", "LHPOUT",
+			"LLINEIN", "Line Jack",
+			"RLINEIN", "Line Jack",
+			"MICIN", "Mic Bias",
+			"Mic Bias", "Mic Jack";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&sound_master>;
+		simple-audio-card,frame-master = <&sound_master>;
+
+		sound_master: simple-audio-card,cpu {
+				sound-dai = <&sai2>;
+		};
+	};
+};
+
+&can1 {
+	status = "okay";
+};
+
+&can2 {
+	status = "okay";
+};
+
+&fec1 {
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+	phy-handle = <&ethphy0>;
+	status = "okay";
+};
+
+&fec2 {
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+	phy-handle = <&ethphy1>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c2 {
+	clock_frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	wm8731: audio-codec@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8731";
+		reg = <0x1a>;
+		clocks = <&clks IMX6UL_CLK_SAI2>;
+		clock-names = "mclk";
+	};
+
+	touchscreen@38 {
+		compatible = "edt,edt-ft5x06";
+		reg = <0x38>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <4 0>;
+		touchscreen-size-x = <800>;
+		touchscreen-size-y = <480>;
+		touchscreen-inverted-x;
+		touchscreen-inverted-y;
+		wakeup-source;
+	};
+
+	rtc@68 {
+		compatible = "dallas,ds1337";
+		reg = <0x68>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rtc>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&lcdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcdif>;
+	display = <&display0>;
+	status = "okay";
+
+	display0: display0 {
+		bits-per-pixel = <16>;
+		bus-width = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: timing0 {
+				clock-frequency =<35000000>;
+				hactive = <800>;
+				vactive = <480>;
+				hfront-porch = <40>;
+				hback-porch = <40>;
+				hsync-len = <48>;
+				vback-porch = <29>;
+				vfront-porch = <13>;
+				vsync-len = <3>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usbotg1 {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbotg2 {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07	0x1b0b0
+		>;
+	};
+};
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v3 2/5] arm64: Use correct ll/sc atomic constraints
From: Mark Rutland @ 2019-08-28 16:24 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Peter Zijlstra, Catalin Marinas, Boqun Feng, Will Deacon,
	Ard.Biesheuvel, linux-arm-kernel
In-Reply-To: <20190828154422.GA14582@e119886-lin.cambridge.arm.com>

On Wed, Aug 28, 2019 at 04:44:22PM +0100, Andrew Murray wrote:
> On Wed, Aug 28, 2019 at 04:25:40PM +0100, Mark Rutland wrote:
> > On Wed, Aug 28, 2019 at 02:01:19PM +0100, Andrew Murray wrote:
> > > On Thu, Aug 22, 2019 at 04:32:23PM +0100, Mark Rutland wrote:
> > > > On Mon, Aug 12, 2019 at 03:36:22PM +0100, Andrew Murray wrote:
> > > > [...]
> > > > 
> > > > > -ATOMIC64_OPS(and, and)
> > > > > -ATOMIC64_OPS(andnot, bic)
> > > > > -ATOMIC64_OPS(or, orr)
> > > > > -ATOMIC64_OPS(xor, eor)
> > > > > +ATOMIC64_OPS(and, and, K)
> > > > > +ATOMIC64_OPS(andnot, bic, )
> > > > > +ATOMIC64_OPS(or, orr, K)
> > > > > +ATOMIC64_OPS(xor, eor, K)
> > > > 
> > > > Shouldn't these be 'L'?
> > > > 
> > > > IIUC K is a subset of L, so if that's deliberate we should call that out
> > > > explicitly...
> > > 
> > > Oooh yes that's wrong. I guess the atomic64_[and,or,xor] are rarely called
> > > in the kernel which perhaps is why the compiler hasn't shouted at me.
> > > 
> > > Do you agree that the and, orr and eor should all be 'L' instead of 'K'?
> > 
> > Yes, I think all the 64-bit logical ops should all use 'L'.
> 
> With the exception of bic? I don't think there is an appropriate constraint
> for this (it requires an 8 bit immediate).

The ARM ARM doesn't mention BIC (Immediate), and AFAICT that's an
(undocumented?) alias for AND (Immediate) with a negated immediate.

Where did you find a description with an 8-bit immediate?

Regardless, yes, drop the 'L' there -- I can't find any suitable
constraint either.

Thanks,
Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH V2 4/6] PCI: tegra: Add support to enable slot regulators
From: Thierry Reding @ 2019-08-28 16:24 UTC (permalink / raw)
  To: Vidya Sagar
  Cc: devicetree, lorenzo.pieralisi, mperttunen, mmaddireddy, kthota,
	gustavo.pimentel, linux-kernel, kishon, linux-tegra, robh+dt,
	linux-pci, bhelgaas, andrew.murray, digetx, jonathanh,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828131505.28475-5-vidyas@nvidia.com>


[-- Attachment #1.1: Type: text/plain, Size: 4988 bytes --]

On Wed, Aug 28, 2019 at 06:45:03PM +0530, Vidya Sagar wrote:
> Add support to get regulator information of 3.3V and 12V supplies of a PCIe
> slot from the respective controller's device-tree node and enable those
> supplies. This is required in platforms like p2972-0000 where the supplies
> to x16 slot owned by C5 controller need to be enabled before attempting to
> enumerate the devices.
> 
> Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
> ---
> V2:
> * Addressed review comments from Thierry Reding and Andrew Murray
> * Handled failure case of devm_regulator_get_optional() for -ENODEV cleanly
> 
>  drivers/pci/controller/dwc/pcie-tegra194.c | 80 ++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 057ba4f9fbcd..6a66101ec83d 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -278,6 +278,8 @@ struct tegra_pcie_dw {
>  	u32 aspm_l0s_enter_lat;
>  
>  	struct regulator *pex_ctl_supply;
> +	struct regulator *slot_ctl_3v3;
> +	struct regulator *slot_ctl_12v;
>  
>  	unsigned int phy_count;
>  	struct phy **phys;
> @@ -1047,6 +1049,72 @@ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
>  	}
>  }
>  
> +static int tegra_pcie_get_slot_regulators(struct tegra_pcie_dw *pcie)
> +{
> +	pcie->slot_ctl_3v3 = devm_regulator_get_optional(pcie->dev, "vpcie3v3");
> +	if (IS_ERR(pcie->slot_ctl_3v3)) {
> +		if (PTR_ERR(pcie->slot_ctl_3v3) != -ENODEV)
> +			return PTR_ERR(pcie->slot_ctl_3v3);
> +
> +		pcie->slot_ctl_3v3 = NULL;
> +	}
> +
> +	pcie->slot_ctl_12v = devm_regulator_get_optional(pcie->dev, "vpcie12v");
> +	if (IS_ERR(pcie->slot_ctl_12v)) {
> +		if (PTR_ERR(pcie->slot_ctl_12v) != -ENODEV)
> +			return PTR_ERR(pcie->slot_ctl_12v);
> +
> +		pcie->slot_ctl_12v = NULL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int tegra_pcie_enable_slot_regulators(struct tegra_pcie_dw *pcie)
> +{
> +	int ret;
> +
> +	if (pcie->slot_ctl_3v3) {
> +		ret = regulator_enable(pcie->slot_ctl_3v3);
> +		if (ret < 0) {
> +			dev_err(pcie->dev,
> +				"Failed to enable 3V3 slot supply: %d\n", ret);

Nit: perhaps make this error message "Failed to enable 3.3V slot
supply"? Seems somewhat more user-friendly than 3V3.


> +			return ret;
> +		}
> +	}
> +
> +	if (pcie->slot_ctl_12v) {
> +		ret = regulator_enable(pcie->slot_ctl_12v);
> +		if (ret < 0) {
> +			dev_err(pcie->dev,
> +				"Failed to enable 12V slot supply: %d\n", ret);
> +			goto fail_12v_enable;
> +		}
> +	}
> +
> +	/*
> +	 * According to PCI Express Card Electromechanical Specification
> +	 * Revision 1.1, Table-2.4, T_PVPERL (Power stable to PERST# inactive)
> +	 * should be a minimum of 100ms.
> +	 */
> +	msleep(100);

Do you perhaps want to guard this with something like:

	if (pcie->slot_ctl_3v3 || pcie->slot_ctl_12v)

? Doesn't seem useful to me to sleep 100 ms here if there are no
regulators being enabled to begin with.

Thierry

> +
> +	return 0;
> +
> +fail_12v_enable:
> +	if (pcie->slot_ctl_3v3)
> +		regulator_disable(pcie->slot_ctl_3v3);
> +	return ret;
> +}
> +
> +static void tegra_pcie_disable_slot_regulators(struct tegra_pcie_dw *pcie)
> +{
> +	if (pcie->slot_ctl_12v)
> +		regulator_disable(pcie->slot_ctl_12v);
> +	if (pcie->slot_ctl_3v3)
> +		regulator_disable(pcie->slot_ctl_3v3);
> +}
> +
>  static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
>  					bool en_hw_hot_rst)
>  {
> @@ -1060,6 +1128,10 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
>  		return ret;
>  	}
>  
> +	ret = tegra_pcie_enable_slot_regulators(pcie);
> +	if (ret < 0)
> +		goto fail_slot_reg_en;
> +
>  	ret = regulator_enable(pcie->pex_ctl_supply);
>  	if (ret < 0) {
>  		dev_err(pcie->dev, "Failed to enable regulator: %d\n", ret);
> @@ -1142,6 +1214,8 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
>  fail_core_clk:
>  	regulator_disable(pcie->pex_ctl_supply);
>  fail_reg_en:
> +	tegra_pcie_disable_slot_regulators(pcie);
> +fail_slot_reg_en:
>  	tegra_pcie_bpmp_set_ctrl_state(pcie, false);
>  
>  	return ret;
> @@ -1174,6 +1248,8 @@ static int __deinit_controller(struct tegra_pcie_dw *pcie)
>  		return ret;
>  	}
>  
> +	tegra_pcie_disable_slot_regulators(pcie);
> +
>  	ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false);
>  	if (ret) {
>  		dev_err(pcie->dev, "Failed to disable controller %d: %d\n",
> @@ -1373,6 +1449,10 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	ret = tegra_pcie_get_slot_regulators(pcie);
> +	if (ret < 0)
> +		return ret;
> +
>  	pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");
>  	if (IS_ERR(pcie->pex_ctl_supply)) {
>  		dev_err(dev, "Failed to get regulator: %ld\n",
> -- 
> 2.17.1
> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 8/8] coresight: etm4x: docs: Additional documentation for ETM4x.
From: Mathieu Poirier @ 2019-08-28 16:36 UTC (permalink / raw)
  To: Mike Leach; +Cc: Coresight ML, linux-arm-kernel, Suzuki K. Poulose
In-Reply-To: <CAJ9a7VhU8P8BrT_UNbm=2W9CVjPpmqtkZ76TYw8Z8zzHQFraFw@mail.gmail.com>

On Wed, 28 Aug 2019 at 08:20, Mike Leach <mike.leach@linaro.org> wrote:
>
> Hi Mathieu,
>
> I assume you want the split to be ? :-
> 1. the update in Documentation/ARM/testing/sysfs-bus-coresight-devices-etm4x
> 2. the moving of coresight docs to their new common directory.
> 3. the addition of the new etm4x doc

Yes, that would be great.

>
> On Tue, 27 Aug 2019 at 23:34, Mathieu Poirier
> <mathieu.poirier@linaro.org> wrote:
> >
> > On Mon, Aug 19, 2019 at 09:57:20PM +0100, Mike Leach wrote:
> > > Update existing docs for new sysfs API features.
> > > Add new ETMv4 reference document for sysfs programming.
> > > Move coresight documentation to common directory.
> > >
> >
> > I also get the following warnings when adding the patch:
> >
> > $ git am 0008-coresight-etm4x-docs-Additional-documentation-for-ET.patch
> > Applying: coresight: etm4x: docs: Additional documentation for ETM4x.
> > .git/rebase-apply/patch:620: space before tab in indent.
> >                 bitfield up to 32 bits setting trace features.
> > .git/rebase-apply/patch:950: space before tab in indent.
> >                                     ; range comparator
> > .git/rebase-apply/patch:954: space before tab in indent.
> >                                     ; address comparator
> > .git/rebase-apply/patch:1057: new blank line at EOF.
> > +
> > warning: 4 lines add whitespace errors.
> >
>
> OK - I'll re-look at this, but don't recall seeing any errors myself
> & al cleared by checkpatch.

I didn't get any errors from checkpatch either.  I got these while
applying the patch.

>
> Regards
>
> Mike
>
>
> > > Signed-off-by: Mike Leach <mike.leach@linaro.org>
> > > ---
> > >  .../testing/sysfs-bus-coresight-devices-etm4x | 183 ++++---
> > >  .../{ => coresight}/coresight-cpu-debug.txt   |   0
> > >  .../coresight/coresight-etm4x-reference.txt   | 459 ++++++++++++++++++
> > >  .../trace/{ => coresight}/coresight.txt       |   0
> > >  MAINTAINERS                                   |   3 +-
> > >  5 files changed, 575 insertions(+), 70 deletions(-)
> > >  rename Documentation/trace/{ => coresight}/coresight-cpu-debug.txt (100%)
> > >  create mode 100644 Documentation/trace/coresight/coresight-etm4x-reference.txt
> > >  rename Documentation/trace/{ => coresight}/coresight.txt (100%)
> > >
> > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > index 36258bc1b473..112c50ae9986 100644
> > > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > @@ -1,4 +1,4 @@
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/enable_source
> > > +What:                /sys/bus/coresight/devices/etm<N>/enable_source
> > >  Date:                April 2015
> > >  KernelVersion:  4.01
> > >  Contact:        Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -8,82 +8,82 @@ Description:        (RW) Enable/disable tracing on this specific trace entiry.
> > >               of coresight components linking the source to the sink is
> > >               configured and managed automatically by the coresight framework.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cpu
> > > +What:                /sys/bus/coresight/devices/etm<N>/cpu
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) The CPU this tracing entity is associated with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_pe_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_pe_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of PE comparator inputs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_addr_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_addr_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of address comparator pairs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_cntr
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_cntr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of counters that are available for
> > >               tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_ext_inp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_ext_inp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates how many external inputs are implemented.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/numcidc
> > > +What:                /sys/bus/coresight/devices/etm<N>/numcidc
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of Context ID comparators that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/numvmidc
> > > +What:                /sys/bus/coresight/devices/etm<N>/numvmidc
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of VMID comparators that are available
> > >               for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nrseqstate
> > > +What:                /sys/bus/coresight/devices/etm<N>/nrseqstate
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of sequencer states that are
> > >               implemented.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_resource
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_resource
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of resource selection pairs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_ss_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_ss_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of single-shot comparator controls that
> > >               are available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/reset
> > > +What:                /sys/bus/coresight/devices/etm<N>/reset
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (W) Cancels all configuration on a trace unit and set it back
> > >               to its boot configuration.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mode
> > > +What:                /sys/bus/coresight/devices/etm<N>/mode
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -91,302 +91,349 @@ Description:    (RW) Controls various modes supported by this ETM, for example
> > >               P0 instruction tracing, branch broadcast, cycle counting and
> > >               context ID tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/pe
> > > +What:                /sys/bus/coresight/devices/etm<N>/pe
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls which PE to trace.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event
> > > +What:                /sys/bus/coresight/devices/etm<N>/event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the tracing of arbitrary events from bank 0 to 3.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_instren
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_instren
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the behavior of the events in bank 0 to 3.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_ts
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_ts
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the insertion of global timestamps in the trace
> > >               streams.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/syncfreq
> > > +What:                /sys/bus/coresight/devices/etm<N>/syncfreq
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls how often trace synchronization requests occur.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cyc_threshold
> > > +What:                /sys/bus/coresight/devices/etm<N>/cyc_threshold
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Sets the threshold value for cycle counting.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/bb_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/bb_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls which regions in the memory map are enabled to
> > >               use branch broadcasting.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls instruction trace filtering.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/s_exlevel_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/s_exlevel_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) In Secure state, each bit controls whether instruction
> > >               tracing is enabled for the corresponding exception level.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ns_exlevel_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/ns_exlevel_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) In non-secure state, each bit controls whether instruction
> > >               tracing is enabled for the corresponding exception level.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which address comparator or pair (of comparators) to
> > >               work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_instdatatype
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_instdatatype
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls what type of comparison the trace unit performs.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_single
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_single
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Used to setup single address comparator values.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_range
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_range
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Used to setup address range comparator values.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which sequensor.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_state
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_state
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Use this to set, or read, the sequencer state.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_event
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Moves the sequencer state to a specific state.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_reset_event
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_reset_event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Moves the sequencer to state 0 when a programmed event
> > >               occurs.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which counter unit to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntrldvr
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntrldvr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) This sets or returns the reload count value of the
> > >               specific counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_val
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_val
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) This sets or returns the current count value of the
> > >                  specific counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the operation of the selected counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/res_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/res_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which resource selection unit to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/res_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/res_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the selection of the resources in the trace unit.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Select which context ID comparator to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_pid
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_pid
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Get/Set the context ID comparator value to trigger on.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_masks
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_masks
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Mask for all 8 context ID comparator value
> > >               registers (if implemented).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Select which virtual machine ID comparator to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_val
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_val
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Get/Set the virtual machine ID comparator value to
> > >               trigger on.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_masks
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_masks
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Mask for all 8 virtual machine ID comparator value
> > >               registers (if implemented).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcoslsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_exlevel_s_ns
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Set the Exception Level matching bits for secure and
> > > +             non-secure exception levels.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/vinst_pe_cmp_start_stop
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the start stop control register for PE input
> > > +             comparators.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_cmp_view
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (R) Print the current settings for the selected address
> > > +             comparator.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_idx
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Select the single shot control register to access.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_ctrl
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the selected single shot control register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_status
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (R) Print the current value of the selected single shot
> > > +             status register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_pe_ctrl
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the selected single show PE comparator control
> > > +             register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcoslsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the OS Lock Status Register (0x304).
> > >               The value it taken directly  from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdcr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpdcr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Power Down Control Register
> > >               (0x310).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpdsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Power Down Status Register
> > >               (0x314).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trclsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trclsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the SW Lock Status Register
> > >               (0xFB4).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcauthstatus
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcauthstatus
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Authentication Status Register
> > >               (0xFB8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevid
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcdevid
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Device ID Register
> > >               (0xFC8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevtype
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcdevtype
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Device Type Register
> > >               (0xFCC).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr0
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr0
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID0 Register
> > >               (0xFE0).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr1
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr1
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID1 Register
> > >               (0xFE4).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr2
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr2
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID2 Register
> > >               (0xFE8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr3
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr3
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID3 Register
> > >               (0xFEC).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcconfig
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcconfig
> > >  Date:                February 2016
> > >  KernelVersion:       4.07
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the trace configuration register
> > >               (0x010) as currently set by SW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trctraceid
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trctraceid
> > >  Date:                February 2016
> > >  KernelVersion:       4.07
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the trace ID register (0x040).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr0
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr0
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the tracing capabilities of the trace unit (0x1E0).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr1
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr1
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the tracing capabilities of the trace unit (0x1E4).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr2
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr2
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -394,7 +441,7 @@ Description:      (R) Returns the maximum size of the data value, data address,
> > >               VMID, context ID and instuction address in the trace unit
> > >               (0x1E8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr3
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr3
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -403,42 +450,42 @@ Description:    (R) Returns the value associated with various resources
> > >               architecture specification for more details (0x1E8).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr4
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr4
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns how many resources the trace unit supports (0x1F0).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr5
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr5
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns how many resources the trace unit supports (0x1F4).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr8
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr8
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the maximum speculation depth of the instruction
> > >               trace stream. (0x180).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr9
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr9
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the number of P0 right-hand keys that the trace unit
> > >               can use (0x184).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr10
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr10
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the number of P1 right-hand keys that the trace unit
> > >               can use (0x188).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr11
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr11
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -446,7 +493,7 @@ Description:      (R) Returns the number of special P1 right-hand keys that the
> > >               trace unit can use (0x18C).  The value is taken directly from
> > >               the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr12
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr12
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -454,7 +501,7 @@ Description:      (R) Returns the number of conditional P1 right-hand keys that
> > >               the trace unit can use (0x190).  The value is taken directly
> > >               from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr13
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr13
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight/coresight-cpu-debug.txt
> > > similarity index 100%
> > > rename from Documentation/trace/coresight-cpu-debug.txt
> > > rename to Documentation/trace/coresight/coresight-cpu-debug.txt
> > > diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.txt b/Documentation/trace/coresight/coresight-etm4x-reference.txt
> > > new file mode 100644
> > > index 000000000000..72e81bbbef43
> > > --- /dev/null
> > > +++ b/Documentation/trace/coresight/coresight-etm4x-reference.txt
> > > @@ -0,0 +1,459 @@
> > > +ETMv4 sysfs linux driver programming reference - v2.
> > > +====================================================
> > > +
> > > +Supplement to existing ETMv4 driver documentation.
> > > +
> > > +Sysfs files and directories
> > > +---------------------------
> > > +
> > > +Root: /sys/bus/coresight/devices/etm<N>
> > > +
> > > +
> > > +The following paragraphs explain the association between sysfs files and the
> > > +ETMv4 registers that they effect. Note the register names are given without
> > > +the ‘TRC’ prefix.
> > > +
> > > +File         : mode (rw)
> > > +Trace Registers      : {CONFIGR + others}
> > > +Notes                : Bit select trace features. See ‘mode’ section below. Bits
> > > +             in this will cause equivalent programming of trace config and
> > > +             other registers to enable the features requested.
> > > +Syntax & eg  : 'echo bitfield > mode'
> > > +                     bitfield up to 32 bits setting trace features.
> > > +Example              : $> echo 0x > mode
> > > +
> > > +File         : reset (wo)
> > > +Trace Registers      : All
> > > +Notes                : Reset all programming to trace nothing / no logic programmed.
> > > +Syntax               : 'echo 1 > reset'
> > > +
> > > +File         : enable_source (wo)
> > > +Trace Registers      : PRGCTLR, All hardware regs.
> > > +Notes                :  >0: Programs up the hardware with the current values held in
> > > +             the driver and enables trace.
> > > +             0: disable trace hardware.
> > > +Syntax               : 'echo 1 > enable_source'
> > > +
> > > +File         : cpu (ro)
> > > +Trace Registers      : None.
> > > +Notes                : CPU ID that this ETM is attached to.
> > > +Example              :$> cat cpu
> > > +             $> 0
> > > +
> > > +File         : addr_idx (rw)
> > > +Trace Registers      : None.
> > > +Notes                : Virtual register to index address comparator and range
> > > +             features. Set index for first of the pair in a range.
> > > +Syntax               : 'echo idx > addr_idx'
> > > +             Where idx <  nr_addr_cmp x 2
> > > +
> > > +File         : addr_range (rw)
> > > +Trace Registers      : ACVR[idx, idx+1], VIIECTLR
> > > +Notes                : Pair of addresses for a range selected by addr_idx. Include
> > > +             / exclude according to the optional parameter, or if omitted
> > > +             uses the current ‘mode’ setting. Select comparator range in
> > > +             control register. Error if index is odd value.
> > > +Depends              : mode, addr_idx
> > > +Syntax               : 'echo addr1 addr2 [exclude] > addr_range'
> > > +             Where addr1 and addr2 define the range and addr1 < addr2.
> > > +             Optional exclude value - 0 for include, 1 for exclude.
> > > +Example              : $> echo 0x0000 0x2000 0 > addr_range
> > > +
> > > +File         : addr_single (rw)
> > > +Trace Registers      : ACVR[idx]
> > > +Notes                : Set a single address comparator according to addr_idx. This
> > > +             is used if the address comparator is used as part of event
> > > +             generation logic etc.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_single'
> > > +
> > > +File         : addr_start (rw)
> > > +Trace Registers      : ACVR[idx], VISSCTLR
> > > +Notes                : Set a trace start address comparator according to addr_idx.
> > > +             Select comparator in control register.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_start'
> > > +
> > > +File         : addr_stop (rw)
> > > +Trace Registers      : ACVR[idx], VISSCTLR
> > > +Notes                : Set a trace stop address comparator according to addr_idx.
> > > +             Select comparator in control register.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_stop'
> > > +
> > > +File         : addr_context (rw)
> > > +Trace Registers      : ACATR[idx,{6:4}]
> > > +Notes                : Link context ID comparator to address comparator addr_idx
> > > +Depends              : addr_idx.
> > > +Syntax               : 'echo ctxt_idx > addr_context'
> > > +             Where ctxt_idx is the index of the linked context id / vmid
> > > +             comparator.
> > > +
> > > +File         : addr_ctxtype (rw)
> > > +Trace Registers      : ACATR[idx,{3:2}]
> > > +Notes                : Input value string. Set type for linked context ID comparator
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo type > addr_ctxtype'
> > > +             Type one of {all, vmid, ctxid, none}
> > > +Example              : $> echo ctxid > addr_ctxtype
> > > +
> > > +File         : addr_exlevel_s_ns (rw)
> > > +Trace Registers      : ACATR[idx,{14:8}]
> > > +Notes                : Set the ELx secure and non-secure  matching bits for the
> > > +             selected address comparator
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo val > addr_exlevel_s_ns'
> > > +             val is a 7 bit value for exception levels to exclude. Input
> > > +             value shifted to correct bits in register.
> > > +Example              : $> echo 0x4F > addr_exlevel_s_ns
> > > +
> > > +File         : addr_instdatatype (rw)
> > > +Trace Registers      : ACATR[idx,{1:0}]
> > > +Notes                : Set the comparator address type for matching. Driver only
> > > +             supports setting instruction address type.
> > > +Depends              : addr_idx
> > > +
> > > +File         : addr_cmp_view (ro)
> > > +Trace Registers      : ACVR[idx, idx+1], ACATR[idx], VIIECTLR
> > > +Notes                : Read the currently selected address comparator. If part of
> > > +             address range then display both addresses.
> > > +Depends              : addr_idx
> > > +Syntax               : 'cat addr_cmp_view'
> > > +Example              : $> cat addr_cmp_view
> > > +             addr_cmp[0] range 0x0 0xffffffffffffffff include ctrl(0x4b00)
> > > +
> > > +File         : nr_addr_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of address comparator pairs
> > > +
> > > +File         : sshot_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select  single shot register set.
> > > +
> > > +File         : sshot_ctrl (rw)
> > > +Trace Registers      : SSCCR[idx]
> > > +Notes                : Access a single shot comparator control register.
> > > +Depends              : sshot_idx
> > > +Syntax               : 'echo val > sshot_ctrl'
> > > +             Writes val into the selected control register.
> > > +
> > > +File         : sshot_status (ro)
> > > +Trace Registers      : SSCSR[idx]
> > > +Notes                : Read a single shot comparator status register
> > > +Depends              : sshot_idx
> > > +Syntax               : 'cat sshot_status'
> > > +             Read status.
> > > +Example              : $> cat sshot_status
> > > +             0x1
> > > +
> > > +File         : sshot_pe_ctrl (rw)
> > > +Trace Registers      : SSPCICR[idx]
> > > +Notes                : Access a single shot PE comparator input control register.
> > > +Depends              : sshot_idx
> > > +Syntax               : echo val > sshot_pe_ctrl
> > > +             Writes val into the selected control register.
> > > +
> > > +File         : ns_exlevel_vinst (rw)
> > > +Trace Registers      : VICTLR{23:20}
> > > +Notes                : Program non-secure exception level filters. Set / clear NS
> > > +             exception filter bits. Setting ‘1’ excludes trace from the
> > > +             exception level.
> > > +Syntax               : 'echo bitfield > ns_exlevel_viinst'
> > > +             Where bitfield contains bits to set clear for EL0 to EL2
> > > +Example              : %> echo 0x4 > ns_exlevel_viinst
> > > +             ; Exclude EL2 NS trace.
> > > +
> > > +File         : vinst_pe_cmp_start_stop (rw)
> > > +Trace Registers      : VIPCSSCTLR
> > > +Notes                : Access PE start stop comparator input control registers
> > > +
> > > +File         : bb_ctrl (rw)
> > > +Trace Registers      : BBCTLR
> > > +Notes                : Define ranges that Branch Broadcast will operate in.
> > > +             Default (0x0) is all addresses.
> > > +Depends              : BB enabled.
> > > +
> > > +File         : cyc_threshold (rw)
> > > +Trace Registers      : CCCTLR
> > > +Notes                : Set the threshold for which cycle counts will be emitted.
> > > +             Error if attempt to set below minimum defined in IDR3, masked
> > > +             to width of valid bits.
> > > +Depends              : CC enabled.
> > > +
> > > +File         : syncfreq (rw)
> > > +Trace Registers      : SYNCPR
> > > +Notes                : Set trace synchronisation period. Power of 2 value, 0 (off)
> > > +             or 8-20. Driver defaults to 12 (every 4096 bytes).
> > > +
> > > +File         : cntr_idx (rw)
> > > +Trace Registers      : none
> > > +Notes                : Select the counter to access
> > > +Syntax               : 'echo idx > cntr_idx'
> > > +             Where idx <  nr_cntr
> > > +
> > > +File         : cntr_ctrl (rw)
> > > +Trace Registers      : CNTCTLR[idx]
> > > +Notes                : Set counter control value
> > > +Depends              : cntr_idx
> > > +Syntax               : 'echo val > cntr_ctrl'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : cntrldvr (rw)
> > > +Trace Registers      : CNTRLDVR[idx]
> > > +Notes                : Set counter reload value
> > > +Depends              : cntr_idx
> > > +Syntax               : 'echo val > cntrldvr'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : nr_cntr (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of counters implemented.
> > > +
> > > +File         : ctxid_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select the context ID comparator to access
> > > +Syntax               : 'echo idx > ctxid_idx'
> > > +             Where idx <  numcidc
> > > +
> > > +File         : ctxid_pid (rw)
> > > +Trace Registers      : CIDCVR[idx]
> > > +Notes                : Set the context ID comparator value
> > > +Depends              : ctxid_idx
> > > +
> > > +File         : ctxid_masks (rw)
> > > +Trace Registers      : CIDCCTLR0, CIDCCTLR1, CIDCVR<0-7>
> > > +Notes                : Pair of values to set the byte masks for 1-8 context ID
> > > +             comparators. Automatically clears masked bytes to 0 in CID
> > > +             value registers.
> > > +Syntax               : 'echo m3m2m1m0 [m7m6m5m4] > ctxid_masks'
> > > +             32 bit values made up of mask bytes, where mN represents a
> > > +             byte mask value for Ctxt ID comparator N.
> > > +             Second value not required on systems that have fewer than 4
> > > +             context ID comparators
> > > +
> > > +File         : numcidc (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of Context ID comparators
> > > +
> > > +File         : vmid_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select the VM ID comparator to access.
> > > +Syntax               : 'echo idx > vmid_idx'
> > > +             Where idx <  numvmidc
> > > +
> > > +File         : vmid_val (rw)
> > > +Trace Registers      : VMIDCVR[idx]
> > > +Notes                : Set the VM ID comparator value
> > > +Depends              : vmid_idx
> > > +
> > > +File         : vmid_masks (rw)
> > > +Trace Registers      : VMIDCCTLR0, VMIDCCTLR1, VMIDCVR<0-7>
> > > +Notes                : Pair of values to set the byte masks for 1-8 VM ID
> > > +             comparators. Automatically clears masked bytes to 0 in VMID
> > > +             value registers.
> > > +Syntax               : 'echo m3m2m1m0 [m7m6m5m4] > vmid_masks'
> > > +             Where mN represents a byte mask value for VMID comparator N.
> > > +             Second value not required on systems that have fewer than
> > > +             4 VMID comparators.
> > > +
> > > +File         : numvmidc (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of VMID comparators
> > > +
> > > +File         : res_idx (rw)
> > > +Trace Registers      : None.
> > > +Notes                : Select the resource selector control to access. Must be 2 or
> > > +             higher as selectors 0 and 1 are hardwired.
> > > +Syntax               : 'echo idx > res_idx'
> > > +             Where 2 <= idx <  nr_resource x 2
> > > +
> > > +File         : res_ctrl (rw)
> > > +Trace Registers      : RSCTLR[idx]
> > > +Notes                : Set resource selector control value. Value per ETMv4 spec.
> > > +Depends              : res_idx
> > > +Syntax               : 'echo val > res_cntr'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : nr_resource (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of resource selector pairs
> > > +
> > > +File         : event (rw)
> > > +Trace Registers      : EVENTCTRL0R
> > > +Notes                : Set up to 4 implemented event fields.
> > > +Syntax               : 'echo ev3ev2ev1ev0 > event'
> > > +             Where evN is an 8 bit event field. Up to 4 event fields make up
> > > +             the 32bit input value. Number of valid fields implementation
> > > +             dependent defined in IDR0.
> > > +
> > > +File         : event_instren (rw)
> > > +Trace Registers      : EVENTCTRL1R
> > > +Notes                : Choose events which insert event packets into trace stream.
> > > +Depends              : EVENTCTRL0R
> > > +Syntax               : 'echo bitfield > event_instren'
> > > +             Where bitfield is up to 4 bits according to number of event
> > > +             fields.
> > > +
> > > +File         : event_ts (rw)
> > > +Trace Registers      : TSCTLR
> > > +Notes                : Set the event that will generate timestamp requests.
> > > +Depends              : TS activated
> > > +Syntax               : 'echo evfield > event_ts'
> > > +             Where evfield is an 8 bit event selector.
> > > +
> > > +File         : seq_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Sequencer event register select - 0 to 2
> > > +
> > > +
> > > +File         : seq_state (rw)
> > > +Trace Registers      : SEQSTR
> > > +Notes                : Sequencer current state - 0 to 3.
> > > +
> > > +File         : seq_event (rw)
> > > +Trace Registers      : SEQEVR[idx]
> > > +Notes                : State transition event registers
> > > +Depends              : seq_idx
> > > +Syntax               : 'echo evBevF > seq_event'
> > > +             Where evBevF is a 16 bit value made up of two event selectors,
> > > +             evB - back, evF - forwards.
> > > +
> > > +File         : seq_reset_event (rw)
> > > +Trace Registers      : SEQRSTEVR
> > > +Notes                : Sequencer reset event
> > > +Syntax               : 'echo evfield > seq_reset_event'
> > > +             Where evfield is an 8 bit event selector.
> > > +
> > > +File         : nrseqstate (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of sequencer states (0 or 4)
> > > +
> > > +File         : nr_pe_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of PE comparator inputs
> > > +
> > > +File         : nr_ext_inp (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of external inputs
> > > +
> > > +File         : nr_ss_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of Single Shot control registers
> > > +
> > > +Note: When programming any address comparator the driver will tag the
> > > +comparator with a type used - i.e. RANGE, SINGLE, START, STOP. Once this tag
> > > +is set, then only the values can be changed using the same sysfs file / type
> > > +used to program it.
> > > +
> > > +Thus:-
> > > +% echo 0 > addr_idx              ; select address comparator 0
> > > +% echo 0x1000 0x5000 0 > addr_range ; set address range on comparators 0 and 1.
> > > +% echo 0x2000 > addr_start       ; this will error as comparator 0 is a
> > > +                                         ; range comparator
> > > +% echo 2 > addr_idx              ; select address comparator 2
> > > +% echo 0x2000 > addr_start       ; this is OK as comparator 2 is unused,
> > > +% echo 0x3000 > addr_stop        ; this will error as comparator 2 a start
> > > +                                         ; address comparator
> > > +% echo 2 > addr_idx              ; select address comparator 3
> > > +% echo 0x3000 > addr_stop        ; this is OK
> > > +
> > > +To remove programming on all the comparators (and all the other hardware) use
> > > +the reset parameter:
> > > +
> > > +% echo 1 > reset
> > > +
> > > +The ‘mode’ sysfs parameter.
> > > +---------------------------
> > > +
> > > +This is a bitfield selection parameter that sets the overall trace mode for the
> > > +ETM. The table below describes the bits, using the defines from the driver
> > > +source file, along with a description of the feature these represent. Many
> > > +features are optional and therefore dependent on implementation in the
> > > +hardware.
> > > +
> > > +Bit assignements shown below:-
> > > +
> > > +bit (0)          : #define ETM_MODE_EXCLUDE
> > > +description : This is the default value for the include / exclude function when
> > > +           setting address ranges. Set 1 for exclude range. When the mode
> > > +           parameter is set this value is applied to the currently indexed
> > > +           address range.
> > > +
> > > +bit (4)          : #define ETM_MODE_BB
> > > +description : Set to enable branch broadcast if supported in hardware [IDR0].
> > > +
> > > +bit (5)          : #define ETMv4_MODE_CYCACC
> > > +description : Set to enable cycle accurate trace if supported [IDR0].
> > > +
> > > +bit (6)          : ETMv4_MODE_CTXID
> > > +description : Set to enable context ID tracing if supported in hardware [IDR2].
> > > +
> > > +bit (7)          : ETM_MODE_VMID
> > > +description : Set to enable virtual machine ID tracing if supported [IDR2].
> > > +
> > > +bit (11)    : ETMv4_MODE_TIMESTAMP
> > > +description : Set to enable timestamp generation if supported [IDR0].
> > > +
> > > +bit (12)    : ETM_MODE_RETURNSTACK
> > > +description : Set to enable trace return stack use if supported [IDR0].
> > > +
> > > +bit (13-14) : ETM_MODE_QELEM(val)
> > > +description : ‘val’ determines level of Q element support enabled if
> > > +         implemented by the ETM [IDR0]
> > > +
> > > +bit (19)    : ETM_MODE_ATB_TRIGGER
> > > +description : Set to enable the ATBTRIGGER bit in the event control register
> > > +         [EVENTCTLR1] if supported [IDR5].
> > > +
> > > +bit (20)    : ETM_MODE_LPOVERRIDE
> > > +description : Set to enable the LPOVERRIDE bit in the event control register
> > > +         [EVENTCTLR1], if supported [IDR5].
> > > +
> > > +bit (21)    : ETM_MODE_ISTALL_EN
> > > +description : Set to enable the ISTALL bit in the stall control register
> > > +         [STALLCTLR]
> > > +
> > > +bit (23)    : ETM_MODE_INSTPRIO
> > > +description : Set to enable the INSTPRIORITY bit in the stall control register
> > > +         [STALLCTLR] , if supported [IDR0].
> > > +
> > > +bit (24)    : ETM_MODE_NOOVERFLOW
> > > +description : Set to enable the NOOVERFLOW bit in the stall control register
> > > +         [STALLCTLR], if supported [IDR3].
> > > +
> > > +bit (25)    : ETM_MODE_TRACE_RESET
> > > +description : Set to enable the TRCRESET bit in the viewinst control register
> > > +         [VICTLR] , if supported [IDR3].
> > > +
> > > +bit (26)    : ETM_MODE_TRACE_ERR
> > > +description : Set to enable the TRCCTRL bit in the viewinst control register
> > > +         [VICTLR].
> > > +
> > > +bit (27)    : ETM_MODE_VIEWINST_STARTSTOP
> > > +description : Set the initial state value of the ViewInst start / stop logic
> > > +         in the viewinst control register [VICTLR]
> > > +
> > > +bit (30)    : ETM_MODE_EXCL_KERN
> > > +description : Set default trace setup to exclude kernel mode trace (see note a)
> > > +
> > > +bit (31)    : ETM_MODE_EXCL_USER
> > > +description : Set default trace setup to exclude user space trace (see note a)
> > > +
> > > +Note a) On startup the ETM is programmed to trace the complete address space
> > > +using address range comparator 0. ‘mode’ bits 30 / 31 modify this setting to
> > > +set EL exclude bits for NS state in either user space (EL0) or kernel space
> > > +(EL1) in the address range comparator. (the default setting excludes all
> > > +secure EL, and NS EL2)
> > > +
> > > +Once the reset parameter has been used, and/or custom programming has been
> > > +implemented - using these bits will result in the EL bits for address
> > > +comparator 0 being set in the same way.
> > > +
> > > +Note b) Bits 2-3, 8-10, 15-16, 18, 22, control features that only work with
> > > +data trace. As A profile data trace is architecturally prohibited in ETMv4,
> > > +these have been omitted here. Possible uses could be where a kernel has
> > > +support for control of R or M profile infrastructure as part of a heterogeneous
> > > +system.
> > > +
> > > +Bits 17, 28-29 are unused.
> > > +
> > > diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight/coresight.txt
> > > similarity index 100%
> > > rename from Documentation/trace/coresight.txt
> > > rename to Documentation/trace/coresight/coresight.txt
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 783569e3c4b4..777b77fde29b 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1582,8 +1582,7 @@ R:      Suzuki K Poulose <suzuki.poulose@arm.com>
> > >  L:   linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> > >  S:   Maintained
> > >  F:   drivers/hwtracing/coresight/*
> > > -F:   Documentation/trace/coresight.txt
> > > -F:   Documentation/trace/coresight-cpu-debug.txt
> > > +F:   Documentation/trace/coresight/*
> > >  F:   Documentation/devicetree/bindings/arm/coresight.txt
> > >  F:   Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
> > >  F:   Documentation/ABI/testing/sysfs-bus-coresight-devices-*
> > > --
> > > 2.17.1
> > >
>
>
>
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/5] arm64: Use correct ll/sc atomic constraints
From: Andrew Murray @ 2019-08-28 16:42 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Peter Zijlstra, Catalin Marinas, Boqun Feng, Will Deacon,
	Ard.Biesheuvel, linux-arm-kernel
In-Reply-To: <20190828162409.GC42408@lakrids.cambridge.arm.com>

On Wed, Aug 28, 2019 at 05:24:09PM +0100, Mark Rutland wrote:
> On Wed, Aug 28, 2019 at 04:44:22PM +0100, Andrew Murray wrote:
> > On Wed, Aug 28, 2019 at 04:25:40PM +0100, Mark Rutland wrote:
> > > On Wed, Aug 28, 2019 at 02:01:19PM +0100, Andrew Murray wrote:
> > > > On Thu, Aug 22, 2019 at 04:32:23PM +0100, Mark Rutland wrote:
> > > > > On Mon, Aug 12, 2019 at 03:36:22PM +0100, Andrew Murray wrote:
> > > > > [...]
> > > > > 
> > > > > > -ATOMIC64_OPS(and, and)
> > > > > > -ATOMIC64_OPS(andnot, bic)
> > > > > > -ATOMIC64_OPS(or, orr)
> > > > > > -ATOMIC64_OPS(xor, eor)
> > > > > > +ATOMIC64_OPS(and, and, K)
> > > > > > +ATOMIC64_OPS(andnot, bic, )
> > > > > > +ATOMIC64_OPS(or, orr, K)
> > > > > > +ATOMIC64_OPS(xor, eor, K)
> > > > > 
> > > > > Shouldn't these be 'L'?
> > > > > 
> > > > > IIUC K is a subset of L, so if that's deliberate we should call that out
> > > > > explicitly...
> > > > 
> > > > Oooh yes that's wrong. I guess the atomic64_[and,or,xor] are rarely called
> > > > in the kernel which perhaps is why the compiler hasn't shouted at me.
> > > > 
> > > > Do you agree that the and, orr and eor should all be 'L' instead of 'K'?
> > > 
> > > Yes, I think all the 64-bit logical ops should all use 'L'.
> > 
> > With the exception of bic? I don't think there is an appropriate constraint
> > for this (it requires an 8 bit immediate).
> 
> The ARM ARM doesn't mention BIC (Immediate), and AFAICT that's an
> (undocumented?) alias for AND (Immediate) with a negated immediate.
> 
> Where did you find a description with an 8-bit immediate?
> 

I think it's a SIMD instruction, see C7.2.13 of ARM DDI 0487D or 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/EOR_log_imm.html

> Regardless, yes, drop the 'L' there -- I can't find any suitable
> constraint either.

OK I'll drop it, thanks for the feedback.

Thanks,

Andrew Murray

> 
> Thanks,
> Mark.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH V3 0/6] PCI: tegra: Enable PCIe C5 controller of Tegra194 in p2972-0000 platform
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv

This patch series enables Tegra194's C5 controller which owns x16 slot in
p2972-0000 platform. C5 controller's PERST# and CLKREQ# are not configured as
output and bi-directional signals by default and hence they need to be
configured explicitly. Also, x16 slot's 3.3V and 12V supplies are controlled
through GPIOs and hence they need to be enabled through regulator framework.
This patch series adds required infrastructural support to address both the
aforementioned requirements.
Testing done on p2972-0000 platform
- Able to enumerate devices connected to x16 slot (owned by C5 controller)
- Enumerated device's functionality verified
- Suspend-Resume sequence is verified with device connected to x16 slot
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1;
	t=1567013340; bh=TvQY7ZhhxcvoKbpcEAh6qHqIQEasISWH+/X/STdQQk0=;
	h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer:
	 X-NVConfidentiality:MIME-Version:Content-Type;
	b=gVtBiB2IR+pKYaZJQ+f6BYQX23e2leD7q8vdf+vr0+12GlPQc/30oFhIDgzGmLr3W
	 81mgV2Pp3bLNf9oNOB7tnv+yjoJK+qPGAB0bQ+VPMKGOkpvVfFtN4K3D+TkNjEQnQc
	 eBs35Pzc7zQ3jso4y80hoeIGegqfu4qLvORCW3qsy7OuPxjELUpGKvJTozekRSZVw3
	 voa570Uvaiotu9UgYqdAyJe0S4iuNUmJ8eWJDZLb9zkj1gfWhuQaDxt6bOMK8pyr7e
	 SVhNP0p2cTOaV0ALtd16tvi7+vRmcV4uQeArl0l1XPwxwHkR6ShLYbyji3Zb+JxJGN
	 vrTsP917B385w==

V3:
* Addressed some more review comments from Andrew Murray and Thierry Reding

V2:
* Changed the order of patches in the series for easy merging
* Addressed review comments from Thierry Reding and Andrew Murray

Vidya Sagar (6):
  dt-bindings: PCI: tegra: Add sideband pins configuration entries
  dt-bindings: PCI: tegra: Add PCIe slot supplies regulator entries
  PCI: tegra: Add support to configure sideband pins
  PCI: tegra: Add support to enable slot regulators
  arm64: tegra: Add configuration for PCIe C5 sideband signals
  arm64: tegra: Add PCIe slot supply information in p2972-0000 platform

 .../bindings/pci/nvidia,tegra194-pcie.txt     | 16 ++++
 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 24 +++++
 .../boot/dts/nvidia/tegra194-p2972-0000.dts   |  4 +-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      | 38 +++++++-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 94 ++++++++++++++++++-
 5 files changed, 172 insertions(+), 4 deletions(-)

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH V3 1/6] dt-bindings: PCI: tegra: Add sideband pins configuration entries
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add optional bindings "pinctrl-names" and "pinctrl-0" to describe pin
configuration information of a particular PCIe controller.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../devicetree/bindings/pci/nvidia,tegra194-pcie.txt      | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
index 674e5adb2895..0ac1b867ac24 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
@@ -83,6 +83,11 @@ Required properties:
 - vddio-pex-ctl-supply: Regulator supply for PCIe side band signals
 
 Optional properties:
+- pinctrl-names: A list of pinctrl state names.
+  It is mandatory for C5 controller and optional for other controllers.
+  - "default": Configures PCIe I/O for proper operation.
+- pinctrl-0: phandle for the 'default' state of pin configuration.
+  It is mandatory for C5 controller and optional for other controllers.
 - supports-clkreq: Refer to Documentation/devicetree/bindings/pci/pci.txt
 - nvidia,update-fc-fixup: This is a boolean property and needs to be present to
     improve performance when a platform is designed in such a way that it
@@ -120,6 +125,9 @@ Tegra194:
 		num-lanes = <8>;
 		linux,pci-domain = <0>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pex_rst_c5_out_state>, <&clkreq_c5_bi_dir_state>;
+
 		clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>;
 		clock-names = "core";
 
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 2/6] dt-bindings: PCI: tegra: Add PCIe slot supplies regulator entries
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add optional bindings "vpcie3v3-supply" and "vpcie12v-supply" to describe
regulators of a PCIe slot's supplies 3.3V and 12V provided the platform
is designed to have regulator controlled slot supplies.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../devicetree/bindings/pci/nvidia,tegra194-pcie.txt      | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
index 0ac1b867ac24..b739f92da58e 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
@@ -104,6 +104,12 @@ Optional properties:
    specified in microseconds
 - nvidia,aspm-l0s-entrance-latency-us: ASPM L0s entrance latency to be
    specified in microseconds
+- vpcie3v3-supply: A phandle to the regulator node that supplies 3.3V to the slot
+  if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
+  in p2972-0000 platform).
+- vpcie12v-supply: A phandle to the regulator node that supplies 12V to the slot
+  if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
+  in p2972-0000 platform).
 
 Examples:
 =========
@@ -156,6 +162,8 @@ Tegra194:
 			  0xc2000000 0x18 0x00000000 0x18 0x00000000 0x4 0x00000000>;  /* prefetchable memory (16GB) */
 
 		vddio-pex-ctl-supply = <&vdd_1v8ao>;
+		vpcie3v3-supply = <&vdd_3v3_pcie>;
+		vpcie12v-supply = <&vdd_12v_pcie>;
 
 		phys = <&p2u_hsio_2>, <&p2u_hsio_3>, <&p2u_hsio_4>,
 		       <&p2u_hsio_5>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 3/6] PCI: tegra: Add support to configure sideband pins
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to configure sideband signal pins when information is present
in respective controller's device-tree node.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* Used 'dev' instead of 'pcie->dev'

V2:
* Addressed review comment from Andrew Murray
* Handled failure case of pinctrl_pm_select_default_state() cleanly

 drivers/pci/controller/dwc/pcie-tegra194.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index fc0dbeb31d78..77fa6f70bc96 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1304,8 +1304,13 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
 	if (ret < 0) {
 		dev_err(dev, "Failed to get runtime sync for PCIe dev: %d\n",
 			ret);
-		pm_runtime_disable(dev);
-		return ret;
+		goto fail_pm_get_sync;
+	}
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret < 0) {
+		dev_err(dev, "Failed to configure sideband pins: %d\n", ret);
+		goto fail_pinctrl;
 	}
 
 	tegra_pcie_init_controller(pcie);
@@ -1332,7 +1337,9 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
 
 fail_host_init:
 	tegra_pcie_deinit_controller(pcie);
+fail_pinctrl:
 	pm_runtime_put_sync(dev);
+fail_pm_get_sync:
 	pm_runtime_disable(dev);
 	return ret;
 }
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 4/6] PCI: tegra: Add support to enable slot regulators
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to get regulator information of 3.3V and 12V supplies of a PCIe
slot from the respective controller's device-tree node and enable those
supplies. This is required in platforms like p2972-0000 where the supplies
to x16 slot owned by C5 controller need to be enabled before attempting to
enumerate the devices.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* Added a dev_err() print for failure case of tegra_pcie_get_slot_regulators() API
* Modified to make 100ms sleep valid only if at least one of the regulator handles exist

V2:
* Addressed review comments from Thierry Reding and Andrew Murray
* Handled failure case of devm_regulator_get_optional() for -ENODEV cleanly

 drivers/pci/controller/dwc/pcie-tegra194.c | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 77fa6f70bc96..18453cc5e7e4 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -278,6 +278,8 @@ struct tegra_pcie_dw {
 	u32 aspm_l0s_enter_lat;
 
 	struct regulator *pex_ctl_supply;
+	struct regulator *slot_ctl_3v3;
+	struct regulator *slot_ctl_12v;
 
 	unsigned int phy_count;
 	struct phy **phys;
@@ -1047,6 +1049,73 @@ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
 	}
 }
 
+static int tegra_pcie_get_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	pcie->slot_ctl_3v3 = devm_regulator_get_optional(pcie->dev, "vpcie3v3");
+	if (IS_ERR(pcie->slot_ctl_3v3)) {
+		if (PTR_ERR(pcie->slot_ctl_3v3) != -ENODEV)
+			return PTR_ERR(pcie->slot_ctl_3v3);
+
+		pcie->slot_ctl_3v3 = NULL;
+	}
+
+	pcie->slot_ctl_12v = devm_regulator_get_optional(pcie->dev, "vpcie12v");
+	if (IS_ERR(pcie->slot_ctl_12v)) {
+		if (PTR_ERR(pcie->slot_ctl_12v) != -ENODEV)
+			return PTR_ERR(pcie->slot_ctl_12v);
+
+		pcie->slot_ctl_12v = NULL;
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_enable_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	int ret;
+
+	if (pcie->slot_ctl_3v3) {
+		ret = regulator_enable(pcie->slot_ctl_3v3);
+		if (ret < 0) {
+			dev_err(pcie->dev,
+				"Failed to enable 3.3V slot supply: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (pcie->slot_ctl_12v) {
+		ret = regulator_enable(pcie->slot_ctl_12v);
+		if (ret < 0) {
+			dev_err(pcie->dev,
+				"Failed to enable 12V slot supply: %d\n", ret);
+			goto fail_12v_enable;
+		}
+	}
+
+	/*
+	 * According to PCI Express Card Electromechanical Specification
+	 * Revision 1.1, Table-2.4, T_PVPERL (Power stable to PERST# inactive)
+	 * should be a minimum of 100ms.
+	 */
+	if (pcie->slot_ctl_3v3 || pcie->slot_ctl_12v)
+		msleep(100);
+
+	return 0;
+
+fail_12v_enable:
+	if (pcie->slot_ctl_3v3)
+		regulator_disable(pcie->slot_ctl_3v3);
+	return ret;
+}
+
+static void tegra_pcie_disable_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	if (pcie->slot_ctl_12v)
+		regulator_disable(pcie->slot_ctl_12v);
+	if (pcie->slot_ctl_3v3)
+		regulator_disable(pcie->slot_ctl_3v3);
+}
+
 static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 					bool en_hw_hot_rst)
 {
@@ -1060,6 +1129,10 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 		return ret;
 	}
 
+	ret = tegra_pcie_enable_slot_regulators(pcie);
+	if (ret < 0)
+		goto fail_slot_reg_en;
+
 	ret = regulator_enable(pcie->pex_ctl_supply);
 	if (ret < 0) {
 		dev_err(pcie->dev, "Failed to enable regulator: %d\n", ret);
@@ -1142,6 +1215,8 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 fail_core_clk:
 	regulator_disable(pcie->pex_ctl_supply);
 fail_reg_en:
+	tegra_pcie_disable_slot_regulators(pcie);
+fail_slot_reg_en:
 	tegra_pcie_bpmp_set_ctrl_state(pcie, false);
 
 	return ret;
@@ -1174,6 +1249,8 @@ static int __deinit_controller(struct tegra_pcie_dw *pcie)
 		return ret;
 	}
 
+	tegra_pcie_disable_slot_regulators(pcie);
+
 	ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false);
 	if (ret) {
 		dev_err(pcie->dev, "Failed to disable controller %d: %d\n",
@@ -1373,6 +1450,12 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = tegra_pcie_get_slot_regulators(pcie);
+	if (ret < 0) {
+		dev_err(dev, "Failed to get slot regulators: %d\n", ret);
+		return ret;
+	}
+
 	pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");
 	if (IS_ERR(pcie->pex_ctl_supply)) {
 		dev_err(dev, "Failed to get regulator: %ld\n",
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 5/6] arm64: tegra: Add configuration for PCIe C5 sideband signals
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to configure PCIe C5's sideband signals PERST# and CLKREQ#
as output and bi-directional signals respectively which unlike other
PCIe controllers sideband signals are not configured by default.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 38 +++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index adebbbf36bd0..3c0cf54f0aab 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -3,8 +3,9 @@
 #include <dt-bindings/gpio/tegra194-gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/mailbox/tegra186-hsp.h>
-#include <dt-bindings/reset/tegra194-reset.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
 #include <dt-bindings/power/tegra194-powergate.h>
+#include <dt-bindings/reset/tegra194-reset.h>
 #include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
 
 / {
@@ -130,6 +131,38 @@
 			};
 		};
 
+		pinmux: pinmux@2430000 {
+			compatible = "nvidia,tegra194-pinmux";
+			reg = <0x2430000 0x17000
+			       0xc300000 0x4000>;
+
+			status = "okay";
+
+			pex_rst_c5_out_state: pex_rst_c5_out {
+				pex_rst {
+					nvidia,pins = "pex_l5_rst_n_pgg1";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+
+			clkreq_c5_bi_dir_state: clkreq_c5_bi_dir {
+				clkreq {
+					nvidia,pins = "pex_l5_clkreq_n_pgg0";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+		};
+
 		uarta: serial@3100000 {
 			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
 			reg = <0x03100000 0x40>;
@@ -1365,6 +1398,9 @@
 		num-viewport = <8>;
 		linux,pci-domain = <5>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pex_rst_c5_out_state>, <&clkreq_c5_bi_dir_state>;
+
 		clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>,
 			<&bpmp TEGRA194_CLK_PEX1_CORE_5M>;
 		clock-names = "core", "core_m";
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 6/6] arm64: tegra: Add PCIe slot supply information in p2972-0000 platform
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add 3.3V and 12V supplies regulators information of x16 PCIe slot in
p2972-0000 platform which is owned by C5 controller and also enable C5
controller.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 24 +++++++++++++++++++
 .../boot/dts/nvidia/tegra194-p2972-0000.dts   |  4 +++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index 62e07e1197cc..4c38426a6969 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -289,5 +289,29 @@
 			gpio = <&gpio TEGRA194_MAIN_GPIO(A, 3) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
+
+		vdd_3v3_pcie: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+
+			regulator-name = "PEX_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio TEGRA194_MAIN_GPIO(Z, 2) GPIO_ACTIVE_HIGH>;
+			regulator-boot-on;
+			enable-active-high;
+		};
+
+		vdd_12v_pcie: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+
+			regulator-name = "VDD_12V";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_LOW>;
+			regulator-boot-on;
+			enable-active-low;
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
index 23597d53c9c9..d47cd8c4dd24 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
@@ -93,9 +93,11 @@
 	};
 
 	pcie@141a0000 {
-		status = "disabled";
+		status = "okay";
 
 		vddio-pex-ctl-supply = <&vdd_1v8ao>;
+		vpcie3v3-supply = <&vdd_3v3_pcie>;
+		vpcie12v-supply = <&vdd_12v_pcie>;
 
 		phys = <&p2u_nvhs_0>, <&p2u_nvhs_1>, <&p2u_nvhs_2>,
 		       <&p2u_nvhs_3>, <&p2u_nvhs_4>, <&p2u_nvhs_5>,
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [GIT PULL] arm64: Fixes for -rc7
From: Will Deacon @ 2019-08-28 17:32 UTC (permalink / raw)
  To: torvalds
  Cc: kvm, rkrcmar, marc.zyngier, catalin.marinas, linux-kernel,
	pbonzini, kvmarm, linux-arm-kernel

Hi Linus,

Hot on the heels of our last set of fixes are a few more for -rc7. Two
of them are fixing issues with our virtual interrupt controller
implementation in KVM/arm, while the other is a longstanding but
straightforward kallsyms fix which was been acked by Masami and resolves
an initialisation failure in kprobes observed on arm64.

Please pull, thanks.

Will

--->8

The following changes since commit b6143d10d23ebb4a77af311e8b8b7f019d0163e6:

  arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side (2019-08-16 17:40:03 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 82e40f558de566fdee214bec68096bbd5e64a6a4:

  KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI (2019-08-28 11:21:42 +0100)

----------------------------------------------------------------
arm64 fixes for -rc7

- Fix GICv2 emulation bug (KVM)

- Fix deadlock in virtual GIC interrupt injection code (KVM)

- Fix kprobes blacklist init failure due to broken kallsyms lookup

----------------------------------------------------------------
Heyi Guo (1):
      KVM: arm/arm64: vgic: Fix potential deadlock when ap_list is long

Marc Zyngier (2):
      kallsyms: Don't let kallsyms_lookup_size_offset() fail on retrieving the first symbol
      KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI

 kernel/kallsyms.c             |  6 ++++--
 virt/kvm/arm/vgic/vgic-mmio.c | 18 ++++++++++++++++++
 virt/kvm/arm/vgic/vgic-v2.c   |  5 ++++-
 virt/kvm/arm/vgic/vgic-v3.c   |  5 ++++-
 virt/kvm/arm/vgic/vgic.c      |  7 +++++++
 5 files changed, 37 insertions(+), 4 deletions(-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 02/11] kselftest: arm64: adds first test and common utils
From: Cristian Marussi @ 2019-08-28 17:34 UTC (permalink / raw)
  To: Dave Martin; +Cc: andreyknvl, shuah, linux-arm-kernel, linux-kselftest
In-Reply-To: <20190813162411.GZ10425@arm.com>

Hi

On 13/08/2019 17:24, Dave Martin wrote:
> For the subject line, maybe name the test being added (same as for the
> other patches).

I doubt to be able to fit within 50 chars Subject line constraint, if I add
the test case name.

> 
> On Fri, Aug 02, 2019 at 06:02:51PM +0100, Cristian Marussi wrote:
>> Added some arm64/signal specific boilerplate and utility code to help
>> further testcase development.
>>
>> A simple testcase and related helpers are also introduced in this commit:
>> mangle_pstate_invalid_compat_toggle is a simple mangle testcase which
>> messes with the ucontext_t from within the sig_handler, trying to toggle
> 
> "signal handler"?
> 

ok

>> PSTATE state bits to switch the system between 32bit/64bit execution state.
>> Expects SIGSEGV on test PASS.
>>
>> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
>> ---
>> A few fixes:
>> - test_arm64_signals.sh runner script generation has been reviewed in order to
>>   be safe against the .gitignore
>> - using kselftest.h officially provided defines for tests' return values
>> - removed SAFE_WRITE()/dump_uc()
>> - looking for si_code==SEGV_ACCERR on SEGV test cases to better understand if
>>   the sigfault had been directly triggered by Kernel
>> ---
>>  tools/testing/selftests/arm64/Makefile        |   2 +-
>>  .../testing/selftests/arm64/signal/.gitignore |   6 +
>>  tools/testing/selftests/arm64/signal/Makefile |  88 ++++++
>>  tools/testing/selftests/arm64/signal/README   |  59 ++++
>>  .../arm64/signal/test_arm64_signals.src_shell |  55 ++++
>>  .../selftests/arm64/signal/test_signals.c     |  26 ++
>>  .../selftests/arm64/signal/test_signals.h     | 137 +++++++++
>>  .../arm64/signal/test_signals_utils.c         | 261 ++++++++++++++++++
>>  .../arm64/signal/test_signals_utils.h         |  13 +
>>  .../arm64/signal/testcases/.gitignore         |   1 +
>>  .../mangle_pstate_invalid_compat_toggle.c     |  25 ++
>>  .../arm64/signal/testcases/testcases.c        | 150 ++++++++++
>>  .../arm64/signal/testcases/testcases.h        |  83 ++++++
>>  13 files changed, 905 insertions(+), 1 deletion(-)
>>  create mode 100644 tools/testing/selftests/arm64/signal/.gitignore
>>  create mode 100644 tools/testing/selftests/arm64/signal/Makefile
>>  create mode 100644 tools/testing/selftests/arm64/signal/README
>>  create mode 100755 tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals.h
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.h
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/.gitignore
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.h
>>
>> diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
>> index 03a0d4f71218..af59dc74e0dc 100644
>> --- a/tools/testing/selftests/arm64/Makefile
>> +++ b/tools/testing/selftests/arm64/Makefile
>> @@ -6,7 +6,7 @@ ARCH ?= $(shell uname -m)
>>  ARCH := $(shell echo $(ARCH) | sed -e s/aarch64/arm64/)
>>  
>>  ifeq ("x$(ARCH)", "xarm64")
>> -SUBDIRS :=
>> +SUBDIRS := signal
>>  else
>>  SUBDIRS :=
>>  endif
>> diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
>> new file mode 100644
>> index 000000000000..434f65c15f03
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/.gitignore
>> @@ -0,0 +1,6 @@
>> +# Helper script's internal testcases list (TPROGS) is regenerated
>> +# each time by Makefile on standalone (non KSFT driven) runs.
>> +# Committing such list creates a dependency between testcases
>> +# patches such that they are no more easily revertable. Just ignore.
>> +test_arm64_signals.src_shell
>> +test_arm64_signals.sh
>> diff --git a/tools/testing/selftests/arm64/signal/Makefile b/tools/testing/selftests/arm64/signal/Makefile
>> new file mode 100644
>> index 000000000000..8c8d08be4b0d
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/Makefile
>> @@ -0,0 +1,88 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2019 ARM Limited
>> +
>> +# Supports also standalone invokation out of KSFT-tree
>> +# Compile standalone and run on your device with:
>> +#
>> +#  $ make -C tools/testing/selftests/arm64/signal INSTALL_PATH=<your-dir> install
> 
> I'm wondering whether supporting stand-alone invocation is actually
> worth it.  Maybe this just adds complexity for little benefit.
> 
> Although it's useful for debugging and development, it doesn't look like
> other tests in kselftest support standalone invocation -- did I miss
> some?

I introduced standalone to be able to 'detach' from KSFT during tests' devel phase,
but it does not seem worth all this work to maintain it. So I'm removing it in V4.

> 
>> +#
>> +# Run standalone on device with:
>> +#
>> +#  $ <your-device-instdir>/test_arm64_signals.sh [-k|-v]
>> +#
>> +# If INSTALL_PATH= is NOT provided it will default to ./install
>> +
>> +# A proper top_srcdir is needed both by KSFT(lib.mk)
>> +# and standalone builds
>> +top_srcdir = ../../../../..
>> +
>> +CFLAGS += -std=gnu99 -I. -I$(top_srcdir)/tools/testing/selftests/
>> +SRCS := $(filter-out testcases/testcases.c,$(wildcard testcases/*.c))
>> +PROGS := $(patsubst %.c,%,$(SRCS))
>> +
>> +# Guessing as best as we can where the Kernel headers
>> +# could have been installed depending on ENV config and
>> +# type of invocation.
>> +ifeq ($(KBUILD_OUTPUT),)
>> +khdr_dir = $(top_srcdir)/usr/include
>> +else
>> +ifeq (0,$(MAKELEVEL))
>> +khdr_dir = $(KBUILD_OUTPUT)/usr/include
>> +else
>> +# the KSFT preferred location when KBUILD_OUTPUT is set
>> +khdr_dir = $(KBUILD_OUTPUT)/kselftest/usr/include
>> +endif
>> +endif
> 
> When is KBUILD_OUTPUT set / not set?
> 

Depending how the user/CI is configured KSFT installs the kernel
headers in different places....here I'm trying to guess where they
have been installed by KSFT.

>> +
>> +CFLAGS += -I$(khdr_dir)
> 
> Do we rely on any non-UAPI headers?  If not, the default should probably
> be to rely on the system headers (or toolchain default headers) -- i.e.,
> add no -I option at all.

I only need updated UAPI headers, but I cannot build without this specific -I..
that points to the installed kernel headers directory.

As an example it fails with: undefined  HWCAP_SSBS if I remove the -I

> 
> I'm wondering why none of the other kselftests need this header search
> logic.
> 

Well... a lot of KSFT tests has something related to headers search in their Makefiles:

../kcmp/Makefile:CFLAGS += -I../../../../usr/include/
../networking/timestamping/Makefile:CFLAGS += -I../../../../../usr/include
../ipc/Makefile:CFLAGS += -I../../../../usr/include/
../memfd/Makefile:CFLAGS += -I../../../../include/uapi/
../memfd/Makefile:CFLAGS += -I../../../../include/
../memfd/Makefile:CFLAGS += -I../../../../usr/include/

which seems aimed at doing the same thing, but it is a broken approach
as far as I can see since if KBUILD_OUTPUT is set, KSFT will install the
headers accordingly, so that the above static includes won't work anymore.

Not sure if I'm missing something here, but my understanding was that

- some KSFT requires arch specific bits, usually included within the dedicated kernel
headers provided with the source itself and installed with make headers_install.

and that

- such headers can be found naturally, being included from top level libc headers
only if:

1. a fully updated toolchain containing updated headers too is available at CROSS_COMPILE=

or

2. proper -I options are specified to the compiler to specify where KSFT installed the 
  kernel headers related to this kernel and its related KSFT testcases

or

3. updated kernel headers were installed on top of the available CROSS_COMPILE toolchain

or

4. we are building and running natively, so you can install the kernel headers on
   system default path and those will be searched


My 'feeling' would have been that in the KSFT scenario we should try to stick with option  2.,
in order to be able to run KSFT and run the related testcases, relying just on the shipped
Kernel/KSFT and possibly underlying hw features, but not having any dependencies
on the toolchain/libc.

My question is: what happens on a CI-somewhere if suddenly there's the need to update
the toolchain somehow (fully or partially only the headers) to be able to simply
build/run the new KSFT included with this Kernel ?; even if we accept this need to update
the toochain, where this CI should get/scrap-from these minimum toolchain requirements ?
(in an automated manner)

If instead we can agree to stick with 2.,  I wonder if this locate-headers mechanism which I introduced
here should be in charge of the KSFT framework or if there is something broken in my tests: but 
in these regards similar issues seems to affect KSFT arm64 tags tests queued on arm64/for-next

https://lkml.org/lkml/2019/8/23/721


>> +
>> +# Standalone run
>> +ifeq (0,$(MAKELEVEL))
>> +CC := $(CROSS_COMPILE)gcc
>> +RUNNER_SRC = test_arm64_signals.src_shell
>> +RUNNER = test_arm64_signals.sh
>> +INSTALL_PATH ?= install/
>> +
>> +all: $(RUNNER)
>> +
>> +$(RUNNER): $(PROGS)
> 
> $(RUNNER_SRC) should also be in the dependencies here.
> 
>> +	cp $(RUNNER_SRC) $(RUNNER)
>> +	sed -i -e 's#PROGS=.*#PROGS="$(PROGS)"#' $@
> 
> Or just a single command: sed -e '...' <$< >$@

I'll drop all of this together with standalone mode.
> 
>> +
>> +install: all
>> +	mkdir -p $(INSTALL_PATH)/testcases
>> +	cp $(PROGS) $(INSTALL_PATH)/testcases
>> +	cp $(RUNNER) $(INSTALL_PATH)/
>> +
>> +.PHONY clean:
>> +	rm -f $(PROGS)
>> +# KSFT run
>> +else
>> +# Generated binaries to be installed by top KSFT script
>> +TEST_GEN_PROGS := $(notdir $(PROGS))
>> +
>> +# Get Kernel headers installed and use them.
>> +KSFT_KHDR_INSTALL := 1
>> +
>> +# This include mk will also mangle the TEST_GEN_PROGS list
>> +# to account for any OUTPUT target-dirs optionally provided
>> +# by the toplevel makefile
>> +include ../../lib.mk
>> +
>> +$(TEST_GEN_PROGS): $(PROGS)
>> +	cp $(PROGS) $(OUTPUT)/
>> +
>> +clean:
>> +	$(CLEAN)
>> +	rm -f $(PROGS)
>> +endif
>> +
>> +# Common test-unit targets to build common-layout test-cases executables
>> +# Needs secondary expansion to properly include the testcase c-file in pre-reqs
>> +.SECONDEXPANSION:
>> +$(PROGS): test_signals.c test_signals_utils.c testcases/testcases.c $$@.c test_signals.h test_signals_utils.h testcases/testcases.h
>> +	@if [ ! -d $(khdr_dir) ]; then \
>> +		echo -n "\n!!! WARNING: $(khdr_dir) NOT FOUND."; \
>> +		echo "===>  Are you sure Kernel Headers have been installed properly ?\n"; \
>> +	fi
>> +	$(CC) $(CFLAGS) $^ -o $@
>> diff --git a/tools/testing/selftests/arm64/signal/README b/tools/testing/selftests/arm64/signal/README
>> new file mode 100644
>> index 000000000000..53f005f7910a
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/README
>> @@ -0,0 +1,59 @@
>> +KSelfTest arm64/signal/
>> +=======================
>> +
>> +Signals Tests
>> ++++++++++++++
>> +
>> +- Tests are built around a common main compilation unit: such shared main
>> +  enforces a standard sequence of operations needed to perform a single
>> +  signal-test (setup/trigger/run/result/cleanup)
>> +
>> +- The above mentioned ops are configurable on a test-by-test basis: each test
>> +  is described (and configured) using the descriptor signals.h::struct tdescr
>> +
>> +- Each signal testcase is compiled into its own executable: a separate
>> +  executable is used for each test since many tests complete successfully
>> +  by receiving some kind of fatal signal from the Kernel, so it's safer
>> +  to run each test unit in its own standalone process, so as to start each
>> +  test from a clean slate.
>> +
>> +- New tests can be simply defined in testcases/ dir providing a proper struct
>> +  tdescr overriding all the defaults we wish to change (as of now providing a
>> +  custom run method is mandatory though)
>> +
>> +- Signals' test-cases hereafter defined belong currently to two
>> +  principal families:
>> +
>> +  - 'mangle_' tests: a real signal (SIGUSR1) is raised and used as a trigger
>> +    and then the test case code messes-up with the sigframe ucontext_t from
>> +    inside the sighandler itself.
> 
> "messes-up" makes it sound a bit like the test case code itself goes
> wrong.
> 
> Maybe just say something like "the test case code modifies the signal
> frame from inside the signal handler itself."

ok
> 
>> +
>> +  - 'fake_sigreturn_' tests: a brand new custom artificial sigframe structure
>> +    is placed on the stack and a sigreturn syscall is called to simulate a
>> +    real signal return. This kind of tests does not use a trigger usually and
>> +    they are just fired using some simple included assembly trampoline code.
>> +
>> + - Most of these tests are successfully passing if the process gets killed by
>> +   some fatal signal: usually SIGSEGV or SIGBUS. Since while writing this
>> +   kind of tests it is extremely easy in fact to end-up injecting other
>> +   unrelated SEGV bugs in the testcases, it becomes extremely tricky to
>> +   be really sure that the tests are really addressing what they are meant
>> +   to address and they are not instead falling apart due to unplanned bugs
>> +   in the test code.
>> +   In order to alleviate the misery of the life of such test-developer, a few
>> +   helpers are provided:
>> +
>> +   - a couple of ASSERT_BAD/GOOD_CONTEXT() macros to easily parse a ucontext_t
>> +     and verify if it is indeed GOOD or BAD (depending on what we were
>> +     expecting), using the same logic/perspective as in the arm64 Kernel signals
>> +     routines.
>> +
>> +   - a sanity mechanism to be used in 'fake_sigreturn_'-alike tests: enabled by
>> +     default it takes care to verify that the test-execution had at least
>> +     successfully progressed up to the stage of triggering the fake sigreturn
>> +     call.
>> +
>> +  In both cases test results are expected in terms of:
>> +   - some fatal signal sent by the Kernel to the test process
>> +  or
>> +  - analyzing some final regs state
>> diff --git a/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
>> new file mode 100755
>> index 000000000000..163e941e2997
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> 
> Unusual filename?
> 
> In the non-standalone case, is this run directly with TPROGS set in the
> environment instead of modifying the script?  (I haven't understood all
> the logic yet.)
> 
> If so, it is a shell script, and should just be called
> test_arm64_signals.sh
> 
> Otherwise, it's a non-executable template for a shell script, so should
> have 0644 permissions and could be called test_arm64_signals.sh.in or
> test_arm64_signals.sh.template, say.
> 

It's a non-executable template for a shell script and all of this is needed
only in standalone mode. I'm dropping it.
(this re-generation on the fly from a template was needed to properly .gitignoring this)

>> @@ -0,0 +1,55 @@
>> +#!/bin/sh
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2019 ARM Limited
>> +
>> +ret=0
>> +keep_on_fail=0
>> +err_out="2> /dev/null"
>> +
>> +usage() {
>> +	echo "Usage: `basename $0` [-v] [-k]"
>> +	exit 1
>> +}
>> +
>> +# avoiding getopt to avoid compatibility issues on targets
>> +# with limited resources
>> +while [ $# -gt 0 ]
>> +do
>> +	case $1 in
>> +		"-k")
>> +			keep_on_fail=1
>> +			;;
>> +		"-v")
>> +			err_out=
>> +			;;
>> +		*)
>> +			usage
>> +			;;
>> +	esac
>> +	shift
>> +done
>> +
>> +TPROGS=
>> +
>> +tot=$(echo $TPROGS | wc -w)
>> +
>> +# Tests are expected in testcases/ subdir inside the installation path
>> +workdir="`dirname $0 2>/dev/null`"
>> +[ -n $workdir ] && cd $workdir
>> +
>> +passed=0
>> +run=0
>> +for test in $TPROGS
>> +do
>> +	run=$((run + 1))
>> +	eval ./$test $err_out
>> +	if [ $? != 0 ]; then
>> +		[ $keep_on_fail = 0 ] && echo "===>>> FAILED:: $test <<<===" && ret=1 && break
>> +	else
>> +		passed=$((passed + 1))
>> +	fi
>> +done
>> +
>> +echo "==>> PASSED: $passed/$run on $tot available tests."
>> +
>> +exit $ret
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals.c b/tools/testing/selftests/arm64/signal/test_signals.c
>> new file mode 100644
>> index 000000000000..3447d7011aec
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals.c
>> @@ -0,0 +1,26 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
> 
> We should probably have a brief comment to say what this is.
> For example:
> 
> /*
>  * Generic test wrapper for arm64 signal tests
>  * Each test provides its own tde to link with this wrapper.
>  */
> 
Ok I'll do.

>> +
>> +#include <kselftest.h>
>> +
>> +#include "test_signals.h"
>> +#include "test_signals_utils.h"
>> +
>> +struct tdescr *current;
>> +extern struct tdescr tde;
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +	current = &tde;
>> +
>> +	ksft_print_msg("%s :: %s - SIG_TRIG:%d  SIG_OK:%d -- current:%p\n",
>> +		       current->name, current->descr, current->sig_trig,
>> +		       current->sig_ok, current);
> 
> Does the user need all this?
> 
> It's sufficient to print the test name, a one-line description and
> results.  If something goes wrong, we can print a bit more detail.
> 
> Maybe just do something like
> 
> #ifdef DEBUG
> #define debug_printf(format, ...) ksft_print_msg(format, ## __VA_ARGS__)
> #else
> #define debug_printf(format, ...) ((void)0)
> #endif
> 
> (Unless kselftest already has something like this, in which case you
> could just use that.)

I don't think KSFT has this capability by itself.
I was thinking about reducing verbosity.

> 
>> +	if (test_setup(current)) {
>> +		if (test_run(current))
>> +			test_result(current);
>> +		test_cleanup(current);
>> +	}
>> +
>> +	return current->pass ? KSFT_PASS : KSFT_FAIL;
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
>> new file mode 100644
>> index 000000000000..85db3ac44b32
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals.h
>> @@ -0,0 +1,137 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#ifndef __TEST_SIGNALS_H__
>> +#define __TEST_SIGNALS_H__
>> +
>> +#include <assert.h>
>> +#include <stdbool.h>
>> +#include <signal.h>
>> +#include <ucontext.h>
>> +#include <stdint.h>
> 
> Does anything in this header use <assert.h> or <stdint.h>?
> 

Probably no more...I'll check.

>> +
>> +/*
>> + * Using ARCH specific and sanitized Kernel headers installed by KSFT
>> + * framework since we asked for it by setting flag KSFT_KHDR_INSTALL
>> + * in our Makefile.
>> + */
>> +#include <asm/ptrace.h>
>> +#include <asm/hwcap.h>
>> +
>> +/* pasted from include/linux/stringify.h */
>> +#define __stringify_1(x...)	#x
>> +#define __stringify(x...)	__stringify_1(x)
>> +
>> +/*
> 
> I think we can delete this entire comment.
> 
> The macro name is fairly self-explanatory anyway.  Although the
> rationale is interesting, our approach to reading system registers
> here is just the same as elsewhere in the kernel.

OK
> 
>> + * Reads a sysreg using the, possibly provided, S3_ encoding in order to
>> + * avoid inject any dependency on the used toolchain regarding possibly
>> + * still unsupported ARMv8 extensions.
>> + *
>> + * Using a standard mnemonic here to indicate the specific sysreg (like SSBS)
>> + * would introduce a compile-time dependency on possibly unsupported ARMv8
>> + * Extensions: you could end-up failing to build the test depending on the
>> + * available toolchain.
>> + * This is undesirable since some tests, even if specifically targeted at some
>> + * ARMv8 Extensions, can be plausibly run even on hardware lacking the above
>> + * optional ARM features. (SSBS bit preservation is an example: Kernel handles
>> + * it transparently not caring at all about the effective set of supported
>> + * features).
>> + * On the other side we will expect to observe different behaviours if the
>> + * feature is supported or not: usually getting a SIGILL when trying to use
>> + * unsupported features. For this reason we have anyway in place some
>> + * preliminary run-time checks about the cpu effectively supported features.
>> + *
>> + * This helper macro is meant to be used for regs readable at EL0, BUT some
>> + * EL1 sysregs are indeed readable too through MRS emulation Kernel-mechanism
>> + * if the required reg is included in the supported encoding space:
>> + *
>> + *  Documentation/arm64/cpu-feature-regsiters.txt
>> + *
>> + *  "The infrastructure emulates only the following system register space:
>> + *   	Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7
>> + */
>> +#define get_regval(regname, out) \
>> +	asm volatile("mrs %0, " __stringify(regname) : "=r" (out) :: "memory")
>> +
>> +/* Regs encoding and masks naming copied in from sysreg.h */
>> +#define SYS_ID_AA64MMFR1_EL1	S3_0_C0_C7_1	/* MRS Emulated */
>> +#define SYS_ID_AA64MMFR2_EL1	S3_0_C0_C7_2	/* MRS Emulated */
> 
> These ID regs are part of armv8.0-a, so we don't need to use the magic
> syntax.
> mmm... why I found them in non UAPI headers defined as follows ?

arch/arm64/include/asm/sysreg.h:#define SYS_ID_AA64MMFR1_EL1            sys_reg(3, 0, 0, 7, 1)

anyway I tried to use nonS3 regular sysreg naming (with a reasonably new compiler:

/opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-

and it fails (only on id_aa64mmfr2_el1) as follows:
/tmp/ccqAyE8P.s: Assembler messages:                      
/tmp/ccoGrnGc.s:1085: Error: selected processor does not support system register name 'id_aa64mmfr2_el1'

In fact this seems to remind me (not totally sure) that this was the reason to use such S3 syntax on this
sysregs too.

>> +#define ID_AA64MMFR1_PAN_SHIFT	20
>> +#define ID_AA64MMFR2_UAO_SHIFT	4
>> +
>> +/* Local Helpers */
> 
> Can these names indicate the sysreg they should be used with, e.g.
> 
> #define ID_AA64MMFR1_EL1_PAN_SUPPORTED(val) ...
> #define ID_AA64MMFR2_EL1_UAO_SUPPORTED(val) ...
> 
ok

>> +#define IS_PAN_SUPPORTED(val) \
>> +	(!!((val) & (0xfUL << ID_AA64MMFR1_PAN_SHIFT)))
>> +#define IS_UAO_SUPPORTED(val) \
>> +	(!!((val) & (0xfUL << ID_AA64MMFR2_UAO_SHIFT)))
>> +
>> +#define S3_MRS_SSBS_SYSREG		S3_3_C4_C2_6	/* EL0 supported */
> 
> Maybe just SSBS_SYSREG.
> 
> Sysreg encodings are always for use with MRS/MSR anyway, and "S3" is
> really part of the definition rather than part of the name.
> 
ok

>> +
>> +/*
>> + * Feature flags used in tdescr.feats_required to specify
>> + * any feature by the test
>> + */
>> +enum {
>> +	FSSBS_BIT,
>> +	FPAN_BIT,
>> +	FUAO_BIT,
>> +	FMAX_END
>> +};
>> +
>> +#define FEAT_SSBS		(1UL << FSSBS_BIT)
>> +#define FEAT_PAN		(1UL << FPAN_BIT)
>> +#define FEAT_UAO		(1UL << FUAO_BIT)
>> +
>> +/*
>> + * A descriptor used to describe and configure a test case.
>> + * Fields with a non-trivial meaning are described inline in the following.
>> + */
>> +struct tdescr {
>> +	/* KEEP THIS FIELD FIRST for easier lookup from assembly */
>> +	void		*token;
>> +	/* when disabled token based sanity checking is skipped in handler */
>> +	bool		sanity_disabled;
>> +	/* just a name for the test-case; manadatory field */
>> +	char		*name;
>> +	char		*descr;
>> +	unsigned long	feats_required;
>> +	/* bitmask of effectively supported feats: populated at run-time */
>> +	unsigned long	feats_supported;
>> +	bool		feats_ok;
> 
> Is feats_ok used?

Removed.

> 
>> +	bool		initialized;
>> +	unsigned int	minsigstksz;
>> +	/* signum used as a test trigger. Zero if no trigger-signal is used */
>> +	int		sig_trig;
>> +	/*
>> +	 * signum considered as a successful test completion.
>> +	 * Zero when no signal is expected on success
>> +	 */
>> +	int		sig_ok;
>> +	/* signum expected on unsupported CPU features. */
>> +	int		sig_unsupp;
>> +	/* a timeout in second for test completion */
>> +	unsigned int	timeout;
>> +	bool		triggered;
>> +	bool		pass;
>> +	/* optional sa_flags for the installed handler */
>> +	int		sa_flags;
>> +	ucontext_t	saved_uc;
>> +
>> +	/* a setup function to be called before test starts */
>> +	int (*setup)(struct tdescr *td);
>> +	void (*cleanup)(struct tdescr *td);
> 
> Add a comment to say what cleanup() is?
> 
ok
>> +
>> +	/* an optional function to be used as a trigger for test starting */
>> +	int (*trigger)(struct tdescr *td);
>> +	/*
>> +	 * the actual test-core: invoked differently depending on the
>> +	 * presence of the trigger function above; this is mandatory
>> +	 */
>> +	int (*run)(struct tdescr *td, siginfo_t *si, ucontext_t *uc);
>> +
>> +	/* an optional function for custom results' processing */
>> +	void (*check_result)(struct tdescr *td);
>> +
>> +	void *priv;
>> +};
>> +#endif
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
>> new file mode 100644
>> index 000000000000..ac0055f6340b
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
>> @@ -0,0 +1,261 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <signal.h>
>> +#include <string.h>
>> +#include <unistd.h>
>> +#include <assert.h>
>> +#include <sys/auxv.h>
>> +#include <linux/auxvec.h>
>> +#include <ucontext.h>
>> +
>> +#include "test_signals.h"
>> +#include "test_signals_utils.h"
>> +#include "testcases/testcases.h"
>> +
>> +extern struct tdescr *current;
>> +
>> +static char *feats_store[FMAX_END] = {
>> +	"SSBS",
>> +	"PAN",
>> +	"UAO"
>> +};
>> +
>> +#define MAX_FEATS_SZ	128
>> +static inline char *feats_to_string(unsigned long feats)
>> +{
>> +	static char feats_string[MAX_FEATS_SZ];
>> +
>> +	for (int i = 0; i < FMAX_END && feats_store[i][0]; i++) {
>> +		if (feats & 1UL << i)
>> +			snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
>> +				 feats_string, feats_store[i]);
>> +	}
>> +
>> +	return feats_string;
>> +}
>> +
>> +static void unblock_signal(int signum)
>> +{
>> +	sigset_t sset;
>> +
>> +	sigemptyset(&sset);
>> +	sigaddset(&sset, signum);
>> +	sigprocmask(SIG_UNBLOCK, &sset, NULL);
>> +}
>> +
>> +static void default_result(struct tdescr *td, bool force_exit)
>> +{
>> +	if (td->pass)
>> +		fprintf(stderr, "==>> completed. PASS(1)\n");
>> +	else
>> +		fprintf(stdout, "==>> completed. FAIL(0)\n");
>> +	if (force_exit)
>> +		exit(td->pass ? EXIT_SUCCESS : EXIT_FAILURE);
>> +}
>> +
>> +static inline bool are_feats_ok(struct tdescr *td)
>> +{
>> +	return td ? td->feats_required == td->feats_supported : 0;
> 
> Should this be something like
> (td->feats_required & td->feats_supported) == td->feats_required ?
> 
> Otherwise additional supported features that our test doesn't care about
> will cause this check to fail.
> 
Yes better.

> 
> Do we really need to check td?
> 

Overly defensive

> assert(foo); followed by dereferincing foo is usually a bit pointless
> because you'd get a SIGSEGV anyway.
>
> However, since the tests generate deliberate SIGSEGVs too this could
> be confusing -- in which case, having an explicit assert() here does
> no harm.
> 
not sure about which assert you refer here

>> +}
>> +
>> +static void default_handler(int signum, siginfo_t *si, void *uc)
>> +{
>> +	if (current->sig_trig && signum == current->sig_trig) {
>> +		fprintf(stderr, "Handling SIG_TRIG\n");
>> +		current->triggered = 1;
>> +		/* ->run was asserted NON-NULL in test_setup() already */
>> +		current->run(current, si, uc);
>> +	} else if (signum == SIGILL && !current->initialized) {
>> +		/*
>> +		 * A SIGILL here while still not initialized means we failed
>> +		 * even to asses the existence of features during init
>> +		 */
>> +		fprintf(stdout,
>> +			"Got SIGILL test_init. Marking ALL features UNSUPPORTED.\n");
>> +		current->feats_supported = 0;
>> +	} else if (current->sig_ok && signum == current->sig_ok) {
>> +		/* it's a bug in the test code when this assert fail */
> 
> Why?  Is this because sig_ok is considered acceptable only as an effect
> of the test -- i.e., we shouldn't see it if the test hasn't been
> triggered yet?

This assert would like to ensure that when you receive a sig_ok signal,
if a sig_trig was defined != 0, the trigger have been in fact used and processed before
receiving this sig_ok here: so you didn't define a signal trigger at all, or, if defined
it has been fired to arrive here. I'll add some commenting about this.

> 
>> +		assert(!current->sig_trig || current->triggered);
>> +		fprintf(stderr,
>> +			"SIG_OK -- SP:%p  si_addr@:0x%p  si_code:%d  token@:0x%p  offset:%ld\n",
>> +			((ucontext_t *)uc)->uc_mcontext.sp,
>> +			si->si_addr, si->si_code, current->token,
>> +			current->token - si->si_addr);
>> +		/*
>> +		 * fake_sigreturn tests, which have sanity_enabled=1, set, at
>> +		 * the very last time, the token field to the SP address used
>> +		 * to place the fake sigframe: so token==0 means we never made
>> +		 * it to the end, segfaulting well-before, and the test is
>> +		 * possibly broken.
>> +		 */
>> +		if (!current->sanity_disabled && !current->token) {
>> +			fprintf(stdout,
>> +				"current->token ZEROED...test is probably broken!\n");
>> +			assert(0);
> 
> In case someone builds with -DNDEBUG, should we add abort()?
> 
Well, in such a case all the test suite is mostly compromised anyway.
But you are right, I'll add an abort() at least here when broken tests are detected.

>> +		}
>> +		/*
>> +		 * Trying to narrow down the SEGV to the ones generated by
>> +		 * Kernel itself via arm64_notify_segfault()
>> +		 */
>> +		if (current->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
>> +			fprintf(stdout,
>> +				"si_code != SEGV_ACCERR...test is probably broken!\n");
>> +			assert(0);
>> +		}
> 
> I'm not sure whether si_code is really ABI here, though I'm not sure
> what else we can do to diagnose the signal more accurately.
> 
> Maybe add a comment to say that this might need to change if this
> aspect of the kernel ABI evolves.
Ok
> 
>> +		fprintf(stderr, "Handling SIG_OK\n");
>> +		current->pass = 1;
>> +		/*
>> +		 * Some tests can lead to SEGV loops: in such a case we want
>> +		 * to terminate immediately exiting straight away
>> +		 */
>> +		default_result(current, 1);
>> +	} else {
>> +		if (signum == current->sig_unsupp && !are_feats_ok(current)) {
>> +			fprintf(stderr, "-- RX SIG_UNSUPP on unsupported feature...OK\n");
>> +			current->pass = 1;
>> +		} else if (signum == SIGALRM && current->timeout) {
>> +			fprintf(stderr, "-- Timeout !\n");
>> +		} else {
>> +			fprintf(stderr,
>> +				"-- RX UNEXPECTED SIGNAL: %d\n", signum);
>> +		}
>> +		default_result(current, 1);
>> +	}
>> +}
>> +
>> +static int default_setup(struct tdescr *td)
>> +{
>> +	struct sigaction sa;
>> +
>> +	sa.sa_sigaction = default_handler;
>> +	sa.sa_flags = SA_SIGINFO;
> 
> Add SA_RESTART?
> 
> I'm not sure whether this affects these tests, but the libc stdio
> functions don't like being interrupted by signals.  SA_RESTART should
> hide most issues of this sort.
> 

Ok...I was not aware of these possible issues.

>> +	if (td->sa_flags)
>> +		sa.sa_flags |= td->sa_flags;
> 
> Do we need the if() here?  If td->sa_flags == 0, the assignment is
> harmless anyway.
True.

> 
>> +	sigemptyset(&sa.sa_mask);
>> +	/* uncatchable signals naturally skipped ... */
>> +	for (int sig = 1; sig < 32; sig++)
>> +		sigaction(sig, &sa, NULL);
>> +	/*
>> +	 * RT Signals default disposition is Term but they cannot be
>> +	 * generated by the Kernel in response to our tests; so just catch
>> +	 * them all and report them as UNEXPECTED signals.
>> +	 */
>> +	for (int sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
>> +		sigaction(sig, &sa, NULL);
>> +
>> +	/* just in case...unblock explicitly all we need */
>> +	if (td->sig_trig)
>> +		unblock_signal(td->sig_trig);
>> +	if (td->sig_ok)
>> +		unblock_signal(td->sig_ok);
>> +	if (td->sig_unsupp)
>> +		unblock_signal(td->sig_unsupp);
>> +
>> +	if (td->timeout) {
>> +		unblock_signal(SIGALRM);
>> +		alarm(td->timeout);
>> +	}
>> +	fprintf(stderr, "Registered handlers for all signals.\n");
>> +
>> +	return 1;
>> +}
>> +
>> +static inline int default_trigger(struct tdescr *td)
>> +{
>> +	return !raise(td->sig_trig);
>> +}
>> +
>> +static int test_init(struct tdescr *td)
>> +{
>> +	td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
>> +	if (!td->minsigstksz)
>> +		td->minsigstksz = MINSIGSTKSZ;
>> +	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
>> +
>> +	if (td->feats_required) {
>> +		bool feats_ok = false;
>> +		td->feats_supported = 0;
>> +		/*
>> +		 * Checking for CPU required features using both the
>> +		 * auxval and the arm64 MRS Emulation to read sysregs.
>> +		 */
>> +		if (getauxval(AT_HWCAP) & HWCAP_CPUID) {
>> +			uint64_t val = 0;
>> +
> 
> Would it be simpler just to query all these features unconditionally?
> 
> We just need to check that all the features the test needs are present.
> If other features are present, we can happily ignore them, but
> discovering them is harmless.
> 
Ok
>> +			if (td->feats_required & FEAT_SSBS) {
>> +				/* Uses HWCAP to check capability */
>> +				if (getauxval(AT_HWCAP) & HWCAP_SSBS)
>> +					td->feats_supported |= FEAT_SSBS;
>> +			}
>> +			if (td->feats_required & FEAT_PAN) {
>> +				/* Uses MRS emulation to check capability */
>> +				get_regval(SYS_ID_AA64MMFR1_EL1, val);
>> +				if (IS_PAN_SUPPORTED(val))
>> +					td->feats_supported |= FEAT_PAN;
>> +			}
>> +			if (td->feats_required & FEAT_UAO) {
>> +				/* Uses MRS emulation to check capability */
>> +				get_regval(SYS_ID_AA64MMFR2_EL1 , val);
>> +				if (IS_UAO_SUPPORTED(val))
>> +					td->feats_supported |= FEAT_UAO;
>> +			}
>> +		} else {
>> +			fprintf(stderr,
>> +				"HWCAP_CPUID NOT available. Mark ALL feats UNSUPPORTED.\n");
>> +		}
>> +		feats_ok = are_feats_ok(td);
>> +		fprintf(stderr,
>> +			"Required Features: [%s] %ssupported\n",
>> +			feats_ok ? feats_to_string(td->feats_supported) :
>> +		        feats_to_string(td->feats_required ^ td->feats_supported),
>> +			!feats_ok ? "NOT " : "");
>> +	}
>> +
>> +	td->initialized = 1;
>> +	return 1;
>> +}
>> +
>> +int test_setup(struct tdescr *td)
>> +{
>> +	/* assert core invariants symptom of a rotten testcase */
>> +	assert(current);
>> +	assert(td);
>> +	assert(td->name);
>> +	assert(td->run);
>> +
>> +	if (!test_init(td))
>> +		return 0;
>> +
>> +	if (td->setup)
>> +		return td->setup(td);
>> +	else
>> +		return default_setup(td);
>> +}
>> +
>> +int test_run(struct tdescr *td)
>> +{
>> +	if (td->sig_trig) {
>> +		if (td->trigger)
>> +			return td->trigger(td);
>> +		else
>> +			return default_trigger(td);
>> +	} else {
>> +		return td->run(td, NULL, NULL);
>> +	}
>> +}
>> +
>> +void test_result(struct tdescr *td)
>> +{
>> +	if (td->check_result)
>> +		td->check_result(td);
>> +	default_result(td, 0);
>> +}
>> +
>> +void test_cleanup(struct tdescr *td)
>> +{
>> +	if (td->cleanup)
>> +		td->cleanup(td);
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> new file mode 100644
>> index 000000000000..8658d1a7d4b9
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> @@ -0,0 +1,13 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#ifndef __TEST_SIGNALS_UTILS_H__
>> +#define __TEST_SIGNALS_UTILS_H__
>> +
>> +#include "test_signals.h"
>> +
>> +int test_setup(struct tdescr *td);
>> +void test_cleanup(struct tdescr *td);
>> +int test_run(struct tdescr *td);
>> +void test_result(struct tdescr *td);
>> +#endif
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/.gitignore b/tools/testing/selftests/arm64/signal/testcases/.gitignore
>> new file mode 100644
>> index 000000000000..8651272e3cfc
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/.gitignore
>> @@ -0,0 +1 @@
>> +mangle_pstate_invalid_compat_toggle
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>> new file mode 100644
>> index 000000000000..971193e7501b
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>> @@ -0,0 +1,25 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
> 
> Each testcase should have a comment explaining what it is trying to
> test, and how.
> 
Ok

>> +#include "test_signals_utils.h"
>> +#include "testcases.h"
>> +
>> +static int mangle_invalid_pstate_run(struct tdescr *td, siginfo_t *si,
>> +				     ucontext_t *uc)
>> +{
>> +	ASSERT_GOOD_CONTEXT(uc);
>> +
>> +	/* This config should trigger a SIGSEGV by Kernel */
>> +	uc->uc_mcontext.pstate ^= PSR_MODE32_BIT;
>> +
>> +	return 1;
>> +}
>> +
>> +struct tdescr tde = {
>> +		.sanity_disabled = true,
>> +		.name = "MANGLE_PSTATE_INVALID_STATE_TOGGLE",
>> +		.descr = "Mangling uc_mcontext with INVALID STATE_TOGGLE",
>> +		.sig_trig = SIGUSR1,
>> +		.sig_ok = SIGSEGV,
>> +		.run = mangle_invalid_pstate_run,
>> +};
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
>> new file mode 100644
>> index 000000000000..a59785092e1f
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
>> @@ -0,0 +1,150 @@
>> +#include "testcases.h"
>> +
>> +struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
>> +				size_t resv_sz, size_t *offset)
>> +{
>> +	size_t offs = 0;
>> +	struct _aarch64_ctx *found = NULL;
>> +
>> +	if (!head || resv_sz < HDR_SZ)
>> +		return found;
>> +
>> +	do {
>> +		if (head->magic == magic) {
>> +			found = head;
>> +			break;
>> +		}
>> +		offs += head->size;
>> +		head = GET_RESV_NEXT_HEAD(head);
> 
> Are offs and head tracking the same thing here?
> 
> Maybe it would be cleaner to have GET_RESV_NEXT_HEAD() do the bounds
> checking itself.
> 
offs is used for bound checking but it is also optionally provided to the
caller as the offset in bytes at which the header was found, and yes it tracks the
underlying same thing at the end.
I'll try to cleanup and re-org this function a bit.

>> +	} while (offs < resv_sz - HDR_SZ);
>> +
>> +	if (offset)
>> +		*offset = offs;
>> +
>> +	return found;
>> +}
>> +
>> +bool validate_extra_context(struct extra_context *extra, char **err)
>> +{
>> +	struct _aarch64_ctx *term;
>> +
>> +	if (!extra || !err)
>> +		return false;
>> +
>> +	fprintf(stderr, "Validating EXTRA...\n");
>> +	term = GET_RESV_NEXT_HEAD(extra);
>> +	if (!term || term->magic || term->size) {
>> +		*err = "UN-Terminated EXTRA context";
> 
> This sounds like the extra context doesn't contain a terminator, which
> isn't what we're checking here.  Maybe say "terminator missing after
> extra context", or similar.

ok
> 
>> +		return false;
>> +	}
>> +	if (extra->datap & 0x0fUL)
>> +		*err = "Extra DATAP misaligned";
>> +	else if (extra->size & 0x0fUL)
>> +		*err = "Extra SIZE misaligned";
>> +	else if (extra->datap != (uint64_t)term + sizeof(*term))
>> +		*err = "Extra DATAP misplaced (not contiguos)";
>> +	if (*err)
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>> +bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
>> +{
>> +	bool terminated = false;
>> +	size_t offs = 0;
>> +	int flags = 0;
>> +	struct extra_context *extra = NULL;
>> +	struct _aarch64_ctx *head =
>> +		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
>> +
>> +	if (!err)
>> +		return false;
>> +	/* Walk till the end terminator verifying __reserved contents */
>> +	while (head && !terminated && offs < resv_sz) {
>> +		if ((uint64_t)head & 0x0fUL) {
>> +			*err = "Misaligned HEAD";
>> +			return false;
>> +		}
>> +
>> +		switch (head->magic) {
>> +			case 0:
>> +				if (head->size)
>> +					*err = "Bad size for MAGIC0";
> 
> Or "terminator".  We don't have an actual symbolic name for magic number
> 0.  (Arguably it would have been nice to have a name, but we managed
> without.)

ok
> 
>> +				else
>> +					terminated = true;
>> +				break;
>> +			case FPSIMD_MAGIC:
>> +				if (flags & FPSIMD_CTX)
>> +					*err = "Multiple FPSIMD_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct fpsimd_context))
>> +					*err = "Bad size for fpsimd_context";
>> +				flags |= FPSIMD_CTX;
>> +				break;
>> +			case ESR_MAGIC:
>> +				if (head->size != sizeof(struct esr_context))
>> +					fprintf(stderr,
>> +						"Bad size for esr_context is not an error...just ignore.\n");
> 
> Why isn't this an error?  Should the kernel ever write an esr_context
> with a different size?

There is no check on Kernel side:

    case ESR_MAGIC:
    	/* ignore */
        break;

so I sticked with that, since this function can be used to validate a Kernel originated sigframe
or a crafted one which will be passed down to the Kernel.

> 
>> +				break;
>> +			case SVE_MAGIC:
>> +				if (flags & SVE_CTX)
>> +					*err = "Multiple SVE_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct sve_context))
>> +					*err = "Bad size for sve_context";
>> +				flags |= SVE_CTX;
>> +				break;
>> +			case EXTRA_MAGIC:
>> +				if (flags & EXTRA_CTX)
>> +					*err = "Multiple EXTRA_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct extra_context))
>> +					*err = "Bad size for extra_context";
>> +				flags |= EXTRA_CTX;
>> +				extra = (struct extra_context *)head;
>> +				break;
>> +			case KSFT_BAD_MAGIC:
>> +				/*
>> +				 * This is a BAD magic header defined
>> +				 * artificially by a testcase and surely
>> +				 * unknown to the Kernel parse_user_sigframe().
>> +				 * It MUST cause a Kernel induced SEGV
>> +				 */
>> +				*err = "BAD MAGIC !";
>> +				break;
>> +			default:
>> +				/*
>> +				 * A still unknown Magic: potentially freshly added
>> +				 * to the Kernel code and still unknown to the
>> +				 * tests.
>> +				 */
>> +				fprintf(stdout,
>> +					"SKIP Unknown MAGIC: 0x%X - Is KSFT arm64/signal up to date ?\n",
>> +					head->magic);
>> +				break;
>> +		}
>> +
>> +		if (*err)
>> +			return false;
>> +
>> +		offs += head->size;
> 
> Can this addition cause offs to become > resv_sz?  If so, the next
> comparison will go wrong.

True. I'll refactor the comparison to avoid subtraction like in :

	if (resv_sz < offs + sizeof(*head)) {

> 
>> +		if (resv_sz - offs < sizeof(*head)) {
>> +			*err = "HEAD Overrun";
>> +			return false;
>> +		}
>> +
>> +		if (flags & EXTRA_CTX)
>> +			if (!validate_extra_context(extra, err))
>> +				return false;
> 
> Can we validate the contents of the extra context too?
> 
> Ideally we can use the same code to check __reserved[] and the extra
> context.
> 
Do you mean the content pointed by extra->datap ?
This extra_context validation routine is generally under review and fixes in a further
arm64/signal SVE extensions patch still to be published (and cleaned up):
[kselftest: arm64: adds SVE-related signal test], given that EXTRA_CONTEXT can effectively
appear only when SVE related instruction are used properly.

Should I introduce this and other extra-context related fixes here instead ?
(it is hard to test and debug without any triggering SVE instruction though...)

>> +
>> +		head = GET_RESV_NEXT_HEAD(head);
>> +	}
>> +
>> +	if (terminated && !(flags & FPSIMD_CTX)) {
>> +		*err = "Missing FPSIMD";
>> +		return false;
>> +	}
>> +
>> +	return true;
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
>> new file mode 100644
>> index 000000000000..624717c71b1d
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
>> @@ -0,0 +1,83 @@
>> +#ifndef __TESTCASES_H__
>> +#define __TESTCASES_H__
>> +
> 
> Pedantically, we should have <stddef.h> for NULL.
> 

ok

>> +#include <stdio.h>
>> +#include <stdbool.h>
>> +#include <stdint.h>
>> +#include <unistd.h>
> 
> Is <unistd.h> used now that SAFE_WRITE() is gone?
> 

Removed.

>> +#include <ucontext.h>
>> +#include <assert.h>
>> +
>> +/* Architecture specific sigframe definitions */
>> +#include <asm/sigcontext.h>
> 
> [...]
> 
> Cheers
> ---Dave
> 

Cheers

Cristian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v9 2/3] fdt: add support for rng-seed
From: Kees Cook @ 2019-08-24 19:04 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Josh Poimboeuf, Grzegorz Halat, H . Peter Anvin, Guenter Roeck,
	Will Deacon, Marek Szyprowski, Rob Herring, Daniel Thompson,
	Anders Roxell, Yury Norov, Marc Zyngier, Russell King,
	Aaro Koskinen, Ingo Molnar, Viresh Kumar, Waiman Long,
	Paul E . McKenney, Wei Li, Alexey Dobriyan, Julien Thierry,
	Len Brown, Arnd Bergmann, Rik van Riel, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Hsin-Yi Wang, Thomas Gleixner,
	linux-arm-kernel, Theodore Y . Ts'o, Greg Kroah-Hartman,
	Marcelo Tosatti, linux-kernel, Armijn Hemel, Jiri Kosina,
	Mathieu Desnoyers, Andrew Morton, Tim Chen, David S . Miller
In-Reply-To: <5d5ed368.1c69fb81.419fc.0803@mx.google.com>

On Thu, Aug 22, 2019 at 10:39:51AM -0700, Stephen Boyd wrote:
> Quoting Hsin-Yi Wang (2019-08-22 00:15:22)
> > Introducing a chosen node, rng-seed, which is an entropy that can be
> > passed to kernel called very early to increase initial device
> > randomness. Bootloader should provide this entropy and the value is
> > read from /chosen/rng-seed in DT.
> > 
> > Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
> > since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.
> > 
> > Add a new interface add_bootloader_randomness() for rng-seed use case.
> > Depends on whether the seed is trustworthy, rng seed would be passed to
> > add_hwgenerator_randomness(). Otherwise it would be passed to
> > add_device_randomness(). Decision is controlled by kernel config
> > RANDOM_TRUST_BOOTLOADER.
> > 
> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > ---
> > Change from v8:
> > * Add a new interface add_bootloader_randomness
> > * Add a new kernel config
> > ---
> >  drivers/char/Kconfig   | 10 ++++++++++
> >  drivers/char/random.c  | 15 +++++++++++++++
> >  drivers/of/fdt.c       | 14 ++++++++++++--
> >  include/linux/random.h |  1 +
> >  4 files changed, 38 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> > index 96156c729a31..5974a5906fd0 100644
> > --- a/drivers/char/Kconfig
> > +++ b/drivers/char/Kconfig
> > @@ -551,3 +551,13 @@ config RANDOM_TRUST_CPU
> >         has not installed a hidden back door to compromise the CPU's
> >         random number generation facilities. This can also be configured
> >         at boot with "random.trust_cpu=on/off".
> > +
> > +config RANDOM_TRUST_BOOTLOADER
> > +       bool "Trust the bootloader to initialize Linux's CRNG"
> > +       default n
> 
> You can drop the default.
> 
> > +       help
> > +       Bootloader could provide rng-seed set in /chosen/rng-seed in DT to help
> > +       increase initial device randomness. Assume the entropy provided is
> > +       trustworthy, it would be regarded as true hardware RNGs and update the
> > +       entropy estimate. Otherwise it would be regarded as device input that
> > +       could help mix the entropy pool, but won't be added to actual entropy.
> 
> Maybe reword this to something like:
> 
> 	Some bootloaders can provide entropy to increase the kernel's
> 	initial device randomness. Say Y here to assume the entropy
> 	provided by the booloader is trustworthy so it will be added to
> 	the kernel's entropy pool. Otherwise, say N here so it will be
> 	regarded as device input that only mixes the entropy pool.
> 
> > \ No newline at end of file
> > diff --git a/drivers/char/random.c b/drivers/char/random.c
> > index 5d5ea4ce1442..29d3ff3de1e1 100644
> > --- a/drivers/char/random.c
> > +++ b/drivers/char/random.c
> > @@ -2445,3 +2445,18 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
> >         credit_entropy_bits(poolp, entropy);
> >  }
> >  EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
> > +
> > +/* Handle random seed passed by bootloader.
> > + * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
> > + * it would be regarded as device data.
> > + * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
> > + */
> > +void add_bootloader_randomness(const void *buf, unsigned int size)
> > +{
> > +#ifdef CONFIG_RANDOM_TRUST_BOOTLOADER

Can this please be a boot param (with the default controlled by the
CONFIG)? See how CONFIG_RANDOM_TRUST_CPU is wired up...

-Kees

> > +       add_hwgenerator_randomness(buf, size, size * 8);
> > +#else
> > +       add_device_randomness(buf, size);
> > +#endif
> 
> Maybe use
> 
> 	if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
> 		add_hwgenerator_randomness(buf, size, size * 8);
> 	else
> 		add_device_randomness(buf, size);
> 	
> > +}
> > +EXPORT_SYMBOL_GPL(add_bootloader_randomness);
> > \ No newline at end of file

-- 
Kees Cook

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] arm-smmu: check for generic bindings first
From: Stefano Stabellini @ 2019-08-28 17:38 UTC (permalink / raw)
  To: will
  Cc: sstabellini, linux-kernel, michal.simek, git, Stefano Stabellini,
	robin.murphy, linux-arm-kernel

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

Today, the arm-smmu driver checks for mmu-masters on device tree, the
legacy property, if it is absent it assumes that we are using the new
bindings. If it is present it assumes that we are using the legacy
bindings. All arm-smmus need to use the same bindings: legacy or new.

There are two issues with this:

- we are not actually checking for the new bindings explicitly
It would be better to have an explicit check for the new bindings rather
than assuming we must be using the new if the old are not there.

- old and new bindings cannot coexist
It would be nice to be able to provide both old and new bindings so
that software that hasn't been updated yet is still able to get IOMMU
information from the legacy bindings while at the same time newer
software can get the latest information via the new bindings. (Xen has
not been updated to use the new binding yet for instance.) The current
code breaks under these circumstances because if the old bindings are
present, the new are not even checked.

This patch changes the scheme by checking for #iommu-cells, which is
only present with the new bindings, before checking for mmu-masters.
The new bindings are always favored when present. All SMMUs still need
to use the same bindings: mix-and-matching new and old bindings between
different SMMUs is not allowed.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---

Let me know if you'd like me to turn the two using_*_binding variables
into a single one.

Also, please note that this is not meant as an excuse not to get Xen
updated to use the new binding.

 drivers/iommu/arm-smmu.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 64977c131ee6..79b518ff215c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2118,7 +2118,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 {
 	const struct arm_smmu_match_data *data;
 	struct device *dev = &pdev->dev;
-	bool legacy_binding;
+	bool legacy_binding, generic_binding;
 
 	if (of_property_read_u32(dev->of_node, "#global-interrupts",
 				 &smmu->num_global_irqs)) {
@@ -2132,16 +2132,20 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 
 	parse_driver_options(smmu);
 
-	legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL);
-	if (legacy_binding && !using_generic_binding) {
-		if (!using_legacy_binding)
-			pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
-		using_legacy_binding = true;
-	} else if (!legacy_binding && !using_legacy_binding) {
+	generic_binding = of_find_property(dev->of_node, "#iommu-cells", NULL);
+	if (generic_binding && !using_legacy_binding) {
 		using_generic_binding = true;
 	} else {
-		dev_err(dev, "not probing due to mismatched DT properties\n");
-		return -ENODEV;
+		legacy_binding = of_find_property(dev->of_node, "mmu-masters",
+						  NULL);
+		if (legacy_binding && !using_generic_binding) {
+			if (!using_legacy_binding)
+				pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
+			using_legacy_binding = true;
+		} else {
+			dev_err(dev, "not probing due to mismatched DT properties\n");
+			return -ENODEV;
+		}
 	}
 
 	if (of_dma_is_coherent(dev->of_node))
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [GIT PULL] arm64: Fixes for -rc7
From: pr-tracker-bot @ 2019-08-28 17:45 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvm, rkrcmar, marc.zyngier, catalin.marinas, linux-kernel,
	pbonzini, torvalds, kvmarm, linux-arm-kernel
In-Reply-To: <20190828173233.zqwm5nd4p5xa4jxi@willie-the-truck>

The pull request you sent on Wed, 28 Aug 2019 18:32:33 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9cf6b756cdf2cd38b8b0dac2567f7c6daf5e79d5

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 0/5] arm64: avoid out-of-line ll/sc atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel

When building for LSE atomics (CONFIG_ARM64_LSE_ATOMICS), if the hardware
or toolchain doesn't support it the existing code will fallback to ll/sc
atomics. It achieves this by branching from inline assembly to a function
that is built with specical compile flags. Further this results in the
clobbering of registers even when the fallback isn't used increasing
register pressure.

Let's improve this by providing inline implementatins of both LSE and
ll/sc and use a static key to select between them. This allows for the
compiler to generate better atomics code.

Whilst it may be difficult to understand the performance impact, we gain
improved code readability, ability to use Clang, and improved backtrace
reliability.

Build and boot tested, along with atomic_64_test.

Following is the assembly of a function that has three consecutive
atomic_add calls when built with LSE and this patchset:

Dump of assembler code for function atomics_test:
   0xffff000010084338 <+0>:     b       0xffff000010084388 <atomics_test+80>
   0xffff00001008433c <+4>:     b       0xffff000010084388 <atomics_test+80>
   0xffff000010084340 <+8>:     adrp    x0, 0xffff0000118d5000 <reset_devices>
   0xffff000010084344 <+12>:    add     x2, x0, #0x0
   0xffff000010084348 <+16>:    mov     w1, #0x1                        // #1
   0xffff00001008434c <+20>:    add     x3, x2, #0x28
   0xffff000010084350 <+24>:    stadd   w1, [x3]
   0xffff000010084354 <+28>:    b       0xffff00001008439c <atomics_test+100>
   0xffff000010084358 <+32>:    b       0xffff00001008439c <atomics_test+100>
   0xffff00001008435c <+36>:    add     x1, x0, #0x0
   0xffff000010084360 <+40>:    mov     w2, #0x1                        // #1
   0xffff000010084364 <+44>:    add     x3, x1, #0x28
   0xffff000010084368 <+48>:    stadd   w2, [x3]
   0xffff00001008436c <+52>:    b       0xffff0000100843ac <atomics_test+116>
   0xffff000010084370 <+56>:    b       0xffff0000100843ac <atomics_test+116>
   0xffff000010084374 <+60>:    add     x0, x0, #0x0
   0xffff000010084378 <+64>:    mov     w1, #0x1                        // #1
   0xffff00001008437c <+68>:    add     x2, x0, #0x28
   0xffff000010084380 <+72>:    stadd   w1, [x2]
   0xffff000010084384 <+76>:    ret
   0xffff000010084388 <+80>:    adrp    x0, 0xffff0000118d5000 <reset_devices>
   0xffff00001008438c <+84>:    add     x1, x0, #0x0
   0xffff000010084390 <+88>:    add     x1, x1, #0x28
   0xffff000010084394 <+92>:    b       0xffff000010084570
   0xffff000010084398 <+96>:    b       0xffff000010084354 <atomics_test+28>
   0xffff00001008439c <+100>:   add     x1, x0, #0x0
   0xffff0000100843a0 <+104>:   add     x1, x1, #0x28
   0xffff0000100843a4 <+108>:   b       0xffff000010084588
   0xffff0000100843a8 <+112>:   b       0xffff00001008436c <atomics_test+52>
   0xffff0000100843ac <+116>:   add     x0, x0, #0x0
   0xffff0000100843b0 <+120>:   add     x0, x0, #0x28
   0xffff0000100843b4 <+124>:   b       0xffff0000100845a0
   0xffff0000100843b8 <+128>:   ret
End of assembler dump.

ffff000010084570:       f9800031        prfm    pstl1strm, [x1]
ffff000010084574:       885f7c22        ldxr    w2, [x1]
ffff000010084578:       11000442        add     w2, w2, #0x1
ffff00001008457c:       88037c22        stxr    w3, w2, [x1]
ffff000010084580:       35ffffa3        cbnz    w3, ffff000010084574 <do_one_initcall+0x1b4>
ffff000010084584:       17ffff85        b       ffff000010084398 <atomics_test+0x60>
ffff000010084588:       f9800031        prfm    pstl1strm, [x1]
ffff00001008458c:       885f7c22        ldxr    w2, [x1]
ffff000010084590:       11000442        add     w2, w2, #0x1
ffff000010084594:       88037c22        stxr    w3, w2, [x1]
ffff000010084598:       35ffffa3        cbnz    w3, ffff00001008458c <do_one_initcall+0x1cc>
ffff00001008459c:       17ffff83        b       ffff0000100843a8 <atomics_test+0x70>
ffff0000100845a0:       f9800011        prfm    pstl1strm, [x0]
ffff0000100845a4:       885f7c01        ldxr    w1, [x0]
ffff0000100845a8:       11000421        add     w1, w1, #0x1
ffff0000100845ac:       88027c01        stxr    w2, w1, [x0]
ffff0000100845b0:       35ffffa2        cbnz    w2, ffff0000100845a4 <do_one_initcall+0x1e4>
ffff0000100845b4:       17ffff81        b       ffff0000100843b8 <atomics_test+0x80>

The two branches before each section of atomics relates to the two static
keys which both become nop's when LSE is available. When LSE isn't
available the branches are used to run the slowpath fallback LL/SC atomics.

In v1 of this series, due to the use of likely/unlikely for the LSE code,
the fallback code ended up in one place at the end of the function. In this
v2 patchset we move the fallback code into its own subsection, this moves
any atomics code to the end of each compilation unit. It is felt that this
may improve icache performance for both LSE and LL/SC.

Where CONFIG_ARM64_LSE_ATOMICS isn't enabled then the same function is as
follows:

Dump of assembler code for function atomics_test:
   0xffff000010084338 <+0>:     adrp    x0, 0xffff000011865000 <reset_devices>
   0xffff00001008433c <+4>:     add     x0, x0, #0x0
   0xffff000010084340 <+8>:     add     x3, x0, #0x28
   0xffff000010084344 <+12>:    prfm    pstl1strm, [x3]
   0xffff000010084348 <+16>:    ldxr    w1, [x3]
   0xffff00001008434c <+20>:    add     w1, w1, #0x1
   0xffff000010084350 <+24>:    stxr    w2, w1, [x3]
   0xffff000010084354 <+28>:    cbnz    w2, 0xffff000010084348 <atomics_test+16>
   0xffff000010084358 <+32>:    prfm    pstl1strm, [x3]
   0xffff00001008435c <+36>:    ldxr    w1, [x3]
   0xffff000010084360 <+40>:    add     w1, w1, #0x1
   0xffff000010084364 <+44>:    stxr    w2, w1, [x3]
   0xffff000010084368 <+48>:    cbnz    w2, 0xffff00001008435c <atomics_test+36>
   0xffff00001008436c <+52>:    prfm    pstl1strm, [x3]
   0xffff000010084370 <+56>:    ldxr    w1, [x3]
   0xffff000010084374 <+60>:    add     w1, w1, #0x1
   0xffff000010084378 <+64>:    stxr    w2, w1, [x3]
   0xffff00001008437c <+68>:    cbnz    w2, 0xffff000010084370 <atomics_test+56>
   0xffff000010084380 <+72>:    ret
End of assembler dump.

These changes add some bloat on defconfig according to bloat-o-meter:

For LSE build (text):
  add/remove: 4/109 grow/shrink: 3398/67 up/down: 151556/-4940
  Total: Before=12759457, After=12906073, chg +1.15%

For LL/LSC only build (text):
  add/remove: 2/2 grow/shrink: 1423/57 up/down: 12224/-564 (11660)
  Total: Before=12836417, After=12848077, chg +0.09%

The bloat for LSE is due to the provision of LL/SC fallback atomics no longer
being !inline.

The bloat for LL/SC seems to be due to patch 2, which changes some assembly
constraints (i.e. moving an intermediate to a register).

When comparing the number of data transfer instructions (those starting or
ending with ld or st) in vmlinux we see a reduction from 30.8% to 30.6% when
applying this series. And no change when CONFIG_ARM64_LSE_ATOMICS isn't
enabled (30.9%). This was a feable attempt to measure register spilling.

Changes since v3:

 - Remove stale sentence from commit message of 'jump_label: Don't warn on...'

 - Reorder include statements in atomic_arch.h (asm last)

 - Reword commit message of 'arm64: Use correct ll/sc atomic constraints...' as
   suggested by Mark Rutland

 - Drop buggy 'K' contraints for LL/SC atomic_[and, or, xor] functions

 - Use correct 'L' constrints for LL/SC atomic64_[and, or, xor] functions

 - Rebased onto v5.3-rc3

Changes since v2:

 - Ensure _{relaxed,acquire,release} qualifers are used

 - Rebased onto arm64/for-next/fixes (v5.3-rc3)

Changes since v1:

 - Move LL/SC atomics to a subsection when being used as a fallback

 - Rebased onto arm64/for-next/fixes


Andrew Murray (5):
  jump_label: Don't warn on __exit jump entries
  arm64: Use correct ll/sc atomic constraints
  arm64: atomics: avoid out-of-line ll/sc atomics
  arm64: avoid using hard-coded registers for LSE atomics
  arm64: atomics: remove atomic_ll_sc compilation unit

 arch/arm64/include/asm/atomic.h       |  11 +-
 arch/arm64/include/asm/atomic_arch.h  | 155 ++++++++++
 arch/arm64/include/asm/atomic_ll_sc.h | 200 ++++++-------
 arch/arm64/include/asm/atomic_lse.h   | 395 +++++++++-----------------
 arch/arm64/include/asm/cmpxchg.h      |   2 +-
 arch/arm64/include/asm/lse.h          |  11 -
 arch/arm64/lib/Makefile               |  19 --
 arch/arm64/lib/atomic_ll_sc.c         |   3 -
 kernel/jump_label.c                   |   4 +-
 9 files changed, 399 insertions(+), 401 deletions(-)
 create mode 100644 arch/arm64/include/asm/atomic_arch.h
 delete mode 100644 arch/arm64/lib/atomic_ll_sc.c

-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 1/5] jump_label: Don't warn on __exit jump entries
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

On architectures that discard .exit.* sections at runtime, a
warning is printed for each jump label that is used within an
in-kernel __exit annotated function:

can't patch jump_label at ehci_hcd_cleanup+0x8/0x3c
WARNING: CPU: 0 PID: 1 at kernel/jump_label.c:410 __jump_label_update+0x12c/0x138

As these functions will never get executed (they are free'd along
with the rest of initmem) - we do not need to patch them and should
not display any warnings.

The warning is displayed because the test required to satisfy
jump_entry_is_init is based on init_section_contains (__init_begin to
__init_end) whereas the test in __jump_label_update is based on
init_kernel_text (_sinittext to _einittext) via kernel_text_address).

Fixes: 19483677684b ("jump_label: Annotate entries that operate on __init code earlier")
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
 kernel/jump_label.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index df3008419a1d..cdb3ffab128b 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -407,7 +407,9 @@ static bool jump_label_can_update(struct jump_entry *entry, bool init)
 		return false;
 
 	if (!kernel_text_address(jump_entry_code(entry))) {
-		WARN_ONCE(1, "can't patch jump_label at %pS", (void *)jump_entry_code(entry));
+		WARN_ONCE(!jump_entry_is_init(entry),
+			  "can't patch jump_label at %pS",
+			  (void *)jump_entry_code(entry));
 		return false;
 	}
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 2/5] arm64: Use correct ll/sc atomic constraints
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

The A64 ISA accepts distinct (but overlapping) ranges of immediates for:

 * add arithmetic instructions ('I' machine constraint)
 * sub arithmetic instructions ('J' machine constraint)
 * 32-bit logical instructions ('K' machine constraint)
 * 64-bit logical instructions ('L' machine constraint)

... but we currently use the 'I' constraint for many atomic operations
using sub or logical instructions, which is not always valid.

When CONFIG_ARM64_LSE_ATOMICS is not set, this allows invalid immediates
to be passed to instructions, potentially resulting in a build failure.
When CONFIG_ARM64_LSE_ATOMICS is selected the out-of-line ll/sc atomics
always use a register as they have no visibility of the value passed by
the caller.

This patch adds a constraint parameter to the ATOMIC_xx and
__CMPXCHG_CASE macros so that we can pass appropriate constraints for
each case, with uses updated accordingly.

Unfortunately prior to GCC 8.1.0 the 'K' constraint erroneously accepted
0xffffffff, so we must instead force the use of a register.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic_ll_sc.h | 89 ++++++++++++++-------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index c8c850bc3dfb..6dd011e0b434 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -26,7 +26,7 @@
  * (the optimize attribute silently ignores these options).
  */
 
-#define ATOMIC_OP(op, asm_op)						\
+#define ATOMIC_OP(op, asm_op, constraint)				\
 __LL_SC_INLINE void							\
 __LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
 {									\
@@ -40,11 +40,11 @@ __LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
 "	stxr	%w1, %w0, %2\n"						\
 "	cbnz	%w1, 1b"						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i));							\
+	: #constraint "r" (i));						\
 }									\
 __LL_SC_EXPORT(arch_atomic_##op);
 
-#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE int							\
 __LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
 {									\
@@ -59,14 +59,14 @@ __LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
 "	cbnz	%w1, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
 }									\
 __LL_SC_EXPORT(arch_atomic_##op##_return##name);
 
-#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)	\
 __LL_SC_INLINE int							\
 __LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
 {									\
@@ -81,7 +81,7 @@ __LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
 "	cbnz	%w2, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
@@ -99,8 +99,8 @@ __LL_SC_EXPORT(arch_atomic_fetch_##op##name);
 	ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
 	ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(add, add)
-ATOMIC_OPS(sub, sub)
+ATOMIC_OPS(add, add, I)
+ATOMIC_OPS(sub, sub, J)
 
 #undef ATOMIC_OPS
 #define ATOMIC_OPS(...)							\
@@ -110,17 +110,17 @@ ATOMIC_OPS(sub, sub)
 	ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
 	ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(and, and)
-ATOMIC_OPS(andnot, bic)
-ATOMIC_OPS(or, orr)
-ATOMIC_OPS(xor, eor)
+ATOMIC_OPS(and, and, )
+ATOMIC_OPS(andnot, bic, )
+ATOMIC_OPS(or, orr, )
+ATOMIC_OPS(xor, eor, )
 
 #undef ATOMIC_OPS
 #undef ATOMIC_FETCH_OP
 #undef ATOMIC_OP_RETURN
 #undef ATOMIC_OP
 
-#define ATOMIC64_OP(op, asm_op)						\
+#define ATOMIC64_OP(op, asm_op, constraint)				\
 __LL_SC_INLINE void							\
 __LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
 {									\
@@ -134,11 +134,11 @@ __LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
 "	stxr	%w1, %0, %2\n"						\
 "	cbnz	%w1, 1b"						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i));							\
+	: #constraint "r" (i));						\
 }									\
 __LL_SC_EXPORT(arch_atomic64_##op);
 
-#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE s64							\
 __LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
 {									\
@@ -153,14 +153,14 @@ __LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
 "	cbnz	%w1, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
 }									\
 __LL_SC_EXPORT(arch_atomic64_##op##_return##name);
 
-#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE s64							\
 __LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
 {									\
@@ -175,7 +175,7 @@ __LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
 "	cbnz	%w2, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
@@ -193,8 +193,8 @@ __LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
 	ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)	\
 	ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(add, add)
-ATOMIC64_OPS(sub, sub)
+ATOMIC64_OPS(add, add, I)
+ATOMIC64_OPS(sub, sub, J)
 
 #undef ATOMIC64_OPS
 #define ATOMIC64_OPS(...)						\
@@ -204,10 +204,10 @@ ATOMIC64_OPS(sub, sub)
 	ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)	\
 	ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(and, and)
-ATOMIC64_OPS(andnot, bic)
-ATOMIC64_OPS(or, orr)
-ATOMIC64_OPS(xor, eor)
+ATOMIC64_OPS(and, and, L)
+ATOMIC64_OPS(andnot, bic, )
+ATOMIC64_OPS(or, orr, L)
+ATOMIC64_OPS(xor, eor, L)
 
 #undef ATOMIC64_OPS
 #undef ATOMIC64_FETCH_OP
@@ -237,7 +237,7 @@ __LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
 }
 __LL_SC_EXPORT(arch_atomic64_dec_if_positive);
 
-#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl)		\
+#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl, constraint)	\
 __LL_SC_INLINE u##sz							\
 __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 					 unsigned long old,		\
@@ -265,29 +265,34 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 	"2:"								\
 	: [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),			\
 	  [v] "+Q" (*(u##sz *)ptr)					\
-	: [old] "Kr" (old), [new] "r" (new)				\
+	: [old] #constraint "r" (old), [new] "r" (new)			\
 	: cl);								\
 									\
 	return oldval;							\
 }									\
 __LL_SC_EXPORT(__cmpxchg_case_##name##sz);
 
-__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         )
-__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         )
-__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         )
-__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         )
-__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory")
-__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory")
-__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory")
-__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory")
-__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory")
-__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory")
-__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory")
-__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory")
-__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory")
-__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory")
+/*
+ * Earlier versions of GCC (no later than 8.1.0) appear to incorrectly
+ * handle the 'K' constraint for the value 4294967295 - thus we use no
+ * constraint for 32 bit operations.
+ */
+__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         , )
+__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         , )
+__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         , )
+__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         , L)
+__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory", )
+__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory", )
+__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory", )
+__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory", L)
+__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory", )
+__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory", )
+__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory", )
+__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory", L)
+__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory", L)
 
 #undef __CMPXCHG_CASE
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 3/5] arm64: atomics: avoid out-of-line ll/sc atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

When building for LSE atomics (CONFIG_ARM64_LSE_ATOMICS), if the hardware
or toolchain doesn't support it the existing code will fallback to ll/sc
atomics. It achieves this by branching from inline assembly to a function
that is built with specical compile flags. Further this results in the
clobbering of registers even when the fallback isn't used increasing
register pressure.

Let's improve this by providing inline implementations of both LSE and
ll/sc and use a static key to select between them. This allows for the
compiler to generate better atomics code.

To improve icache performance for the LL/SC fallback atomics, we put them
in their own subsection.

Please note that as atomic_arch.h is included indirectly by kernel.h
(via bitops.h), we cannot depend on features provided later in the kernel.h
file. This prevents us from placing the system_uses_lse_atomics function
in cpu_feature.h due to its dependencies.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic.h       |  11 +-
 arch/arm64/include/asm/atomic_arch.h  | 155 +++++++++++
 arch/arm64/include/asm/atomic_ll_sc.h | 113 ++++----
 arch/arm64/include/asm/atomic_lse.h   | 365 ++++++++------------------
 arch/arm64/include/asm/cmpxchg.h      |   2 +-
 arch/arm64/include/asm/lse.h          |  11 -
 6 files changed, 329 insertions(+), 328 deletions(-)
 create mode 100644 arch/arm64/include/asm/atomic_arch.h

diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
index 657b0457d83c..c70d3f389d29 100644
--- a/arch/arm64/include/asm/atomic.h
+++ b/arch/arm64/include/asm/atomic.h
@@ -17,16 +17,7 @@
 
 #ifdef __KERNEL__
 
-#define __ARM64_IN_ATOMIC_IMPL
-
-#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
-#include <asm/atomic_lse.h>
-#else
-#include <asm/atomic_ll_sc.h>
-#endif
-
-#undef __ARM64_IN_ATOMIC_IMPL
-
+#include <asm/atomic_arch.h>
 #include <asm/cmpxchg.h>
 
 #define ATOMIC_INIT(i)	{ (i) }
diff --git a/arch/arm64/include/asm/atomic_arch.h b/arch/arm64/include/asm/atomic_arch.h
new file mode 100644
index 000000000000..1aac7fc65084
--- /dev/null
+++ b/arch/arm64/include/asm/atomic_arch.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Selection between LSE and LL/SC atomics.
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ * Author: Andrew Murray <andrew.murray@arm.com>
+ */
+
+#ifndef __ASM_ATOMIC_ARCH_H
+#define __ASM_ATOMIC_ARCH_H
+
+
+#include <linux/jump_label.h>
+
+#include <asm/cpucaps.h>
+#include <asm/atomic_ll_sc.h>
+#include <asm/atomic_lse.h>
+
+extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
+extern struct static_key_false arm64_const_caps_ready;
+
+static inline bool system_uses_lse_atomics(void)
+{
+	return (IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) &&
+		IS_ENABLED(CONFIG_AS_LSE) &&
+		static_branch_likely(&arm64_const_caps_ready)) &&
+		static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
+}
+
+#define __lse_ll_sc_body(op, ...)					\
+({									\
+	system_uses_lse_atomics() ?					\
+		__lse_##op(__VA_ARGS__) :				\
+		__ll_sc_##op(__VA_ARGS__);				\
+})
+
+#define ATOMIC_OP(op)							\
+static inline void arch_##op(int i, atomic_t *v)			\
+{									\
+	__lse_ll_sc_body(op, i, v);					\
+}
+
+ATOMIC_OP(atomic_andnot)
+ATOMIC_OP(atomic_or)
+ATOMIC_OP(atomic_xor)
+ATOMIC_OP(atomic_add)
+ATOMIC_OP(atomic_and)
+ATOMIC_OP(atomic_sub)
+
+
+#define ATOMIC_FETCH_OP(name, op)					\
+static inline int arch_##op##name(int i, atomic_t *v)			\
+{									\
+	return __lse_ll_sc_body(op##name, i, v);			\
+}
+
+#define ATOMIC_FETCH_OPS(op)						\
+	ATOMIC_FETCH_OP(_relaxed, op)					\
+	ATOMIC_FETCH_OP(_acquire, op)					\
+	ATOMIC_FETCH_OP(_release, op)					\
+	ATOMIC_FETCH_OP(        , op)
+
+ATOMIC_FETCH_OPS(atomic_fetch_andnot)
+ATOMIC_FETCH_OPS(atomic_fetch_or)
+ATOMIC_FETCH_OPS(atomic_fetch_xor)
+ATOMIC_FETCH_OPS(atomic_fetch_add)
+ATOMIC_FETCH_OPS(atomic_fetch_and)
+ATOMIC_FETCH_OPS(atomic_fetch_sub)
+ATOMIC_FETCH_OPS(atomic_add_return)
+ATOMIC_FETCH_OPS(atomic_sub_return)
+
+
+#define ATOMIC64_OP(op)							\
+static inline void arch_##op(long i, atomic64_t *v)			\
+{									\
+	__lse_ll_sc_body(op, i, v);					\
+}
+
+ATOMIC64_OP(atomic64_andnot)
+ATOMIC64_OP(atomic64_or)
+ATOMIC64_OP(atomic64_xor)
+ATOMIC64_OP(atomic64_add)
+ATOMIC64_OP(atomic64_and)
+ATOMIC64_OP(atomic64_sub)
+
+
+#define ATOMIC64_FETCH_OP(name, op)					\
+static inline long arch_##op##name(long i, atomic64_t *v)		\
+{									\
+	return __lse_ll_sc_body(op##name, i, v);			\
+}
+
+#define ATOMIC64_FETCH_OPS(op)						\
+	ATOMIC64_FETCH_OP(_relaxed, op)					\
+	ATOMIC64_FETCH_OP(_acquire, op)					\
+	ATOMIC64_FETCH_OP(_release, op)					\
+	ATOMIC64_FETCH_OP(        , op)
+
+ATOMIC64_FETCH_OPS(atomic64_fetch_andnot)
+ATOMIC64_FETCH_OPS(atomic64_fetch_or)
+ATOMIC64_FETCH_OPS(atomic64_fetch_xor)
+ATOMIC64_FETCH_OPS(atomic64_fetch_add)
+ATOMIC64_FETCH_OPS(atomic64_fetch_and)
+ATOMIC64_FETCH_OPS(atomic64_fetch_sub)
+ATOMIC64_FETCH_OPS(atomic64_add_return)
+ATOMIC64_FETCH_OPS(atomic64_sub_return)
+
+
+static inline long arch_atomic64_dec_if_positive(atomic64_t *v)
+{
+	return __lse_ll_sc_body(atomic64_dec_if_positive, v);
+}
+
+#define __CMPXCHG_CASE(name, sz)			\
+static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
+					      u##sz old,		\
+					      u##sz new)		\
+{									\
+	return __lse_ll_sc_body(_cmpxchg_case_##name##sz,		\
+				ptr, old, new);				\
+}
+
+__CMPXCHG_CASE(    ,  8)
+__CMPXCHG_CASE(    , 16)
+__CMPXCHG_CASE(    , 32)
+__CMPXCHG_CASE(    , 64)
+__CMPXCHG_CASE(acq_,  8)
+__CMPXCHG_CASE(acq_, 16)
+__CMPXCHG_CASE(acq_, 32)
+__CMPXCHG_CASE(acq_, 64)
+__CMPXCHG_CASE(rel_,  8)
+__CMPXCHG_CASE(rel_, 16)
+__CMPXCHG_CASE(rel_, 32)
+__CMPXCHG_CASE(rel_, 64)
+__CMPXCHG_CASE(mb_,  8)
+__CMPXCHG_CASE(mb_, 16)
+__CMPXCHG_CASE(mb_, 32)
+__CMPXCHG_CASE(mb_, 64)
+
+
+#define __CMPXCHG_DBL(name)						\
+static inline long __cmpxchg_double##name(unsigned long old1,		\
+					 unsigned long old2,		\
+					 unsigned long new1,		\
+					 unsigned long new2,		\
+					 volatile void *ptr)		\
+{									\
+	return __lse_ll_sc_body(_cmpxchg_double##name, 			\
+				old1, old2, new1, new2, ptr);		\
+}
+
+__CMPXCHG_DBL(   )
+__CMPXCHG_DBL(_mb)
+
+#endif	/* __ASM_ATOMIC_LSE_H */
diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index 6dd011e0b434..95091f72228b 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -10,83 +10,86 @@
 #ifndef __ASM_ATOMIC_LL_SC_H
 #define __ASM_ATOMIC_LL_SC_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
+#if IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) && IS_ENABLED(CONFIG_AS_LSE)
+#define __LL_SC_FALLBACK(asm_ops)					\
+"	b	3f\n"							\
+"	.subsection	1\n"						\
+"3:\n"									\
+asm_ops "\n"								\
+"	b	4f\n"							\
+"	.previous\n"							\
+"4:\n"
+#else
+#define __LL_SC_FALLBACK(asm_ops) asm_ops
 #endif
 
 /*
  * AArch64 UP and SMP safe atomic ops.  We use load exclusive and
  * store exclusive to ensure that these are atomic.  We may loop
  * to ensure that the update happens.
- *
- * NOTE: these functions do *not* follow the PCS and must explicitly
- * save any clobbered registers other than x0 (regardless of return
- * value).  This is achieved through -fcall-saved-* compiler flags for
- * this file, which unfortunately don't work on a per-function basis
- * (the optimize attribute silently ignores these options).
  */
 
 #define ATOMIC_OP(op, asm_op, constraint)				\
-__LL_SC_INLINE void							\
-__LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
+static inline void							\
+__ll_sc_atomic_##op(int i, atomic_t *v)					\
 {									\
 	unsigned long tmp;						\
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "\n"				\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ldxr	%w0, %2\n"						\
 "	" #asm_op "	%w0, %w0, %w3\n"				\
 "	stxr	%w1, %w0, %2\n"						\
-"	cbnz	%w1, 1b"						\
+"	cbnz	%w1, 1b\n")						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i));						\
-}									\
-__LL_SC_EXPORT(arch_atomic_##op);
+}
 
 #define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE int							\
-__LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
+static inline int							\
+__ll_sc_atomic_##op##_return##name(int i, atomic_t *v)			\
 {									\
 	unsigned long tmp;						\
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "_return" #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ld" #acq "xr	%w0, %2\n"					\
 "	" #asm_op "	%w0, %w0, %w3\n"				\
 "	st" #rel "xr	%w1, %w0, %2\n"					\
 "	cbnz	%w1, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic_##op##_return##name);
+}
 
-#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)	\
-__LL_SC_INLINE int							\
-__LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
+#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint) \
+static inline int							\
+__ll_sc_atomic_fetch_##op##name(int i, atomic_t *v)			\
 {									\
 	unsigned long tmp;						\
 	int val, result;						\
 									\
 	asm volatile("// atomic_fetch_" #op #name "\n"			\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %3\n"					\
 "1:	ld" #acq "xr	%w0, %3\n"					\
 "	" #asm_op "	%w1, %w0, %w4\n"				\
 "	st" #rel "xr	%w2, %w1, %3\n"					\
 "	cbnz	%w2, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic_fetch_##op##name);
+}
 
 #define ATOMIC_OPS(...)							\
 	ATOMIC_OP(__VA_ARGS__)						\
@@ -121,66 +124,66 @@ ATOMIC_OPS(xor, eor, )
 #undef ATOMIC_OP
 
 #define ATOMIC64_OP(op, asm_op, constraint)				\
-__LL_SC_INLINE void							\
-__LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
+static inline void							\
+__ll_sc_atomic64_##op(s64 i, atomic64_t *v)				\
 {									\
 	s64 result;							\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "\n"				\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ldxr	%0, %2\n"						\
 "	" #asm_op "	%0, %0, %3\n"					\
 "	stxr	%w1, %0, %2\n"						\
-"	cbnz	%w1, 1b"						\
+"	cbnz	%w1, 1b")						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i));						\
-}									\
-__LL_SC_EXPORT(arch_atomic64_##op);
+}
 
 #define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE s64							\
-__LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
+static inline long							\
+__ll_sc_atomic64_##op##_return##name(s64 i, atomic64_t *v)		\
 {									\
 	s64 result;							\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "_return" #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ld" #acq "xr	%0, %2\n"					\
 "	" #asm_op "	%0, %0, %3\n"					\
 "	st" #rel "xr	%w1, %0, %2\n"					\
 "	cbnz	%w1, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic64_##op##_return##name);
+}
 
 #define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE s64							\
-__LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
+static inline long							\
+__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v)		\
 {									\
 	s64 result, val;						\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_fetch_" #op #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %3\n"					\
 "1:	ld" #acq "xr	%0, %3\n"					\
 "	" #asm_op "	%1, %0, %4\n"					\
 "	st" #rel "xr	%w2, %1, %3\n"					\
 "	cbnz	%w2, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
+}
 
 #define ATOMIC64_OPS(...)						\
 	ATOMIC64_OP(__VA_ARGS__)					\
@@ -214,13 +217,14 @@ ATOMIC64_OPS(xor, eor, L)
 #undef ATOMIC64_OP_RETURN
 #undef ATOMIC64_OP
 
-__LL_SC_INLINE s64
-__LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
+static inline s64
+__ll_sc_atomic64_dec_if_positive(atomic64_t *v)
 {
 	s64 result;
 	unsigned long tmp;
 
 	asm volatile("// atomic64_dec_if_positive\n"
+	__LL_SC_FALLBACK(
 "	prfm	pstl1strm, %2\n"
 "1:	ldxr	%0, %2\n"
 "	subs	%0, %0, #1\n"
@@ -228,20 +232,19 @@ __LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
 "	stlxr	%w1, %0, %2\n"
 "	cbnz	%w1, 1b\n"
 "	dmb	ish\n"
-"2:"
+"2:")
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)
 	:
 	: "cc", "memory");
 
 	return result;
 }
-__LL_SC_EXPORT(arch_atomic64_dec_if_positive);
 
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl, constraint)	\
-__LL_SC_INLINE u##sz							\
-__LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
+static inline u##sz							\
+__ll_sc__cmpxchg_case_##name##sz(volatile void *ptr,			\
 					 unsigned long old,		\
-					 u##sz new))			\
+					 u##sz new)			\
 {									\
 	unsigned long tmp;						\
 	u##sz oldval;							\
@@ -255,6 +258,7 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 		old = (u##sz)old;					\
 									\
 	asm volatile(							\
+	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %[v]\n"				\
 	"1:	ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n"		\
 	"	eor	%" #w "[tmp], %" #w "[oldval], %" #w "[old]\n"	\
@@ -262,15 +266,14 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 	"	st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n"	\
 	"	cbnz	%w[tmp], 1b\n"					\
 	"	" #mb "\n"						\
-	"2:"								\
+	"2:")								\
 	: [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),			\
 	  [v] "+Q" (*(u##sz *)ptr)					\
 	: [old] #constraint "r" (old), [new] "r" (new)			\
 	: cl);								\
 									\
 	return oldval;							\
-}									\
-__LL_SC_EXPORT(__cmpxchg_case_##name##sz);
+}
 
 /*
  * Earlier versions of GCC (no later than 8.1.0) appear to incorrectly
@@ -297,16 +300,17 @@ __CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory", L)
 #undef __CMPXCHG_CASE
 
 #define __CMPXCHG_DBL(name, mb, rel, cl)				\
-__LL_SC_INLINE long							\
-__LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,		\
+static inline long							\
+__ll_sc__cmpxchg_double##name(unsigned long old1,			\
 				      unsigned long old2,		\
 				      unsigned long new1,		\
 				      unsigned long new2,		\
-				      volatile void *ptr))		\
+				      volatile void *ptr)		\
 {									\
 	unsigned long tmp, ret;						\
 									\
 	asm volatile("// __cmpxchg_double" #name "\n"			\
+	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %2\n"				\
 	"1:	ldxp	%0, %1, %2\n"					\
 	"	eor	%0, %0, %3\n"					\
@@ -316,14 +320,13 @@ __LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,		\
 	"	st" #rel "xp	%w0, %5, %6, %2\n"			\
 	"	cbnz	%w0, 1b\n"					\
 	"	" #mb "\n"						\
-	"2:"								\
+	"2:")								\
 	: "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr)	\
 	: "r" (old1), "r" (old2), "r" (new1), "r" (new2)		\
 	: cl);								\
 									\
 	return ret;							\
-}									\
-__LL_SC_EXPORT(__cmpxchg_double##name);
+}
 
 __CMPXCHG_DBL(   ,        ,  ,         )
 __CMPXCHG_DBL(_mb, dmb ish, l, "memory")
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 69acb1c19a15..7dce5e1f074e 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -10,22 +10,13 @@
 #ifndef __ASM_ATOMIC_LSE_H
 #define __ASM_ATOMIC_LSE_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
-#endif
-
-#define __LL_SC_ATOMIC(op)	__LL_SC_CALL(arch_atomic_##op)
 #define ATOMIC_OP(op, asm_op)						\
-static inline void arch_atomic_##op(int i, atomic_t *v)			\
+static inline void __lse_atomic_##op(int i, atomic_t *v)			\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op),		\
-"	" #asm_op "	%w[i], %[v]\n")					\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS);						\
+	asm volatile(							\
+"	" #asm_op "	%w[i], %[v]\n"					\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v));							\
 }
 
 ATOMIC_OP(andnot, stclr)
@@ -36,21 +27,15 @@ ATOMIC_OP(add, stadd)
 #undef ATOMIC_OP
 
 #define ATOMIC_FETCH_OP(name, mb, op, asm_op, cl...)			\
-static inline int arch_atomic_fetch_##op##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_##op##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_##op##name),				\
-	/* LSE atomics */						\
-"	" #asm_op #mb "	%w[i], %w[i], %[v]")				\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	asm volatile(							\
+"	" #asm_op #mb "	%w[i], %w[i], %[v]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 #define ATOMIC_FETCH_OPS(op, asm_op)					\
@@ -68,23 +53,16 @@ ATOMIC_FETCH_OPS(add, ldadd)
 #undef ATOMIC_FETCH_OPS
 
 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...)				\
-static inline int arch_atomic_add_return##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_add_return##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(add_return##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30")				\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%w[i], %w[i], w30"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_OP_ADD_RETURN(_relaxed,   )
@@ -94,41 +72,26 @@ ATOMIC_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC_OP_ADD_RETURN
 
-static inline void arch_atomic_and(int i, atomic_t *v)
+static inline void __lse_atomic_and(int i, atomic_t *v)
 {
-	register int w0 asm ("w0") = i;
-	register atomic_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC(and)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	mvn	%w[i], %w[i]\n"
-	"	stclr	%w[i], %[v]")
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stclr	%w[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC_FETCH_OP_AND(name, mb, cl...)				\
-static inline int arch_atomic_fetch_and##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_and##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_and##name)					\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mvn	%w[i], %w[i]\n"					\
-	"	ldclr" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldclr" #mb "	%w[i], %w[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_FETCH_OP_AND(_relaxed,   )
@@ -138,42 +101,27 @@ ATOMIC_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_AND
 
-static inline void arch_atomic_sub(int i, atomic_t *v)
+static inline void __lse_atomic_sub(int i, atomic_t *v)
 {
-	register int w0 asm ("w0") = i;
-	register atomic_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC(sub)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	neg	%w[i], %w[i]\n"
-	"	stadd	%w[i], %[v]")
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stadd	%w[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC_OP_SUB_RETURN(name, mb, cl...)				\
-static inline int arch_atomic_sub_return##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_sub_return##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(sub_return##name)				\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30")				\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS , ##cl);					\
+	"	add	%w[i], %w[i], w30"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_OP_SUB_RETURN(_relaxed,   )
@@ -184,23 +132,16 @@ ATOMIC_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC_OP_SUB_RETURN
 
 #define ATOMIC_FETCH_OP_SUB(name, mb, cl...)				\
-static inline int arch_atomic_fetch_sub##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_sub##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_sub##name)					\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
-	"	ldadd" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldadd" #mb "	%w[i], %w[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_FETCH_OP_SUB(_relaxed,   )
@@ -209,20 +150,14 @@ ATOMIC_FETCH_OP_SUB(_release,  l, "memory")
 ATOMIC_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_SUB
-#undef __LL_SC_ATOMIC
 
-#define __LL_SC_ATOMIC64(op)	__LL_SC_CALL(arch_atomic64_##op)
 #define ATOMIC64_OP(op, asm_op)						\
-static inline void arch_atomic64_##op(s64 i, atomic64_t *v)		\
+static inline void __lse_atomic64_##op(s64 i, atomic64_t *v)		\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op),	\
-"	" #asm_op "	%[i], %[v]\n")					\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS);						\
+	asm volatile(							\
+"	" #asm_op "	%[i], %[v]\n"					\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v));							\
 }
 
 ATOMIC64_OP(andnot, stclr)
@@ -233,21 +168,15 @@ ATOMIC64_OP(add, stadd)
 #undef ATOMIC64_OP
 
 #define ATOMIC64_FETCH_OP(name, mb, op, asm_op, cl...)			\
-static inline s64 arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_##op##name(s64 i, atomic64_t *v)\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_##op##name),				\
-	/* LSE atomics */						\
-"	" #asm_op #mb "	%[i], %[i], %[v]")				\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	asm volatile(							\
+"	" #asm_op #mb "	%[i], %[i], %[v]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 #define ATOMIC64_FETCH_OPS(op, asm_op)					\
@@ -265,23 +194,16 @@ ATOMIC64_FETCH_OPS(add, ldadd)
 #undef ATOMIC64_FETCH_OPS
 
 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...)				\
-static inline s64 arch_atomic64_add_return##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_add_return##name(s64 i, atomic64_t *v)\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(add_return##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30")				\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%[i], %[i], x30"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_OP_ADD_RETURN(_relaxed,   )
@@ -291,41 +213,26 @@ ATOMIC64_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC64_OP_ADD_RETURN
 
-static inline void arch_atomic64_and(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_and(s64 i, atomic64_t *v)
 {
-	register s64 x0 asm ("x0") = i;
-	register atomic64_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(and)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	mvn	%[i], %[i]\n"
-	"	stclr	%[i], %[v]")
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stclr	%[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC64_FETCH_OP_AND(name, mb, cl...)				\
-static inline s64 arch_atomic64_fetch_and##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_and##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_and##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mvn	%[i], %[i]\n"					\
-	"	ldclr" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldclr" #mb "	%[i], %[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_FETCH_OP_AND(_relaxed,   )
@@ -335,42 +242,27 @@ ATOMIC64_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_AND
 
-static inline void arch_atomic64_sub(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 {
-	register s64 x0 asm ("x0") = i;
-	register atomic64_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(sub)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	neg	%[i], %[i]\n"
-	"	stadd	%[i], %[v]")
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stadd	%[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)				\
-static inline s64 arch_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(sub_return##name)				\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30")				\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%[i], %[i], x30"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_OP_SUB_RETURN(_relaxed,   )
@@ -381,23 +273,16 @@ ATOMIC64_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC64_OP_SUB_RETURN
 
 #define ATOMIC64_FETCH_OP_SUB(name, mb, cl...)				\
-static inline s64 arch_atomic64_fetch_sub##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_sub##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_sub##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
-	"	ldadd" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldadd" #mb "	%[i], %[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_FETCH_OP_SUB(_relaxed,   )
@@ -407,15 +292,9 @@ ATOMIC64_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_SUB
 
-static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
+static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 {
-	register long x0 asm ("x0") = (long)v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(dec_if_positive)
-	__nops(6),
-	/* LSE atomics */
+	asm volatile(
 	"1:	ldr	x30, %[v]\n"
 	"	subs	%[ret], x30, #1\n"
 	"	b.lt	2f\n"
@@ -423,20 +302,16 @@ static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
 	"	sub	x30, x30, #1\n"
 	"	sub	x30, x30, %[ret]\n"
 	"	cbnz	x30, 1b\n"
-	"2:")
-	: [ret] "+&r" (x0), [v] "+Q" (v->counter)
+	"2:"
+	: [ret] "+&r" (v), [v] "+Q" (v->counter)
 	:
-	: __LL_SC_CLOBBERS, "cc", "memory");
+	: "x30", "cc", "memory");
 
-	return x0;
+	return (long)v;
 }
 
-#undef __LL_SC_ATOMIC64
-
-#define __LL_SC_CMPXCHG(op)	__LL_SC_CALL(__cmpxchg_case_##op)
-
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...)			\
-static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
+static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr,	\
 					      u##sz old,		\
 					      u##sz new)		\
 {									\
@@ -444,17 +319,13 @@ static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
 	register u##sz x1 asm ("x1") = old;				\
 	register u##sz x2 asm ("x2") = new;				\
 									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_CMPXCHG(name##sz)					\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mov	" #w "30, %" #w "[old]\n"			\
 	"	cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n"	\
-	"	mov	%" #w "[ret], " #w "30")			\
+	"	mov	%" #w "[ret], " #w "30"				\
 	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr)		\
 	: [old] "r" (x1), [new] "r" (x2)				\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	: "x30", ##cl);							\
 									\
 	return x0;							\
 }
@@ -476,13 +347,10 @@ __CMPXCHG_CASE(w, h,  mb_, 16, al, "memory")
 __CMPXCHG_CASE(w,  ,  mb_, 32, al, "memory")
 __CMPXCHG_CASE(x,  ,  mb_, 64, al, "memory")
 
-#undef __LL_SC_CMPXCHG
 #undef __CMPXCHG_CASE
 
-#define __LL_SC_CMPXCHG_DBL(op)	__LL_SC_CALL(__cmpxchg_double##op)
-
 #define __CMPXCHG_DBL(name, mb, cl...)					\
-static inline long __cmpxchg_double##name(unsigned long old1,		\
+static inline long __lse__cmpxchg_double##name(unsigned long old1,	\
 					 unsigned long old2,		\
 					 unsigned long new1,		\
 					 unsigned long new2,		\
@@ -496,20 +364,16 @@ static inline long __cmpxchg_double##name(unsigned long old1,		\
 	register unsigned long x3 asm ("x3") = new2;			\
 	register unsigned long x4 asm ("x4") = (unsigned long)ptr;	\
 									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_CMPXCHG_DBL(name)					\
-	__nops(3),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
 	"	eor	%[old1], %[old1], %[oldval1]\n"			\
 	"	eor	%[old2], %[old2], %[oldval2]\n"			\
-	"	orr	%[old1], %[old1], %[old2]")			\
+	"	orr	%[old1], %[old1], %[old2]"			\
 	: [old1] "+&r" (x0), [old2] "+&r" (x1),				\
 	  [v] "+Q" (*(unsigned long *)ptr)				\
 	: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),		\
 	  [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)		\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	: cl);								\
 									\
 	return x0;							\
 }
@@ -517,7 +381,6 @@ static inline long __cmpxchg_double##name(unsigned long old1,		\
 __CMPXCHG_DBL(   ,   )
 __CMPXCHG_DBL(_mb, al, "memory")
 
-#undef __LL_SC_CMPXCHG_DBL
 #undef __CMPXCHG_DBL
 
 #endif	/* __ASM_ATOMIC_LSE_H */
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index 7a299a20f6dc..e5fff8cd4904 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -10,7 +10,7 @@
 #include <linux/build_bug.h>
 #include <linux/compiler.h>
 
-#include <asm/atomic.h>
+#include <asm/atomic_arch.h>
 #include <asm/barrier.h>
 #include <asm/lse.h>
 
diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h
index 8262325e2fc6..52b80846d1b7 100644
--- a/arch/arm64/include/asm/lse.h
+++ b/arch/arm64/include/asm/lse.h
@@ -22,14 +22,6 @@
 
 __asm__(".arch_extension	lse");
 
-/* Move the ll/sc atomics out-of-line */
-#define __LL_SC_INLINE		notrace
-#define __LL_SC_PREFIX(x)	__ll_sc_##x
-#define __LL_SC_EXPORT(x)	EXPORT_SYMBOL(__LL_SC_PREFIX(x))
-
-/* Macro for constructing calls to out-of-line ll/sc atomics */
-#define __LL_SC_CALL(op)	"bl\t" __stringify(__LL_SC_PREFIX(op)) "\n"
-#define __LL_SC_CLOBBERS	"x16", "x17", "x30"
 
 /* In-line patching at runtime */
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)				\
@@ -46,9 +38,6 @@ __asm__(".arch_extension	lse");
 
 #else	/* __ASSEMBLER__ */
 
-#define __LL_SC_INLINE		static inline
-#define __LL_SC_PREFIX(x)	x
-#define __LL_SC_EXPORT(x)
 
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)	llsc
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 4/5] arm64: avoid using hard-coded registers for LSE atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

Now that we have removed the out-of-line ll/sc atomics we can give
the compiler the freedom to choose its own register allocation. Let's
remove the hard-coded use of x30.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic_lse.h | 70 +++++++++++++++++------------
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 7dce5e1f074e..c6bd87d2915b 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -55,12 +55,14 @@ ATOMIC_FETCH_OPS(add, ldadd)
 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...)				\
 static inline int __lse_atomic_add_return##name(int i, atomic_t *v)	\
 {									\
+	u32 tmp;							\
+									\
 	asm volatile(							\
-	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30"				\
-	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
+	"	add	%w[i], %w[i], %w[tmp]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -113,13 +115,15 @@ static inline void __lse_atomic_sub(int i, atomic_t *v)
 #define ATOMIC_OP_SUB_RETURN(name, mb, cl...)				\
 static inline int __lse_atomic_sub_return##name(int i, atomic_t *v)	\
 {									\
+	u32 tmp;							\
+									\
 	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
-	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30"				\
-	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
+	"	add	%w[i], %w[i], %w[tmp]"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);							\
 									\
 	return i;							\
 }
@@ -196,12 +200,14 @@ ATOMIC64_FETCH_OPS(add, ldadd)
 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...)				\
 static inline long __lse_atomic64_add_return##name(s64 i, atomic64_t *v)\
 {									\
+	unsigned long tmp;						\
+									\
 	asm volatile(							\
-	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30"				\
-	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
+	"	add	%[i], %[i], %x[tmp]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -254,13 +260,15 @@ static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)				\
 static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
 {									\
+	unsigned long tmp;						\
+									\
 	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
-	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30"				\
-	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
+	"	add	%[i], %[i], %x[tmp]"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -294,18 +302,20 @@ ATOMIC64_FETCH_OP_SUB(        , al, "memory")
 
 static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 {
+	unsigned long tmp;
+
 	asm volatile(
-	"1:	ldr	x30, %[v]\n"
-	"	subs	%[ret], x30, #1\n"
+	"1:	ldr	%x[tmp], %[v]\n"
+	"	subs	%[ret], %x[tmp], #1\n"
 	"	b.lt	2f\n"
-	"	casal	x30, %[ret], %[v]\n"
-	"	sub	x30, x30, #1\n"
-	"	sub	x30, x30, %[ret]\n"
-	"	cbnz	x30, 1b\n"
+	"	casal	%x[tmp], %[ret], %[v]\n"
+	"	sub	%x[tmp], %x[tmp], #1\n"
+	"	sub	%x[tmp], %x[tmp], %[ret]\n"
+	"	cbnz	%x[tmp], 1b\n"
 	"2:"
-	: [ret] "+&r" (v), [v] "+Q" (v->counter)
+	: [ret] "+&r" (v), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)
 	:
-	: "x30", "cc", "memory");
+	: "cc", "memory");
 
 	return (long)v;
 }
@@ -318,14 +328,16 @@ static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr,	\
 	register unsigned long x0 asm ("x0") = (unsigned long)ptr;	\
 	register u##sz x1 asm ("x1") = old;				\
 	register u##sz x2 asm ("x2") = new;				\
+	unsigned long tmp;						\
 									\
 	asm volatile(							\
-	"	mov	" #w "30, %" #w "[old]\n"			\
-	"	cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n"	\
-	"	mov	%" #w "[ret], " #w "30"				\
-	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr)		\
+	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
+	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
+	"	mov	%" #w "[ret], %" #w "[tmp]"			\
+	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
+	  [tmp] "=&r" (tmp)						\
 	: [old] "r" (x1), [new] "r" (x2)				\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return x0;							\
 }
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 5/5] arm64: atomics: remove atomic_ll_sc compilation unit
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

We no longer fall back to out-of-line atomics on systems with
CONFIG_ARM64_LSE_ATOMICS where ARM64_HAS_LSE_ATOMICS is not set. Let's
remove the now unused compilation unit which provided these symbols.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/lib/Makefile       | 19 -------------------
 arch/arm64/lib/atomic_ll_sc.c |  3 ---
 2 files changed, 22 deletions(-)
 delete mode 100644 arch/arm64/lib/atomic_ll_sc.c

diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 33c2a4abda04..f10809ef1690 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -11,25 +11,6 @@ CFLAGS_REMOVE_xor-neon.o	+= -mgeneral-regs-only
 CFLAGS_xor-neon.o		+= -ffreestanding
 endif
 
-# Tell the compiler to treat all general purpose registers (with the
-# exception of the IP registers, which are already handled by the caller
-# in case of a PLT) as callee-saved, which allows for efficient runtime
-# patching of the bl instruction in the caller with an atomic instruction
-# when supported by the CPU. Result and argument registers are handled
-# correctly, based on the function prototype.
-lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
-CFLAGS_atomic_ll_sc.o	:= -ffixed-x1 -ffixed-x2        		\
-		   -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6		\
-		   -ffixed-x7 -fcall-saved-x8 -fcall-saved-x9		\
-		   -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12	\
-		   -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15	\
-		   -fcall-saved-x18 -fomit-frame-pointer
-CFLAGS_REMOVE_atomic_ll_sc.o := $(CC_FLAGS_FTRACE)
-GCOV_PROFILE_atomic_ll_sc.o	:= n
-KASAN_SANITIZE_atomic_ll_sc.o	:= n
-KCOV_INSTRUMENT_atomic_ll_sc.o	:= n
-UBSAN_SANITIZE_atomic_ll_sc.o	:= n
-
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
 obj-$(CONFIG_CRC32) += crc32.o
diff --git a/arch/arm64/lib/atomic_ll_sc.c b/arch/arm64/lib/atomic_ll_sc.c
deleted file mode 100644
index b0c538b0da28..000000000000
--- a/arch/arm64/lib/atomic_ll_sc.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <asm/atomic.h>
-#define __ARM64_IN_ATOMIC_IMPL
-#include <asm/atomic_ll_sc.h>
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related


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