Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/5] arm64: dts: actions: Add gpio properties to pinctrl node for S900
From: Manivannan Sadhasivam @ 2018-05-20  5:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520051736.4842-1-manivannan.sadhasivam@linaro.org>

Add gpio properties to pinctrl node for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..aa3a49b0d646 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -178,6 +178,9 @@
 			compatible = "actions,s900-pinctrl";
 			reg = <0x0 0xe01b0000 0x0 0x1000>;
 			clocks = <&cmu CLK_GPIO>;
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 146>;
+			#gpio-cells = <2>;
 		};
 
 		timer: timer at e0228000 {
-- 
2.14.1

^ permalink raw reply related

* [PATCH v2 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
From: Manivannan Sadhasivam @ 2018-05-20  5:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520051736.4842-1-manivannan.sadhasivam@linaro.org>

Add gpio line names to Actions Semi S900 based Bubblegum-96 board.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 ++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index ff043c961d75..d0ba35df9015 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -34,3 +34,178 @@
 	status = "okay";
 	clocks = <&cmu CLK_UART5>;
 };
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC = not connected (pin out but not routed from the chip to
+ *              anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC = Low Speed External Connector
+ *         HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+	gpio-line-names =
+		"GPIO-A", /* GPIO_0, LSEC pin 23 */
+		"GPIO-B", /* GPIO_1, LSEC pin 24 */
+		"GPIO-C", /* GPIO_2, LSEC pin 25 */
+		"GPIO-D", /* GPIO_3, LSEC pin 26 */
+		"GPIO-E", /* GPIO_4, LSEC pin 27 */
+		"GPIO-F", /* GPIO_5, LSEC pin 28 */
+		"GPIO-G", /* GPIO_6, LSEC pin 29 */
+		"GPIO-H", /* GPIO_7, LSEC pin 30 */
+		"GPIO-I", /* GPIO_8, LSEC pin 31 */
+		"GPIO-J", /* GPIO_9, LSEC pin 32 */
+		"NC", /* GPIO_10 */
+		"NC", /* GPIO_11 */
+		"SIRQ2_1V8", /* GPIO_12 */
+		"PCM0_OUT", /* GPIO_13 */
+		"WIFI_LED", /* GPIO_14 */
+		"PCM0_SYNC", /* GPIO_15 */
+		"PCM0_CLK", /* GPIO_16 */
+		"PCM0_IN", /* GPIO_17 */
+		"BT_LED", /* GPIO_18 */
+		"LED0", /* GPIO_19 */
+		"LED1", /* GPIO_20 */
+		"JTAG_TCK", /* GPIO_21 */
+		"JTAG_TMS", /* GPIO_22 */
+		"JTAG_TDI", /* GPIO_23 */
+		"JTAG_TDO", /* GPIO_24 */
+		"[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+		"NC", /* GPIO_26 */
+		"[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+		"SD0_D0", /* GPIO_28 */
+		"SD0_D1", /* GPIO_29 */
+		"SD0_D2", /* GPIO_30 */
+		"SD0_D3", /* GPIO_31 */
+		"SD1_D0", /* GPIO_32 */
+		"SD1_D1", /* GPIO_33 */
+		"SD1_D2", /* GPIO_34 */
+		"SD1_D3", /* GPIO_35 */
+		"SD0_CMD", /* GPIO_36 */
+		"SD0_CLK", /* GPIO_37 */
+		"SD1_CMD", /* GPIO_38 */
+		"SD1_CLK", /* GPIO_39 */
+		"SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+		"SPI0_CS", /* GPIO_41, LSEC pin 12 */
+		"SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+		"SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+		"I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+		"I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+		"UART0_RX", /* GPIO_46, LSEC pin 7 */
+		"UART0_TX", /* GPIO_47, LSEC pin 5 */
+		"UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+		"UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+		"I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+		"I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+		"I2C0_SCLK", /* GPIO_52 */
+		"I2C0_SDATA", /* GPIO_53 */
+		"I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+		"I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+		"I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+		"I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+		"CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+		"CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+		"CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+		"CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+		"CSI0_CN", /* GPIO_62, HSEC pin 4 */
+		"CSI0_CP", /* GPIO_63, HSEC pin 2 */
+		"CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+		"CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+		"CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+		"CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+		"[CLK0]", /* GPIO_68, HSEC pin 15 */
+		"CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+		"CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+		"CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+		"CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+		"CSI1_CN", /* GPIO_73, HSEC pin 56 */
+		"CSI1_CP", /* GPIO_74, HSEC pin 54 */
+		"[CLK1]", /* GPIO_75, HSEC pin 17 */
+		"[GPIOD0]", /* GPIO_76 */
+		"[GPIOD1]", /* GPIO_77 */
+		"BT_RST_N", /* GPIO_78 */
+		"EXT_DC_EN", /* GPIO_79 */
+		"[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+		"[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+		"[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+		"[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+		"WAKE_BT", /* GPIO_84 */
+		"WL_REG_ON", /* GPIO_85 */
+		"NC", /* GPIO_86 */
+		"NC", /* GPIO_87 */
+		"NC", /* GPIO_88 */
+		"NC", /* GPIO_89 */
+		"NC", /* GPIO_90 */
+		"WIFI_WAKE", /* GPIO_91 */
+		"BT_WAKE", /* GPIO_92 */
+		"NC", /* GPIO_93 */
+		"OTG_EN2", /* GPIO_94 */
+		"OTG_EN", /* GPIO_95 */
+		"DSI_DP3", /* GPIO_96, HSEC pin 45 */
+		"DSI_DN3", /* GPIO_97, HSEC pin 47 */
+		"DSI_DP1", /* GPIO_98, HSEC pin 33 */
+		"DSI_DN1", /* GPIO_99, HSEC pin 35 */
+		"DSI_CP", /* GPIO_100, HSEC pin 21 */
+		"DSI_CN", /* GPIO_101, HSEC pin 23 */
+		"DSI_DP0", /* GPIO_102, HSEC pin 27 */
+		"DSI_DN0", /* GPIO_103, HSEC pin 29 */
+		"DSI_DP2", /* GPIO_104, HSEC pin 39 */
+		"DSI_DN2", /* GPIO_105, HSEC pin 41 */
+		"N0_D0", /* GPIO_106 */
+		"N0_D1", /* GPIO_107 */
+		"N0_D2", /* GPIO_108 */
+		"N0_D3", /* GPIO_109 */
+		"N0_D4", /* GPIO_110 */
+		"N0_D5", /* GPIO_111 */
+		"N0_D6", /* GPIO_112 */
+		"N0_D7", /* GPIO_113 */
+		"N0_DQS", /* GPIO_114 */
+		"N0_DQSN", /* GPIO_115 */
+		"NC", /* GPIO_116 */
+		"NC", /* GPIO_117 */
+		"NC", /* GPIO_118 */
+		"N0_CEB1", /* GPIO_119 */
+		"CARD_DT", /* GPIO_120 */
+		"N0_CEB3", /* GPIO_121 */
+		"SD_DAT0", /* GPIO_122, HSEC pin 1 */
+		"SD_DAT1", /* GPIO_123, HSEC pin 3 */
+		"SD_DAT2", /* GPIO_124, HSEC pin 5 */
+		"SD_DAT3", /* GPIO_125, HSEC pin 7 */
+		"NC", /* GPIO_126 */
+		"NC", /* GPIO_127 */
+		"[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+		"[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+		"NC", /* GPIO_130 */
+		"SD_CMD", /* GPIO_131 */
+		"GPIO-L", /* GPIO_132, LSEC pin 34 */
+		"GPIO-K", /* GPIO_133, LSEC pin 33 */
+		"NC", /* GPIO_134 */
+		"SD_SCLK", /* GPIO_135 */
+		"NC", /* GPIO_136 */
+		"JTAG_TRST", /* GPIO_137 */
+		"I2C3_SCLK", /* GPIO_138 */
+		"LED2", /* GPIO_139 */
+		"LED3", /* GPIO_140 */
+		"I2C3_SDATA", /* GPIO_141 */
+		"UART3_RX", /* GPIO_142 */
+		"UART3_TX", /* GPIO_143 */
+		"UART3_RTSB", /* GPIO_144 */
+		"UART3_CTSB"; /* GPIO_145 */
+};
-- 
2.14.1

^ permalink raw reply related

* [PATCH v2 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
From: Manivannan Sadhasivam @ 2018-05-20  5:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520051736.4842-1-manivannan.sadhasivam@linaro.org>

Add gpio support to pinctrl driver for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/pinctrl/actions/Kconfig        |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c  | 198 +++++++++++++++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
 drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
 4 files changed, 247 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
index ede97cdbbc12..490927b4ea76 100644
--- a/drivers/pinctrl/actions/Kconfig
+++ b/drivers/pinctrl/actions/Kconfig
@@ -4,6 +4,7 @@ config PINCTRL_OWL
 	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
+	select GPIOLIB
 	help
 	  Say Y here to enable Actions Semi OWL pinctrl driver
 
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
index ee090697b1e9..76243caa08c6 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.c
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -31,6 +32,7 @@
  * struct owl_pinctrl - pinctrl state of the device
  * @dev: device handle
  * @pctrldev: pinctrl handle
+ * @chip: gpio chip
  * @lock: spinlock to protect registers
  * @soc: reference to soc_data
  * @base: pinctrl register base address
@@ -38,6 +40,7 @@
 struct owl_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctrldev;
+	struct gpio_chip chip;
 	raw_spinlock_t lock;
 	struct clk *clk;
 	const struct owl_pinctrl_soc_data *soc;
@@ -536,6 +539,190 @@ static struct pinctrl_desc owl_pinctrl_desc = {
 	.owner = THIS_MODULE,
 };
 
+static const struct owl_gpio_port *
+owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
+{
+	unsigned int start = 0, i;
+
+	for (i = 0; i < pctrl->soc->nports; i++) {
+		const struct owl_gpio_port *port = &pctrl->soc->ports[i];
+
+		if (*pin >= start && *pin < start + port->pins) {
+			*pin -= start;
+			return port;
+		}
+
+		start += port->pins;
+	}
+
+	return NULL;
+}
+
+static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
+{
+	u32 val;
+
+	val = readl_relaxed(base);
+
+	if (flag)
+		val |= BIT(pin);
+	else
+		val &= ~BIT(pin);
+
+	writel_relaxed(val, base);
+}
+
+static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	/* disable gpio output */
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+	u32 val;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(gpio_base + port->dat);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_init(struct owl_pinctrl *pctrl)
+{
+	struct gpio_chip *chip;
+	int ret;
+
+	chip = &pctrl->chip;
+	chip->base = -1;
+	chip->ngpio = pctrl->soc->ngpios;
+	chip->label = dev_name(pctrl->dev);
+	chip->parent = pctrl->dev;
+	chip->owner = THIS_MODULE;
+	chip->of_node = pctrl->dev->of_node;
+
+	ret = gpiochip_add_data(&pctrl->chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to register gpiochip\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 int owl_pinctrl_probe(struct platform_device *pdev,
 				struct owl_pinctrl_soc_data *soc_data)
 {
@@ -571,6 +758,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 	owl_pinctrl_desc.pins = soc_data->pins;
 	owl_pinctrl_desc.npins = soc_data->npins;
 
+	pctrl->chip.direction_input  = owl_gpio_direction_input;
+	pctrl->chip.direction_output = owl_gpio_direction_output;
+	pctrl->chip.get = owl_gpio_get;
+	pctrl->chip.set = owl_gpio_set;
+	pctrl->chip.request = owl_gpio_request;
+	pctrl->chip.free = owl_gpio_free;
+
 	pctrl->soc = soc_data;
 	pctrl->dev = &pdev->dev;
 
@@ -581,6 +775,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 		return PTR_ERR(pctrl->pctrldev);
 	}
 
+	ret = owl_gpio_init(pctrl);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, pctrl);
 
 	return 0;
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
index 448f81a6db3b..74342378937c 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.h
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -114,6 +114,22 @@ struct owl_pinmux_func {
 	unsigned int ngroups;
 };
 
+/**
+ * struct owl_gpio_port - Actions GPIO port info
+ * @offset: offset of the GPIO port.
+ * @pins: number of pins belongs to the GPIO port.
+ * @outen: offset of the output enable register.
+ * @inen: offset of the input enable register.
+ * @dat: offset of the data register.
+ */
+struct owl_gpio_port {
+	unsigned int offset;
+	unsigned int pins;
+	unsigned int outen;
+	unsigned int inen;
+	unsigned int dat;
+};
+
 /**
  * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
  * @pins: array describing all pins of the pin controller.
@@ -124,6 +140,8 @@ struct owl_pinmux_func {
  * @ngroups: number of entries in @groups.
  * @padinfo: array describing the pad info of this SoC.
  * @ngpios: number of pingroups the driver should expose as GPIOs.
+ * @port: array describing all GPIO ports of this SoC.
+ * @nports: number of GPIO ports in this SoC.
  */
 struct owl_pinctrl_soc_data {
 	const struct pinctrl_pin_desc *pins;
@@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
 	unsigned int ngroups;
 	const struct owl_padinfo *padinfo;
 	unsigned int ngpios;
+	const struct owl_gpio_port *ports;
+	unsigned int nports;
 };
 
 int owl_pinctrl_probe(struct platform_device *pdev,
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
index 08d93f8fc086..5503c7945764 100644
--- a/drivers/pinctrl/actions/pinctrl-s900.c
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -33,6 +33,13 @@
 #define PAD_SR1			(0x0274)
 #define PAD_SR2			(0x0278)
 
+#define OWL_GPIO_PORT_A		0
+#define OWL_GPIO_PORT_B		1
+#define OWL_GPIO_PORT_C		2
+#define OWL_GPIO_PORT_D		3
+#define OWL_GPIO_PORT_E		4
+#define OWL_GPIO_PORT_F		5
+
 #define _GPIOA(offset)		(offset)
 #define _GPIOB(offset)		(32 + (offset))
 #define _GPIOC(offset)		(64 + (offset))
@@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
 	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
 };
 
+#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)	\
+	[OWL_GPIO_PORT_##port] = {				\
+		.offset = base,					\
+		.pins = count,					\
+		.outen = _outen,				\
+		.inen = _inen,					\
+		.dat = _dat,					\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
+};
+
 static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.padinfo = s900_padinfo,
 	.pins = (const struct pinctrl_pin_desc *)s900_pads,
@@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.nfunctions = ARRAY_SIZE(s900_functions),
 	.groups = s900_groups,
 	.ngroups = ARRAY_SIZE(s900_groups),
-	.ngpios = NUM_GPIOS
+	.ngpios = NUM_GPIOS,
+	.ports = s900_gpio_ports,
+	.nports = ARRAY_SIZE(s900_gpio_ports)
 };
 
 static int s900_pinctrl_probe(struct platform_device *pdev)
-- 
2.14.1

^ permalink raw reply related

* [PATCH v2 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries
From: Manivannan Sadhasivam @ 2018-05-20  5:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520051736.4842-1-manivannan.sadhasivam@linaro.org>

Add S900 pinctrl entries under ARCH_ACTIONS

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..9e1a17c9b4a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,12 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/pinctrl/actions/*
 F:	drivers/soc/actions/
 F:	include/dt-bindings/power/owl-*
 F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 
-- 
2.14.1

^ permalink raw reply related

* [PATCH v3 1/2] soc: imx: gpcv2: Do not pass static memory as platform data
From: Shawn Guo @ 2018-05-20  6:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHQ1cqGCG0rwPcpoY+bnjcyupg18x1TvULJzvAjRxSkL6z1U_Q@mail.gmail.com>

On Sat, May 19, 2018 at 03:35:55PM -0700, Andrey Smirnov wrote:
> On Tue, Apr 10, 2018 at 11:32 AM, Andrey Smirnov
> <andrew.smirnov@gmail.com> wrote:
> > Platform device core assumes the ownership of dev.platform_data as
> > well as that it is dynamically allocated and it will try to kfree it
> > as a part of platform_device_release(). Change the code to use
> > platform_device_add_data() n instead of a pointer to a static memory
> > to avoid causing a BUG() when calling platform_device_put().
> >
> > The problem can be reproduced by artificially enabling the error path
> > of platform_device_add() call (around line 357).
> >
> > Note that this change also allows us to constify imx7_pgc_domains,
> > since we no longer need to be able to modify it.
> >
> 
> Shawn,
> 
> What's the status of these two patches? Do I need to change anything
> or are they good to go?

The patches were queued on imx/drivers branch for a while.  I forgot to
let you know.  Sorry.

Shawn

^ permalink raw reply

* 答复: [PATCH v4 11/12] mm/memory-failure: increase queued recovery work's priority
From: gengdongjiu @ 2018-05-20  7:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180516162829.14348-12-james.morse@arm.com>

> 
> arm64 can take an NMI-like error notification when user-space steps in some corrupt memory. APEI's GHES code will call
> memory_failure_queue() to schedule the recovery work. We then return to user-space, possibly taking the fault again.
> 
> Currently the arch code unconditionally signals user-space from this path, so we don't get stuck in this loop, but the affected process never
> benefits from memory_failure()s recovery work. To fix this we need to know the recovery work will run before we get back to user-space.
> 
> Increase the priority of the recovery work by scheduling it on the system_highpri_wq, then try to bump the current task off this CPU so that
> the recover work starts immediately.
> 
> Reported-by: Xie XiuQi <xiexiuqi@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Punit Agrawal <punit.agrawal@arm.com>
> Tested-by: Tyler Baicar <tbaicar@codeaurora.org>
> CC: Xie XiuQi <xiexiuqi@huawei.com>
> CC: gengdongjiu <gengdongjiu@huawei.com>

Tested-by: gengdongjiu <gengdongjiu@huawei.com>

> ---
>  mm/memory-failure.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 9d142b9b86dc..f0e69d7ac406 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -55,6 +55,7 @@
>  #include <linux/hugetlb.h>
>  #include <linux/memory_hotplug.h>
>  #include <linux/mm_inline.h>
> +#include <linux/preempt.h>
>  #include <linux/kfifo.h>
>  #include <linux/ratelimit.h>
>  #include "internal.h"
> @@ -1333,6 +1334,7 @@ static DEFINE_PER_CPU(struct memory_failure_cpu, memory_failure_cpu);
>   */
>  void memory_failure_queue(unsigned long pfn, int flags)  {
> +	int cpu = smp_processor_id();
>  	struct memory_failure_cpu *mf_cpu;
>  	unsigned long proc_flags;
>  	struct memory_failure_entry entry = {
> @@ -1342,11 +1344,14 @@ void memory_failure_queue(unsigned long pfn, int flags)
> 
>  	mf_cpu = &get_cpu_var(memory_failure_cpu);
>  	spin_lock_irqsave(&mf_cpu->lock, proc_flags);
> -	if (kfifo_put(&mf_cpu->fifo, entry))
> -		schedule_work_on(smp_processor_id(), &mf_cpu->work);
> -	else
> +	if (kfifo_put(&mf_cpu->fifo, entry)) {
> +		queue_work_on(cpu, system_highpri_wq, &mf_cpu->work);
> +		set_tsk_need_resched(current);
> +		preempt_set_need_resched();
> +	} else {
>  		pr_err("Memory failure: buffer overflow when queuing memory failure at %#lx\n",
>  		       pfn);
> +	}
>  	spin_unlock_irqrestore(&mf_cpu->lock, proc_flags);
>  	put_cpu_var(memory_failure_cpu);
>  }
> --
> 2.16.2

^ permalink raw reply

* 答复: [PATCH v4 11/12] mm/memory-failure: increase queued recovery work's priority
From: gengdongjiu @ 2018-05-20  7:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180516162829.14348-12-james.morse@arm.com>

> 
> arm64 can take an NMI-like error notification when user-space steps in some corrupt memory. APEI's GHES code will call
> memory_failure_queue() to schedule the recovery work. We then return to user-space, possibly taking the fault again.
> 
> Currently the arch code unconditionally signals user-space from this path, so we don't get stuck in this loop, but the affected process never
> benefits from memory_failure()s recovery work. To fix this we need to know the recovery work will run before we get back to user-space.
> 
> Increase the priority of the recovery work by scheduling it on the system_highpri_wq, then try to bump the current task off this CPU so that
> the recover work starts immediately.
> 
> Reported-by: Xie XiuQi <xiexiuqi@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Punit Agrawal <punit.agrawal@arm.com>
> Tested-by: Tyler Baicar <tbaicar@codeaurora.org>
> CC: Xie XiuQi <xiexiuqi@huawei.com>
> CC: gengdongjiu <gengdongjiu@huawei.com>

Tested-by: gengdongjiu <gengdongjiu@huawei.com>

> ---
>  mm/memory-failure.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 9d142b9b86dc..f0e69d7ac406 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -55,6 +55,7 @@
>  #include <linux/hugetlb.h>
>  #include <linux/memory_hotplug.h>
>  #include <linux/mm_inline.h>
> +#include <linux/preempt.h>
>  #include <linux/kfifo.h>
>  #include <linux/ratelimit.h>
>  #include "internal.h"
> @@ -1333,6 +1334,7 @@ static DEFINE_PER_CPU(struct memory_failure_cpu, memory_failure_cpu);
>   */
>  void memory_failure_queue(unsigned long pfn, int flags)  {
> +	int cpu = smp_processor_id();
>  	struct memory_failure_cpu *mf_cpu;
>  	unsigned long proc_flags;
>  	struct memory_failure_entry entry = {
> @@ -1342,11 +1344,14 @@ void memory_failure_queue(unsigned long pfn, int flags)
> 
>  	mf_cpu = &get_cpu_var(memory_failure_cpu);
>  	spin_lock_irqsave(&mf_cpu->lock, proc_flags);
> -	if (kfifo_put(&mf_cpu->fifo, entry))
> -		schedule_work_on(smp_processor_id(), &mf_cpu->work);
> -	else
> +	if (kfifo_put(&mf_cpu->fifo, entry)) {
> +		queue_work_on(cpu, system_highpri_wq, &mf_cpu->work);
> +		set_tsk_need_resched(current);
> +		preempt_set_need_resched();
> +	} else {
>  		pr_err("Memory failure: buffer overflow when queuing memory failure at %#lx\n",
>  		       pfn);
> +	}
>  	spin_unlock_irqrestore(&mf_cpu->lock, proc_flags);
>  	put_cpu_var(memory_failure_cpu);
>  }
> --
> 2.16.2

^ permalink raw reply

* [linux-sunxi] [PATCH 10/15] drm/sun4i: Add support for R40 TV TCONs
From: Jernej Škrabec @ 2018-05-20  7:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGRGNgXbKGhnern4=_W9W5dKM54H5B1dnAD7up-23rUAMWWCSw@mail.gmail.com>

Hi,

Dne nedelja, 20. maj 2018 ob 04:09:52 CEST je Julian Calaby napisal(a):
> Hi Jernej,
> 
> On Sun, May 20, 2018 at 11:57 AM, Julian Calaby <julian.calaby@gmail.com> 
wrote:
> > Hi Jernej,
> > 
> > On Sun, May 20, 2018 at 4:31 AM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> >> R40 display pipeline has a lot of possible configurations. HDMI can be
> >> connected to 2 different TCONs (out of 4) and mixers can be connected to
> >> any TCON. All this must be configured in TCON TOP.
> >> 
> >> Along with definition of TCON capabilities also add mux callback, which
> >> can configure this complex pipeline.
> >> 
> >> For now, only TCON TV is supported.
> >> 
> >> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> ---
> >> 
> >>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 39 ++++++++++++++++++++++++++++++
> >>  1 file changed, 39 insertions(+)
> >> 
> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> b/drivers/gpu/drm/sun4i/sun4i_tcon.c index e0c562ce1c22..81b9551e4f78
> >> 100644
> >> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> @@ -1274,6 +1274,31 @@ static int sun6i_tcon_set_mux(struct sun4i_tcon
> >> *tcon,>> 
> >>         return 0;
> >>  
> >>  }
> >> 
> >> +static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon *tcon,
> >> +                                    const struct drm_encoder *encoder,
> >> +                                    int index)
> >> +{
> >> +       if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
> >> +               sun8i_tcon_top_set_hdmi_src(tcon->tcon_top, index);
> >> +
> >> +       sun8i_tcon_top_de_config(tcon->tcon_top, tcon->id,
> >> +                                tcon_type_tv, index);
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static int sun8i_r40_tcon_tv_set_mux_0(struct sun4i_tcon *tcon,
> >> +                                      const struct drm_encoder *encoder)
> >> +{
> >> +       return sun8i_r40_tcon_tv_set_mux(tcon, encoder, 0);
> >> +}
> >> +
> >> +static int sun8i_r40_tcon_tv_set_mux_1(struct sun4i_tcon *tcon,
> >> +                                      const struct drm_encoder *encoder)
> >> +{
> >> +       return sun8i_r40_tcon_tv_set_mux(tcon, encoder, 1);
> >> +}
> > 
> > Are TCON-TOPs going to be a common thing in new SoCs from Allwinner?
> > If so, maybe we should add an index to the TCON quirks and have a
> > common TCON-TOP set_mux function.
> 
> Actually, that only moves it up a level. Should it be a devicetree property?
> 

TCON-TOP is besides R40 part of two newest Allwinner SoCs, H6 and A63. 
However, they have only one TV TCON and one LCD TCON, so indexes are not 
needed for them (always 0). This makes R40 somewhat special. I don't think it 
makes sense to expand everything just for one SoC.

Best regards,
Jernej

^ permalink raw reply

* [PATCH v1 0/5] Initial support of Trusted Foundations on Tegra30
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This series of patches brings initial support of Trusted Foundations to
Tegra30, that is to the consumer-grade Tegra30 devices which do not allow
to easily replace the proprietary bootloader. Support is initial because
this series implements only a proper CPU boot-up (main + secondary cores)
and a basic L2 cache maintenance that is done using the TF firmware.
Suspend-resume support is missing yet as I couldn't get it to work
(CPU hangs on resume from suspend after awhile and seems that is related
to inappropriately done cache maintenance during of suspend-resume using
the firmware), it is work-in-progress for now.

This patchset is partially based on the work done by Micha? Miros?aw [0].

Please review, thanks.

[0] https://www.spinics.net/lists/linux-tegra/msg30368.html

Dmitry Osipenko (5):
  ARM: trusted_foundations: Implement L2 cache initialization callback
  ARM: trusted_foundations: Provide information about whether firmware
    is registered
  ARM: tegra: Setup L2 cache using Trusted Foundations firmware
  ARM: tegra: Don't apply CPU erratas in insecure mode
  ARM: tegra: Always boot CPU in ARM-mode

 arch/arm/firmware/trusted_foundations.c    | 28 ++++++++++++++++++++++
 arch/arm/include/asm/trusted_foundations.h |  7 ++++++
 arch/arm/mach-tegra/reset-handler.S        | 28 +++++++++++++++-------
 arch/arm/mach-tegra/reset.c                |  5 +++-
 arch/arm/mach-tegra/reset.h                |  4 +++-
 arch/arm/mach-tegra/tegra.c                | 15 ++++++++++++
 6 files changed, 77 insertions(+), 10 deletions(-)

-- 
2.17.0

^ permalink raw reply

* [PATCH v1 1/5] ARM: trusted_foundations: Implement L2 cache initialization callback
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520101542.12206-1-digetx@gmail.com>

Implement L2 cache initialization firmware callback that should be invoked
early in boot to enable cache HW.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/firmware/trusted_foundations.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
index 3fb1b5a1dce9..198ce5c75ca0 100644
--- a/arch/arm/firmware/trusted_foundations.c
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -18,8 +18,13 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <asm/firmware.h>
+#include <asm/outercache.h>
 #include <asm/trusted_foundations.h>
 
+#define TF_CACHE_MAINT		0xfffff100
+
+#define TF_CACHE_INIT		1
+
 #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
 
 #define TF_CPU_PM		0xfffffffc
@@ -63,9 +68,27 @@ static int tf_prepare_idle(void)
 	return 0;
 }
 
+#ifdef CONFIG_CACHE_L2X0
+static void tf_cache_write_sec(unsigned long val, unsigned int reg)
+{
+	pr_warn("%s: Ignoring write [0x%x]: 0x%08lx\n", __func__, reg, val);
+}
+
+static int tf_init_cache(void)
+{
+	outer_cache.write_sec = tf_cache_write_sec;
+	tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_INIT, 0);
+
+	return 0;
+}
+#endif /* CONFIG_CACHE_L2X0 */
+
 static const struct firmware_ops trusted_foundations_ops = {
 	.set_cpu_boot_addr = tf_set_cpu_boot_addr,
 	.prepare_idle = tf_prepare_idle,
+#ifdef CONFIG_CACHE_L2X0
+	.l2x0_init = tf_init_cache,
+#endif
 };
 
 void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
-- 
2.17.0

^ permalink raw reply related

* [PATCH v1 2/5] ARM: trusted_foundations: Provide information about whether firmware is registered
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520101542.12206-1-digetx@gmail.com>

Add a helper that provides information about whether Trusted Foundations
firmware operations have been registered.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/firmware/trusted_foundations.c    | 5 +++++
 arch/arm/include/asm/trusted_foundations.h | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
index 198ce5c75ca0..0428351574de 100644
--- a/arch/arm/firmware/trusted_foundations.c
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -120,3 +120,8 @@ void of_register_trusted_foundations(void)
 		panic("Trusted Foundation: missing version-minor property\n");
 	register_trusted_foundations(&pdata);
 }
+
+bool trusted_foundations_registered(void)
+{
+	return firmware_ops == &trusted_foundations_ops;
+}
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
index 00748350cf72..bfd0d780824b 100644
--- a/arch/arm/include/asm/trusted_foundations.h
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -31,6 +31,7 @@
 #include <linux/of.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
+#include <linux/types.h>
 
 struct trusted_foundations_platform_data {
 	unsigned int version_major;
@@ -41,6 +42,7 @@ struct trusted_foundations_platform_data {
 
 void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
 void of_register_trusted_foundations(void);
+bool trusted_foundations_registered(void);
 
 #else /* CONFIG_TRUSTED_FOUNDATIONS */
 
@@ -68,6 +70,11 @@ static inline void of_register_trusted_foundations(void)
 	if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"))
 		register_trusted_foundations(NULL);
 }
+
+static inline bool trusted_foundations_registered(void)
+{
+	return false;
+}
 #endif /* CONFIG_TRUSTED_FOUNDATIONS */
 
 #endif
-- 
2.17.0

^ permalink raw reply related

* [PATCH v1 3/5] ARM: tegra: Setup L2 cache using Trusted Foundations firmware
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520101542.12206-1-digetx@gmail.com>

On Tegra20/30 L2 cache must be initialized using firmware call if CPU
is running in insecure mode. Initialize L2 cache and setup the outer-cache
callbacks in early boot using the firmware API.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/tegra.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index f9587be48235..590b1cf1a8c4 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -38,6 +38,7 @@
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
 
+#include <asm/firmware.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
@@ -70,9 +71,23 @@ u32 tegra_uart_config[3] = {
 	0,
 };
 
+static void __init tegra_trusted_foundations_l2x0_cache_init(void)
+{
+	if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+	    IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
+	    of_machine_is_compatible("nvidia,tegra20"))
+		call_firmware_op(l2x0_init);
+
+	if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+	    IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) &&
+	    of_machine_is_compatible("nvidia,tegra30"))
+		call_firmware_op(l2x0_init);
+}
+
 static void __init tegra_init_early(void)
 {
 	of_register_trusted_foundations();
+	tegra_trusted_foundations_l2x0_cache_init();
 	tegra_cpu_reset_handler_init();
 }
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH v1 4/5] ARM: tegra: Don't apply CPU erratas in insecure mode
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520101542.12206-1-digetx@gmail.com>

CPU isn't allowed to touch secure registers while running under secure
monitor. Hence skip applying CPU erratas in the reset handler if Trusted
Foundations firmware presents.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/reset-handler.S | 27 +++++++++++++++++++--------
 arch/arm/mach-tegra/reset.c         |  3 +++
 arch/arm/mach-tegra/reset.h         |  4 +++-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 805f306fa6f7..d84c74a95806 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -121,6 +121,12 @@ ENTRY(__tegra_cpu_reset_handler)
 	cpsid	aif, 0x13			@ SVC mode, interrupts disabled
 
 	tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+
+	adr	r12, __tegra_cpu_reset_handler_data
+	ldr	r0, [r12, #RESET_DATA(TF_PRESENT)]
+	cmp	r0, #0
+	bne	after_errata
+
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 t20_check:
 	cmp	r6, #TEGRA20
@@ -155,7 +161,6 @@ after_errata:
 	and	r10, r10, #0x3			@ R10 = CPU number
 	mov	r11, #1
 	mov	r11, r11, lsl r10  		@ R11 = CPU mask
-	adr	r12, __tegra_cpu_reset_handler_data
 
 #ifdef CONFIG_SMP
 	/* Does the OS know about this CPU? */
@@ -169,10 +174,9 @@ after_errata:
 	cmp	r6, #TEGRA20
 	bne	1f
 	/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-	mov32	r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
 	mov	r0, #CPU_NOT_RESETTABLE
 	cmp	r10, #0
-	strneb	r0, [r5, #__tegra20_cpu1_resettable_status_offset]
+	strneb	r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
 1:
 #endif
 
@@ -278,13 +282,20 @@ ENDPROC(__tegra_cpu_reset_handler)
 	.type	__tegra_cpu_reset_handler_data, %object
 	.globl	__tegra_cpu_reset_handler_data
 __tegra_cpu_reset_handler_data:
-	.rept	TEGRA_RESET_DATA_SIZE
-	.long	0
-	.endr
+	.long	0	/* TEGRA_RESET_MASK_PRESENT */
+	.long	0	/* TEGRA_RESET_MASK_LP1 */
+	.long	0	/* TEGRA_RESET_MASK_LP2 */
+	.long	0	/* TEGRA_RESET_STARTUP_SECONDARY */
+	.long	0	/* TEGRA_RESET_STARTUP_LP2 */
+	.long	0	/* TEGRA_RESET_STARTUP_LP1 */
+
 	.globl	__tegra20_cpu1_resettable_status_offset
 	.equ	__tegra20_cpu1_resettable_status_offset, \
 					. - __tegra_cpu_reset_handler_start
-	.byte	0
-	.align L1_CACHE_SHIFT
+	.long	0	/* TEGRA_RESET_RESETTABLE_STATUS */
 
+	.globl	__tegra_tf_present
+	.equ	__tegra_tf_present, . - __tegra_cpu_reset_handler_start
+	.long	0	/* TEGRA_RESET_TF_PRESENT */
+	.align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_end)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index dc558892753c..b02ae7699842 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -24,6 +24,7 @@
 #include <asm/cacheflush.h>
 #include <asm/firmware.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/trusted_foundations.h>
 
 #include "iomap.h"
 #include "irammap.h"
@@ -89,6 +90,8 @@ static void __init tegra_cpu_reset_handler_enable(void)
 
 void __init tegra_cpu_reset_handler_init(void)
 {
+	__tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] =
+		trusted_foundations_registered();
 
 #ifdef CONFIG_SMP
 	__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index 9c479c7925b8..0d9ddc022ece 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -25,7 +25,9 @@
 #define TEGRA_RESET_STARTUP_SECONDARY	3
 #define TEGRA_RESET_STARTUP_LP2		4
 #define TEGRA_RESET_STARTUP_LP1		5
-#define TEGRA_RESET_DATA_SIZE		6
+#define TEGRA_RESET_RESETTABLE_STATUS	6
+#define TEGRA_RESET_TF_PRESENT		7
+#define TEGRA_RESET_DATA_SIZE		8
 
 #ifndef __ASSEMBLY__
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH v1 5/5] ARM: tegra: Always boot CPU in ARM-mode
From: Dmitry Osipenko @ 2018-05-20 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520101542.12206-1-digetx@gmail.com>

CPU always jumps into the reset handler in ARM-mode from the Trusted
Foundations firmware, hence make CPU to always jump into kernel in
ARM-mode regardless of the firmware presence to support Thumb2 kernel + TF
case.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/reset-handler.S | 1 +
 arch/arm/mach-tegra/reset.c         | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index d84c74a95806..7e15c3bdf118 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -115,6 +115,7 @@ ENTRY(__tegra_cpu_reset_handler_start)
  *       must be position-independent.
  */
 
+	.arm
 	.align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler)
 
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index b02ae7699842..3f1ef4561298 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -97,7 +97,7 @@ void __init tegra_cpu_reset_handler_init(void)
 	__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
 		*((u32 *)cpu_possible_mask);
 	__tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
-		__pa_symbol((void *)secondary_startup);
+		__pa_symbol((void *)secondary_startup_arm);
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-- 
2.17.0

^ permalink raw reply related

* [PATCH] iio: adc: stm32-dfsdm: include stm32-dfsdm-adc.h
From: Jonathan Cameron @ 2018-05-20 10:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526397557-31389-1-git-send-email-fabrice.gasnier@st.com>

On Tue, 15 May 2018 17:19:17 +0200
Fabrice Gasnier <fabrice.gasnier@st.com> wrote:

> Fix the following sparse warnings:
>   CHECK   drivers/iio/adc/stm32-dfsdm-adc.c
> symbol 'stm32_dfsdm_get_buff_cb' was not declared. Should it be static?
> symbol 'stm32_dfsdm_release_buff_cb' was not declared. Should it be static?
> 
> BTW, move interrupt.h to sort headers alphabetically.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Applied to the togreg branch of iio.git and pushed out as testing for
the autobuilders to play with it.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/stm32-dfsdm-adc.c       | 4 ++--
>  include/linux/iio/adc/stm32-dfsdm-adc.h | 2 ++
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> index 1b78bec..31462ae 100644
> --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> @@ -8,11 +8,11 @@
>  
>  #include <linux/dmaengine.h>
>  #include <linux/dma-mapping.h>
> -#include <linux/interrupt.h>
> +#include <linux/iio/adc/stm32-dfsdm-adc.h>
>  #include <linux/iio/buffer.h>
>  #include <linux/iio/hw-consumer.h>
> -#include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> +#include <linux/interrupt.h>
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> diff --git a/include/linux/iio/adc/stm32-dfsdm-adc.h b/include/linux/iio/adc/stm32-dfsdm-adc.h
> index e7dc7a5..0da298b 100644
> --- a/include/linux/iio/adc/stm32-dfsdm-adc.h
> +++ b/include/linux/iio/adc/stm32-dfsdm-adc.h
> @@ -9,6 +9,8 @@
>  #ifndef STM32_DFSDM_ADC_H
>  #define STM32_DFSDM_ADC_H
>  
> +#include <linux/iio/iio.h>
> +
>  int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
>  			    int (*cb)(const void *data, size_t size,
>  				      void *private),

^ permalink raw reply

* [reset-control] How to initialize hardware state with the shared reset line?
From: Martin Blumenstingl @ 2018-05-20 10:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK7LNATZgJ4MxOFLUCNARWv3Zz=gpL-jGReDnBnArquiaXRWoQ@mail.gmail.com>

Hi,

On Thu, May 10, 2018 at 11:16 AM, Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
[snip]
> I may be missing something, but
> one solution might be reset hogging on the
> reset provider side.  This allows us to describe
> the initial state of reset lines in the reset controller.
>
> The idea for "reset-hog" is similar to:
>  - "gpio-hog" defined in
>    Documentation/devicetree/bindings/gpio/gpio.txt
>  - "assigned-clocks" defined in
>    Documetation/devicetree/bindings/clock/clock-bindings.txt
>
>
>
> For example,
>
>    reset-controller {
>             ....
>
>             line_a {
>                   reset-hog;
>                   resets = <1>;
>                   reset-assert;
>             };
>    }
>
>
> When the reset controller is registered,
> the reset ID '1' is asserted.
>
>
> So, all reset consumers that share the reset line '1'
> will start from the asserted state
> (i.e. defined state machine state).
I wonder if a "reset hog" can be board specific:
- GPIO hogs are definitely board specific (meson-gxbb-odroidc2.dts for
example uses it to take the USB hub out of reset)
- assigned-clock-parents (and the like) can also be board specific (I
made up a use-case since I don't know of any actual examples: board A
uses an external XTAL while board B uses some other internal
clock-source because it doesn't have an external XTAL)

however, can reset lines be board specific? or in other words: do we
need to describe them in device-tree?
we could extend struct reset_controller_dev (= reset controller
driver) if they are not board specific:
- either assert all reset lines by default except if they are listed
in a new field (may break backwards compatibility, requires testing of
all reset controller drivers)
- specify a list of reset lines and their desired state (or to keep it
easy: specify a list of reset lines that should be asserted)
(I must admit that this is basically your idea but the definition is
moved from device-tree to the reset controller driver)

any "chip" specific differences could be expressed by using a
different of_device_id

one the other hand: your "reset hog" solution looks fine to me if
reset lines can be board specific

> From the discussion with Martin Blumenstingl
> (https://lkml.org/lkml/2018/4/28/115),
> the problem for Amlogic is that
> the reset line is "de-asserted" by default.
> If so, the 'reset-hog' would fix the problem,
> and DWC3 driver would be able to use
> shared, level reset, I think.
I think you are right: if we could control the initial state then we
should be able to use level resets


Regards
Martin

^ permalink raw reply

* [PATCH] arm64: KVM: reduce guest fpsimd trap
From: Marc Zyngier @ 2018-05-20 11:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <F348A9E21A573744858FF7E5D32E29D81BDF6C92@dggemi509-mbs.china.huawei.com>

On Sat, 19 May 2018 02:38:33 +0000
"Tangnianyao (ICT)" <tangnianyao@huawei.com> wrote:

> On Wed, May 16, 2018 at 20:46 PM GST+8, Christoffer Dall wrote:
> > On Wed, May 16, 2018 at 11:32:17AM +0100, Dave Martin wrote:  
> > > On Wed, May 16, 2018 at 10:25:40AM +0100, Marc Zyngier wrote:  
> > > > [+Dave]
> > > > 
> > > > Hi Nianyao,
> > > > 
> > > > On 16/05/18 10:08, Tangnianyao (ICT) wrote:  
> > > > > Add last_fpsimd_trap to notify if guest last exit reason is handling fpsimd. If guest is using fpsimd frequently, save host's fpsimd state and restore guest's fpsimd state and deactive fpsimd trap before returning to guest. It can avoid guest fpsimd trap soon to improve performance.  
> > > 
> > > So, the purpose of this patch is to context switch the FPSIMD state on 
> > > initial entry to the guest, instead of enabling the trap and context 
> > > switching the FPSIMD state lazily?
> > > 
> > > And you decide whether to do this or not, based on whether the guest   
> > triggered a lazy FPSIMD switch previously?  
> 
> I try to detect guest using fpsimd , but not overtraining which may 
> include more complexity and not suitable for common cases. Therefore I 
> just decide whether guest have triggerd a lazy fpsimd switch last time.
> 
> > >   
> > > > > 
> > > > > Signed-off-by: Nianyao Tang <tangnianyao@huawei.com>
> > > > > ---
> > > > >  arch/arm64/kernel/asm-offsets.c |  1 +
> > > > >  arch/arm64/kvm/hyp/entry.S      |  5 +++++
> > > > >  arch/arm64/kvm/hyp/switch.c     | 38 ++++++++++++++++++++++++++++++++++++--
> > > > >  include/linux/kvm_host.h        |  1 +
> > > > >  4 files changed, 43 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/arch/arm64/kernel/asm-offsets.c 
> > > > > b/arch/arm64/kernel/asm-offsets.c index 5bdda65..35a9c5c 100644
> > > > > --- a/arch/arm64/kernel/asm-offsets.c
> > > > > +++ b/arch/arm64/kernel/asm-offsets.c
> > > > > @@ -136,6 +136,7 @@ int main(void)  #ifdef CONFIG_KVM_ARM_HOST
> > > > >    DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
> > > > >    DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
> > > > > +  DEFINE(VCPU_LAST_FPSIMD_TRAP, offsetof(struct kvm_vcpu, 
> > > > > + last_fpsimd_trap));
> > > > >    DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
> > > > >    DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
> > > > >    DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
> > > > > diff --git a/arch/arm64/kvm/hyp/entry.S 
> > > > > b/arch/arm64/kvm/hyp/entry.S index e41a161..956e042 100644
> > > > > --- a/arch/arm64/kvm/hyp/entry.S
> > > > > +++ b/arch/arm64/kvm/hyp/entry.S
> > > > > @@ -197,6 +197,11 @@ alternative_endif
> > > > >  	add	x0, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
> > > > >  	bl	__fpsimd_restore_state
> > > > >  
> > > > > +	// Mark guest using fpsimd now
> > > > > +	ldr x0, [x3, #VCPU_LAST_FPSIMD_TRAP]
> > > > > +	add x0, x0, #1  
> > > 
> > > Can this overflow?  
> 
> It won't overflow. It only trigger one fpsimd trap and restore guest's fpsimd
> state and deactivate fpsimd trap. When next non-fpsimd trap comes, it will be clear unconditionally.
> 
> > >   
> > > > > +	str x0, [x3, #VCPU_LAST_FPSIMD_TRAP]
> > > > > +
> > > > >  	// Skip restoring fpexc32 for AArch64 guests
> > > > >  	mrs	x1, hcr_el2
> > > > >  	tbnz	x1, #HCR_RW_SHIFT, 1f
> > > > > diff --git a/arch/arm64/kvm/hyp/switch.c 
> > > > > b/arch/arm64/kvm/hyp/switch.c index d964523..86eea1b 100644
> > > > > --- a/arch/arm64/kvm/hyp/switch.c
> > > > > +++ b/arch/arm64/kvm/hyp/switch.c
> > > > > @@ -92,7 +92,13 @@ static void activate_traps_vhe(struct kvm_vcpu 
> > > > > *vcpu)
> > > > >  
> > > > >  	val = read_sysreg(cpacr_el1);
> > > > >  	val |= CPACR_EL1_TTA;
> > > > > -	val &= ~(CPACR_EL1_FPEN | CPACR_EL1_ZEN);
> > > > > +	val &= ~CPACR_EL1_ZEN;
> > > > > +
> > > > > +	if (vcpu->last_fpsimd_trap)
> > > > > +		val |= CPACR_EL1_FPEN;
> > > > > +	else
> > > > > +		val &= ~CPACR_EL1_FPEN;
> > > > > +
> > > > >  	write_sysreg(val, cpacr_el1);
> > > > >  
> > > > >  	write_sysreg(kvm_get_hyp_vector(), vbar_el1); @@ -105,7 +111,13 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
> > > > >  	__activate_traps_common(vcpu);
> > > > >  
> > > > >  	val = CPTR_EL2_DEFAULT;
> > > > > -	val |= CPTR_EL2_TTA | CPTR_EL2_TFP | CPTR_EL2_TZ;
> > > > > +	val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
> > > > > +
> > > > > +	if (vcpu->last_fpsimd_trap)
> > > > > +		val &= ~CPTR_EL2_TFP;
> > > > > +	else
> > > > > +		val |= CPTR_EL2_TFP;
> > > > > +
> > > > >  	write_sysreg(val, cptr_el2);
> > > > >  }
> > > > >  
> > > > > @@ -406,6 +418,17 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
> > > > >  	__activate_traps(vcpu);
> > > > >  	__activate_vm(vcpu->kvm);
> > > > >  
> > > > > +	/*
> > > > > +	 * If guest last trap to host for handling fpsimd, last_fpsimd_trap
> > > > > +	 * is set. Restore guest's fpsimd state and deactivate fpsimd trap
> > > > > +	 * to avoid guest traping soon.
> > > > > +	 */
> > > > > +	if (vcpu->last_fpsimd_trap) {
> > > > > +		__fpsimd_save_state(&host_ctxt->gp_regs.fp_regs);
> > > > > +		__fpsimd_restore_state(&guest_ctxt->gp_regs.fp_regs);
> > > > > +		vcpu->last_fpsimd_trap = 0;
> > > > > +	}
> > > > > +
> > > > >  	sysreg_restore_guest_state_vhe(guest_ctxt);
> > > > >  	__debug_switch_to_guest(vcpu);
> > > > >  
> > > > > @@ -454,6 +477,17 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
> > > > >  	__activate_traps(vcpu);
> > > > >  	__activate_vm(kern_hyp_va(vcpu->kvm));
> > > > >  
> > > > > +	/*
> > > > > +	 * If guest last trap to host for handling fpsimd, last_fpsimd_trap
> > > > > +	 * is set. Restore guest's fpsimd state and deactivate fpsimd trap
> > > > > +	 * to avoid guest traping soon.
> > > > > +	 */
> > > > > +	if (vcpu->last_fpsimd_trap) {
> > > > > +		__fpsimd_save_state(&host_ctxt->gp_regs.fp_regs);
> > > > > +		__fpsimd_restore_state(&guest_ctxt->gp_regs.fp_regs);
> > > > > +		vcpu->last_fpsimd_trap = 0;
> > > > > +	}
> > > > > +
> > > > >  	__hyp_vgic_restore_state(vcpu);
> > > > >  	__timer_enable_traps(vcpu);
> > > > >  
> > > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h 
> > > > > index 6930c63..46bdf0d 100644
> > > > > --- a/include/linux/kvm_host.h
> > > > > +++ b/include/linux/kvm_host.h
> > > > > @@ -274,6 +274,7 @@ struct kvm_vcpu {
> > > > >  	bool preempted;
> > > > >  	struct kvm_vcpu_arch arch;
> > > > >  	struct dentry *debugfs_dentry;
> > > > > +	unsigned int last_fpsimd_trap;
> > > > >  };
> > > > >  
> > > > >  static inline int kvm_vcpu_exiting_guest_mode(struct kvm_vcpu 
> > > > > *vcpu)
> > > > > --
> > > > > 2.7.4
> > > > >   
> > > > 
> > > > This doesn't seem to be the 100% correct. I can't see how this works 
> > > > when being preempted, for example... I suggest you look at Dave 
> > > > Martin's series[1], which does this correctly.  
> > > 
> > > If I've understood correctly, this chooses between eager and lazy 
> > > switching, which is addressing a different issue from [1].
> > > 
> > > In effect, this code is attempting to predict whether the guest will 
> > > use FPSIMD before the next exit.  If the prediction is correct and the 
> > > guest does use FPSIMD, then the overhead of the lazy FPSIMD trap 
> > > disappears.  This is probably a good thing, though it may increase 
> > > interrupt latency a little.  However, if the prediction is wrong and 
> > > the guest doesn't use FPSIMD before the next exit, then the overhead 
> > > of guest entry increases for no benefit, because FPSIMD was switched 
> > > unnecessarily.
> > > 
> > > Do you have any benchmarks or metrics on the accuracy of the 
> > > prediction and the overall impact on performance?
> > > 
> > > The changes in [1] should reduce the number of FPSIMD context switches 
> > > overall, so may reduce the benefit of this patch.
> > >   
> 
> This idea may be different. It tries to detect guest using fpsimd, do eager 
> switching ,and reduce guest trap. [1] reduces fpsimd context switches in host when
> it has already trapped.
> 
> > 
> > 
> > Based on previous measurements [2], I found that only in 29% of the times when we return to userspace or are preempted, has the VCPU touched the FPSIMD registers, and therefore a significant majority of the times we enter the guest, the guest doesn't touch the FPSIMD state, even if it has touched it before.
> > 
> > As Dave suggests, if there is data that shows that an immediately following entry from an exit that had VFP enabled implies with a very high probablity that the guest will touch VFP again, then something like this might make sense, but I'd like to see some data to back up this hypothesis before adding additional complexity to the code.
> > 
> > [2]: https://lists.cs.columbia.edu/pipermail/kvmarm/2018-February/029835.html  
> 
> I try to detect guest using fpsimd, and choose eager switching to avoid trapping to hyp soon.
> The reason is, in some micro architecture, vmid switch will flush all L1 TLB entry which doesn't
> contain vmid. It will result in extra 2-stage table walk when returning to guest, which could be
> avoid if not trap to el2. As I know, Maia has this issue.

This looks extremely microarchitectural. Have you tested how this
behaves on other implementations?

> I have done some benchmark test on guest and find that, frequent context switch , which
> save and restore fpsimd frequently, resulted in extra cost compared to host context switch
> because of fpsimd trap. In some benchmarks, like lat_ctx and lat_udp, one asid usually got stuck
> and scheduled to another, where context switch and handling fpsimd happened very frequently.
> In my performance test, lat_ctx with 4 asid switch. In comparison between guest and host, 
> without this, guest is 10% worse than host. With this, guest is only 8% worse than host.
> 
> Detect guest using fpsimd based on lazy fpsimd switch may be not 100% correct. 
> I think accurate detection may be overtraining and is not suitable for common cases.
> Therefore I just do it in simply way to reduce some fpsimd traps.

Can you please with Dave's series (which I have now merged for 4.18)
and let us know if you're still seeing this overhead? If you're still
seeing it, we can then look into it.

Thanks,

	M.
-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply

* [PATCH 2/3] drm/rockchip: lvds: avoid duplicating drm_bridge_attach
From: Heiko Stuebner @ 2018-05-20 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180502074025.12421-3-peda@axentia.se>

Am Mittwoch, 2. Mai 2018, 09:40:24 CEST schrieb Peter Rosin:
> drm_bridge_attach takes care of these assignments, so there is no need
> to open-code them a second time.
> 
> Signed-off-by: Peter Rosin <peda@axentia.se>

applied to drm-misc-next


Thanks
Heiko

^ permalink raw reply

* [arm:zii 12/20] net/dsa/slave.c:1169:2: warning: initialization from incompatible pointer type
From: kbuild test robot @ 2018-05-20 12:02 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git zii
head:   58e9ee3ee4dd4574170181ed8751766e234a33a8
commit: 94d9d1358684609c19eceb53aae76f40435b69dc [12/20] net: dsa: Plug in PHYLINK support
config: i386-randconfig-b0-05201752 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        git checkout 94d9d1358684609c19eceb53aae76f40435b69dc
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   net/dsa/slave.c: In function 'dsa_slave_get_module_info':
   net/dsa/slave.c:550:2: error: implicit declaration of function 'phylink_ethtool_get_module_info' [-Werror=implicit-function-declaration]
     return phylink_ethtool_get_module_info(dp->pl, modinfo);
     ^
   net/dsa/slave.c: In function 'dsa_slave_get_module_eeprom':
   net/dsa/slave.c:558:2: error: implicit declaration of function 'phylink_ethtool_get_module_eeprom' [-Werror=implicit-function-declaration]
     return phylink_ethtool_get_module_eeprom(dp->pl, ee, buf);
     ^
   net/dsa/slave.c: At top level:
>> net/dsa/slave.c:1169:2: warning: initialization from incompatible pointer type
     .mac_link_down = dsa_slave_phylink_mac_link_down,
     ^
   net/dsa/slave.c:1169:2: warning: (near initialization for 'dsa_slave_phylink_mac_ops.mac_link_down')
   net/dsa/slave.c:1170:2: warning: initialization from incompatible pointer type
     .mac_link_up = dsa_slave_phylink_mac_link_up,
     ^
   net/dsa/slave.c:1170:2: warning: (near initialization for 'dsa_slave_phylink_mac_ops.mac_link_up')
   Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls
   Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32
   Cyclomatic Complexity 2 arch/x86/include/asm/jump_label.h:arch_static_branch
   Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
   Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
   Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
   Cyclomatic Complexity 2 include/linux/list.h:__list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
   Cyclomatic Complexity 1 include/linux/list.h:__list_del
   Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
   Cyclomatic Complexity 1 include/linux/list.h:list_del
   Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_irq_disable
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_irq_enable
   Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR
   Cyclomatic Complexity 2 include/linux/notifier.h:notifier_from_errno
   Cyclomatic Complexity 1 include/linux/slab.h:kmalloc_order_trace
   Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large
   Cyclomatic Complexity 3 include/linux/slab.h:kmalloc
   Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
   Cyclomatic Complexity 1 include/linux/skbuff.h:skb_is_nonlinear
   Cyclomatic Complexity 1 include/linux/skbuff.h:skb_tail_pointer
   Cyclomatic Complexity 2 include/linux/skbuff.h:skb_tailroom
   Cyclomatic Complexity 1 include/linux/u64_stats_sync.h:u64_stats_init
   Cyclomatic Complexity 1 include/linux/u64_stats_sync.h:u64_stats_update_begin
   Cyclomatic Complexity 1 include/linux/u64_stats_sync.h:u64_stats_update_end
   Cyclomatic Complexity 1 include/linux/u64_stats_sync.h:__u64_stats_fetch_begin
   Cyclomatic Complexity 1 include/linux/u64_stats_sync.h:__u64_stats_fetch_retry
   Cyclomatic Complexity 2 include/linux/netdevice.h:netdev_for_each_tx_queue
   Cyclomatic Complexity 1 include/linux/netdevice.h:netdev_priv
   Cyclomatic Complexity 1 include/linux/netdevice.h:netdev_notifier_info_to_dev
   Cyclomatic Complexity 1 include/linux/netdevice.h:dev_put
   Cyclomatic Complexity 1 include/linux/netdevice.h:dev_hold
   Cyclomatic Complexity 1 include/linux/netdevice.h:netif_is_bridge_master
   Cyclomatic Complexity 1 include/linux/etherdevice.h:is_zero_ether_addr
   Cyclomatic Complexity 1 include/linux/etherdevice.h:is_multicast_ether_addr
   Cyclomatic Complexity 3 include/linux/etherdevice.h:is_valid_ether_addr
   Cyclomatic Complexity 1 include/linux/etherdevice.h:ether_addr_copy
   Cyclomatic Complexity 1 include/linux/etherdevice.h:eth_hw_addr_inherit
   Cyclomatic Complexity 1 include/linux/etherdevice.h:ether_addr_equal
   Cyclomatic Complexity 1 include/net/netlink.h:nlmsg_msg_size
   Cyclomatic Complexity 1 include/net/netlink.h:nlmsg_total_size
   Cyclomatic Complexity 1 include/net/netlink.h:nlmsg_data
   Cyclomatic Complexity 1 include/net/netlink.h:nlmsg_end
   Cyclomatic Complexity 2 include/net/pkt_cls.h:tcf_exts_to_list
   Cyclomatic Complexity 1 include/net/pkt_cls.h:tcf_exts_has_one_action
   Cyclomatic Complexity 1 include/net/pkt_cls.h:tc_can_offload
   Cyclomatic Complexity 3 include/net/tc_act/tc_mirred.h:is_tcf_mirred_egress_mirror
   Cyclomatic Complexity 1 include/linux/netpoll.h:netpoll_tx_running
   Cyclomatic Complexity 1 include/net/switchdev.h:switchdev_notifier_info_to_dev
   Cyclomatic Complexity 1 include/net/dsa.h:dsa_to_port
   Cyclomatic Complexity 1 net/dsa/dsa_priv.h:dsa_slave_to_port
   Cyclomatic Complexity 1 net/dsa/dsa_priv.h:dsa_slave_to_master
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phy_read
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phy_write
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_slave_get_iflink
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_regs_len
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_regs
   Cyclomatic Complexity 4 net/dsa/slave.c:dsa_slave_get_eeprom_len
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_eeprom
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_set_eeprom
   Cyclomatic Complexity 3 net/dsa/slave.c:dsa_slave_get_sset_count
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_rxnfc
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_set_rxnfc
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_ts_info
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phylink_validate
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phylink_mac_link_state
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phylink_mac_config
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phylink_mac_an_restart
   Cyclomatic Complexity 4 net/dsa/slave.c:dsa_slave_phylink_mac_link_down
   Cyclomatic Complexity 4 net/dsa/slave.c:dsa_slave_phylink_mac_link_up
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_phylink_fixed_state
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_slave_dev_check
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_get_phys_port_name
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_legacy_fdb_add
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_legacy_fdb_del
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_slave_set_lockdep_class_one
   Cyclomatic Complexity 4 net/dsa/slave.c:dsa_slave_port_attr_set
   Cyclomatic Complexity 3 net/dsa/slave.c:dsa_slave_port_attr_get
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_switchdev_fdb_work_init
   Cyclomatic Complexity 7 net/dsa/slave.c:dsa_slave_port_obj_add
   Cyclomatic Complexity 7 net/dsa/slave.c:dsa_slave_port_obj_del
   Cyclomatic Complexity 1 include/linux/err.h:IS_ERR
   Cyclomatic Complexity 5 net/dsa/slave.c:dsa_skb_tx_timestamp
   Cyclomatic Complexity 0 net/dsa/slave.c:dsa_slave_netpoll_send_skb
   Cyclomatic Complexity 2 net/dsa/slave.c:dsa_slave_xmit
   Cyclomatic Complexity 1 net/dsa/slave.c:dsa_slave_fdb_dump
   Cyclomatic Complexity 1 include/net/netlink.h:nla_put_u16
   Cyclomatic Complexity 2 include/net/netlink.h:nlmsg_put
   Cyclomatic Complexity 3 include/net/netlink.h:nlmsg_trim
   Cyclomatic Complexity 1 include/net/netlink.h:nlmsg_cancel
   Cyclomatic Complexity 7 net/dsa/slave.c:dsa_slave_port_fdb_do_dump

vim +1169 net/dsa/slave.c

  1163	
  1164	static const struct phylink_mac_ops dsa_slave_phylink_mac_ops = {
  1165		.validate = dsa_slave_phylink_validate,
  1166		.mac_link_state = dsa_slave_phylink_mac_link_state,
  1167		.mac_config = dsa_slave_phylink_mac_config,
  1168		.mac_an_restart = dsa_slave_phylink_mac_an_restart,
> 1169		.mac_link_down = dsa_slave_phylink_mac_link_down,
  1170		.mac_link_up = dsa_slave_phylink_mac_link_up,
  1171	};
  1172	

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

^ permalink raw reply

* [PATCH] arm64: kdump: fix out of memory issue in __alloc_bootmem_low
From: Chen Zhou @ 2018-05-20 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mao Wenan <maowenan@huawei.com>

On arm64 kdump capture kernel, ACPI runtime code and data are outside
of usable memory range and __alloc_bootmem_low may alloc memory below
4G. If we use "crashkernel=Y[@X]" and the start address is above 4G,
there will be out of memory.

In this patch, we get max_zone_dma_phys by memblock_start_of_DRAM
and __pa_symbol(_end).

Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
---
 arch/arm64/mm/init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 1b18b47..df4d212 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -223,7 +223,8 @@ static void __init reserve_elfcorehdr(void)
  */
 static phys_addr_t __init max_zone_dma_phys(void)
 {
-	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
+	phys_addr_t offset = max(memblock_start_of_DRAM(), __pa_symbol(_end)) &
+		GENMASK_ULL(63, 32);
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
-- 
1.8.3

^ permalink raw reply related

* [PATCH v2] ARM: dts: imx6/7: Remove unit-address from anatop regulators
From: Shawn Guo @ 2018-05-20 12:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526304714-23821-1-git-send-email-festevam@gmail.com>

On Mon, May 14, 2018 at 10:31:54AM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@nxp.com>
> 
> Remove unit-address and reg property from anatop regulators to fix
> the following DTC warnings with W=1:
> 
> arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddcore at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddpu at 20c8140)
> arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddcore at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddsoc at 20c8140)
> arch/arm/boot/dts/imx6dl-apf6dev.dtb: Warning (unique_unit_address): /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddpu at 20c8140: duplicate unit-address (also used in node /soc/aips-bus at 2000000/anatop at 20c8000/regulator-vddsoc at 20c8140)
> 
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>

Applied, thanks.

^ permalink raw reply

* [PATCH 1/2] rtc: st-lpc: fix possible race condition
From: Alexandre Belloni @ 2018-05-20 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

The IRQ is requested before the struct rtc is allocated and registered, but
this struct is used in the IRQ handler. This may lead to a NULL pointer
dereference.

Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc
before requesting the IRQ.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-st-lpc.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index d5222667f892..2f1ef2c28740 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -212,6 +212,10 @@ static int st_rtc_probe(struct platform_device *pdev)
 	if (!rtc)
 		return -ENOMEM;
 
+	rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+	if (IS_ERR(rtc->rtc_dev))
+		return PTR_ERR(rtc->rtc_dev);
+
 	spin_lock_init(&rtc->lock);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -253,26 +257,17 @@ static int st_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, rtc);
 
-	rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev,
-					   &st_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
+	rtc->rtc_dev->ops = &st_rtc_ops;
+
+	ret = rtc_register_device(rtc->rtc_dev);
+	if (ret) {
 		clk_disable_unprepare(rtc->clk);
-		return PTR_ERR(rtc->rtc_dev);
+		return ret;
 	}
 
 	return 0;
 }
 
-static int st_rtc_remove(struct platform_device *pdev)
-{
-	struct st_rtc *rtc = platform_get_drvdata(pdev);
-
-	if (likely(rtc->rtc_dev))
-		rtc_device_unregister(rtc->rtc_dev);
-
-	return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int st_rtc_suspend(struct device *dev)
 {
@@ -325,7 +320,6 @@ static struct platform_driver st_rtc_platform_driver = {
 		.of_match_table = st_rtc_match,
 	},
 	.probe = st_rtc_probe,
-	.remove = st_rtc_remove,
 };
 
 module_platform_driver(st_rtc_platform_driver);
-- 
2.17.0

^ permalink raw reply related

* [PATCH 2/2] rtc: st-lpc: add range
From: Alexandre Belloni @ 2018-05-20 12:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520123337.14856-1-alexandre.belloni@bootlin.com>

The RTC has a 64 bit counter.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-st-lpc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 2f1ef2c28740..df467ace397b 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -258,6 +258,7 @@ static int st_rtc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev->ops = &st_rtc_ops;
+	rtc->range_max = do_div(U64_MAX, rtc->clkrate);
 
 	ret = rtc_register_device(rtc->rtc_dev);
 	if (ret) {
-- 
2.17.0

^ permalink raw reply related

* [PATCH] ARM: dts: imx51-zii-rdu1: limit usbh1 to full-speed
From: Shawn Guo @ 2018-05-20 12:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180515084502.17148-1-nikita.yoush@cogentembedded.com>

On Tue, May 15, 2018 at 11:45:02AM +0300, Nikita Yushchenko wrote:
> On RDU1, imx51 usbh1 interface is either not used, or used via external
> block that breaks USB2 signalling.
> 
> To keep things working if high-speed device gets connected to that
> block, use ChipIdea feature to limit port to full speed.
> 
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>

Applied, thanks.

^ permalink raw reply

* [PATCH V2] ARM: dts: imx7d: correct cpu supply name for voltage scaling
From: Shawn Guo @ 2018-05-20 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526437548-32372-1-git-send-email-Anson.Huang@nxp.com>

On Wed, May 16, 2018 at 10:25:48AM +0800, Anson Huang wrote:
> Correct CPU supply name to meet cpufreq-dt driver's
> requirement for voltage scaling.
> 
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

Applied, thanks.

^ permalink raw reply


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