All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Add the Renesas USBF controller support
@ 2022-11-14 11:15 Herve Codina
  2022-11-14 11:15 ` [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role Herve Codina
                   ` (6 more replies)
  0 siblings, 7 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Hi,

This series add support for the Renesas USBF controller (USB Device
Controller) available in the Renesas RZ/N1 SoC.

The first three patches are related to the H2MODE bit from CFG_USB
register. This register is managed by the Renesas sysctrl driver.
The H2MODE bit allows to configure the internal USB Port interface
for two hosts or one host and one device.

The next patches are related to the USBF controller with a new
binding definition, the driver itself and myself as a maintainer
of this controller.

Best regards,
Herve Codina

Changes v1 -> v2:
  - Patch 1:
    Rename r9a06g032_sysctrl_get_usb_h2mode to r9a06g032_sysctrl_get_usb_role
    and return USB_ROLE_{HOST,DEVICE} or an error code.
    Reword commit log

  - Patches 2 and 3:
    No changes. Some previous feedbacks still need to be taken into account
      https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
      https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/

  - Patch 4:
    Rename file from renesas,usbf.yaml to renesas,rzn1-usbf.yaml.
    Remove 'oneOf'.
    Add blank line and line break.
    Add 'power-domains'.
    Reword commit log

  - Patch 5:
    Remove clocks handling (handled by runtime PM through the clock domain
    pointed by power-domains).
    Fix compilation warning raised by the 'kernel test robot'.

  - Patch 6:
    Add 'power-domains'

  - Patch 7:
    Add 'Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>'

Herve Codina (7):
  soc: renesas: r9a06g032-sysctrl: Export function to get the usb role
  dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property
  dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding
  usb: gadget: udc: add Renesas RZ/N1 USBF controller support
  ARM: dts: r9a06g032: Add the USBF controller node
  MAINTAINERS: add the Renesas RZ/N1 USBF controller entry

 .../clock/renesas,r9a06g032-sysctrl.yaml      |   10 +
 .../bindings/usb/renesas,rzn1-usbf.yaml       |   68 +
 MAINTAINERS                                   |    8 +
 arch/arm/boot/dts/r9a06g032.dtsi              |   12 +
 drivers/clk/renesas/r9a06g032-clocks.c        |   39 +
 drivers/usb/gadget/udc/Kconfig                |   11 +
 drivers/usb/gadget/udc/Makefile               |    1 +
 drivers/usb/gadget/udc/renesas_usbf.c         | 3430 +++++++++++++++++
 include/linux/soc/renesas/r9a06g032-sysctrl.h |    2 +
 9 files changed, 3581 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
 create mode 100644 drivers/usb/gadget/udc/renesas_usbf.c

-- 
2.38.1


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-14 13:33   ` Geert Uytterhoeven
  2022-11-14 11:15 ` [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property Herve Codina
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

The usb role retrieved is determined from the CFG_USB[H2MODE]
value. The CFG_USB register is located within the system
controller.

We need a helper to get the usb role based on H2MODE value from
the CFG_USB register without syscon.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/clk/renesas/r9a06g032-clocks.c        | 18 ++++++++++++++++++
 include/linux/soc/renesas/r9a06g032-sysctrl.h |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index 1488c9d6e639..9ee056498714 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -23,8 +23,11 @@
 #include <linux/slab.h>
 #include <linux/soc/renesas/r9a06g032-sysctrl.h>
 #include <linux/spinlock.h>
+#include <linux/usb/role.h>
 #include <dt-bindings/clock/r9a06g032-sysctrl.h>
 
+#define R9A06G032_SYSCTRL_USB    0x00
+#define R9A06G032_SYSCTRL_USB_H2MODE  (1<<1)
 #define R9A06G032_SYSCTRL_DMAMUX 0xA0
 
 struct r9a06g032_gate {
@@ -341,6 +344,21 @@ int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val)
 }
 EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_set_dmamux);
 
+
+/* Exported helper to get the H2MODE bit from USB register */
+int r9a06g032_sysctrl_get_usb_role(void)
+{
+	u32 usb;
+
+	if (!sysctrl_priv)
+		return -EPROBE_DEFER;
+
+	usb = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_USB);
+	return (usb & R9A06G032_SYSCTRL_USB_H2MODE) ?
+		USB_ROLE_HOST : USB_ROLE_DEVICE;
+}
+EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_get_usb_role);
+
 /* register/bit pairs are encoded as an uint16_t */
 static void
 clk_rdesc_set(struct r9a06g032_priv *clocks,
diff --git a/include/linux/soc/renesas/r9a06g032-sysctrl.h b/include/linux/soc/renesas/r9a06g032-sysctrl.h
index 066dfb15cbdd..fc18d013a498 100644
--- a/include/linux/soc/renesas/r9a06g032-sysctrl.h
+++ b/include/linux/soc/renesas/r9a06g032-sysctrl.h
@@ -4,8 +4,10 @@
 
 #ifdef CONFIG_CLK_R9A06G032
 int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val);
+int r9a06g032_sysctrl_get_usb_role(void);
 #else
 static inline int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) { return -ENODEV; }
+static inline int r9a06g032_sysctrl_get_usb_role(void) { return -ENODEV; }
 #endif
 
 #endif /* __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ */
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
  2022-11-14 11:15 ` [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-14 13:33   ` Geert Uytterhoeven
  2022-11-15 13:05   ` Krzysztof Kozlowski
  2022-11-14 11:15 ` [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property Herve Codina
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Add the h2mode property to force the USBs mode ie:
 - 2 hosts
or
 - 1 host and 1 device

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
index 95bf485c6cec..f9e0a58aa4fb 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
@@ -39,6 +39,16 @@ properties:
   '#power-domain-cells':
     const: 0
 
+  renesas,h2mode:
+    description: |
+      Configure the USBs mode.
+        - <0> : the USBs are in 1 host and 1 device mode.
+        - <1> : the USBs are in 2 host mode.
+      If the property is not present, the value used is the one already present
+      in the CFG_USB register (from reset or set by the bootloader).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1]
+
   '#address-cells':
     const: 1
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
  2022-11-14 11:15 ` [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role Herve Codina
  2022-11-14 11:15 ` [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-14 13:32   ` Geert Uytterhoeven
  2022-11-14 11:15 ` [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding Herve Codina
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Handle the h2mode property and forces the CFG_USB[H2MODE] bit
accordingly.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/clk/renesas/r9a06g032-clocks.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index 9ee056498714..7a5a96c0d082 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -946,6 +946,7 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
 	struct clk *mclk;
 	unsigned int i;
 	u16 uart_group_sel[2];
+	u32 usb, h2mode;
 	int error;
 
 	clocks = devm_kzalloc(dev, sizeof(*clocks), GFP_KERNEL);
@@ -966,6 +967,26 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
 	clocks->reg = of_iomap(np, 0);
 	if (WARN_ON(!clocks->reg))
 		return -ENOMEM;
+
+	error = of_property_read_u32(np, "renesas,h2mode", &h2mode);
+	if (!error) {
+		usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB);
+		switch (h2mode) {
+		case 0:
+			/* 1 host, 1 device */
+			usb &= ~R9A06G032_SYSCTRL_USB_H2MODE;
+			break;
+		case 1:
+			/* 2 hosts */
+			usb |= R9A06G032_SYSCTRL_USB_H2MODE;
+			break;
+		default:
+			dev_err(dev, "invalid h2mode %d\n", h2mode);
+			return -EINVAL;
+		}
+		writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB);
+	}
+
 	for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) {
 		const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i];
 		const char *parent_name = d->source ?
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
                   ` (2 preceding siblings ...)
  2022-11-14 11:15 ` [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-15 13:13   ` Krzysztof Kozlowski
  2022-11-14 11:15 ` [PATCH v2 5/7] usb: gadget: udc: add Renesas RZ/N1 USBF controller support Herve Codina
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

The Renesas RZ/N1 USBF controller is an USB2.0 device controller
(UDC) available in the Renesas r9a06g032 SoC (RZ/N1 family).

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 .../bindings/usb/renesas,rzn1-usbf.yaml       | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml

diff --git a/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
new file mode 100644
index 000000000000..b67e9cea2522
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/renesas,rzn1-usbf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/N1 SoCs USBF (USB Function) controller binding
+
+description: |
+   The Renesas USBF controller is an USB2.0 device
+   controller (UDC).
+
+maintainers:
+  - Herve Codina <herve.codina@bootlin.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a06g032-usbf
+      - const: renesas,rzn1-usbf
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Internal bus clock (AHB) for Function
+      - description: Internal bus clock (AHB) for Power Management
+
+  clock-names:
+    items:
+      - const: hclkf
+      - const: hclkpm
+
+  power-domains:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: The USBF EPC interrupt
+      - description: The USBF AHB-EPC interrupt
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - power-domains
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/r9a06g032-sysctrl.h>
+
+    usb@4001e000 {
+        compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
+        reg = <0x4001e000 0x2000>;
+        interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&sysctrl R9A06G032_HCLK_USBF>,
+                 <&sysctrl R9A06G032_HCLK_USBPM>;
+        clock-names = "hclkf", "hclkpm";
+        power-domains = <&sysctrl>;
+    };
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 5/7] usb: gadget: udc: add Renesas RZ/N1 USBF controller support
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
                   ` (3 preceding siblings ...)
  2022-11-14 11:15 ` [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-14 11:15 ` [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node Herve Codina
  2022-11-14 11:15 ` [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry Herve Codina
  6 siblings, 0 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Add support for the Renesas USBF controller.
This controller is an USB2.0 UDC controller available in the
Renesas r9a06g032 SoC (RZ/N1 family).

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/usb/gadget/udc/Kconfig        |   11 +
 drivers/usb/gadget/udc/Makefile       |    1 +
 drivers/usb/gadget/udc/renesas_usbf.c | 3430 +++++++++++++++++++++++++
 3 files changed, 3442 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/renesas_usbf.c

diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 5756acb07b8d..f856d2c61603 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -204,6 +204,17 @@ config USB_RENESAS_USB3
 	   dynamically linked module called "renesas_usb3" and force all
 	   gadget drivers to also be dynamically linked.
 
+config USB_RENESAS_USBF
+	tristate 'Renesas USB Function controller'
+	depends on ARCH_RENESAS || COMPILE_TEST
+	help
+	   Renesas USB Function controller is a USB peripheral controller
+	   available on RZ/N1 Renesas SoCs.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "renesas_usbf" and force all
+	   gadget drivers to also be dynamically linked.
+
 config USB_PXA27X
 	tristate "PXA 27x"
 	depends on HAS_IOMEM
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 12f9e4c9eb0c..99a2221c0f8b 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_USB_TEGRA_XUDC)	+= tegra-xudc.o
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
 obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
 obj-$(CONFIG_USB_RENESAS_USB3)	+= renesas_usb3.o
+obj-$(CONFIG_USB_RENESAS_USBF)	+= renesas_usbf.o
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 obj-$(CONFIG_USB_S3C_HSUDC)	+= s3c-hsudc.o
 obj-$(CONFIG_USB_LPC32XX)	+= lpc32xx_udc.o
diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c
new file mode 100644
index 000000000000..d43ed6626e8e
--- /dev/null
+++ b/drivers/usb/gadget/udc/renesas_usbf.c
@@ -0,0 +1,3430 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas USBF USB Function driver
+ *
+ * Copyright 2022 Schneider Electric
+ * Author: Herve Codina <herve.codina@bootlin.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/soc/renesas/r9a06g032-sysctrl.h>
+#include <linux/types.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/role.h>
+
+#ifdef DEBUG
+#define TRACE(_fmt, ...) trace_printk("%s: " _fmt, __func__, ##__VA_ARGS__)
+#define USBF_TRACE_EP_MASK 0x0ffff /* All the 16 endpoints */
+#define TRACEEP(_ep, _fmt, ...)                                             \
+	do {                                                                \
+		if ((1 << (_ep)->id) & USBF_TRACE_EP_MASK)                  \
+			trace_printk("%s: " _fmt, __func__, ##__VA_ARGS__); \
+	} while (0)
+#else
+#define TRACE(_fmt, ...) do { } while (0)
+#define TRACEEP(_ep, _fmt, ...) do { } while (0)
+#endif
+
+#define USBF_NUM_ENDPOINTS	16
+#define USBF_EP0_MAX_PCKT_SIZE	64
+
+/* EPC registers */
+#define USBF_REG_USB_CONTROL	0x000
+#define     USBF_USB_PUE2		BIT(2)
+#define     USBF_USB_CONNECTB		BIT(3)
+#define     USBF_USB_DEFAULT		BIT(4)
+#define     USBF_USB_CONF		BIT(5)
+#define     USBF_USB_SUSPEND		BIT(6)
+#define     USBF_USB_RSUM_IN		BIT(7)
+#define     USBF_USB_SOF_RCV		BIT(8)
+#define     USBF_USB_FORCEFS		BIT(9)
+#define     USBF_USB_INT_SEL		BIT(10)
+#define     USBF_USB_SOF_CLK_MODE	BIT(11)
+
+#define USBF_REG_USB_STATUS	0x004
+#define     USBF_USB_RSUM_OUT		BIT(1)
+#define     USBF_USB_SPND_OUT		BIT(2)
+#define     USBF_USB_USB_RST		BIT(3)
+#define     USBF_USB_DEFAULT_ST		BIT(4)
+#define     USBF_USB_CONF_ST		BIT(5)
+#define     USBF_USB_SPEED_MODE		BIT(6)
+#define     USBF_USB_SOF_DELAY_STATUS	BIT(31)
+
+#define USBF_REG_USB_ADDRESS	0x008
+#define     USBF_USB_SOF_STATUS		BIT(15)
+#define     USBF_USB_SET_USB_ADDR(_a)	((_a) << 16)
+#define     USBF_USB_GET_FRAME(_r)	((_r) & 0x7FF)
+
+#define USBF_REG_SETUP_DATA0	0x018
+#define USBF_REG_SETUP_DATA1	0x01C
+#define USBF_REG_USB_INT_STA	0x020
+#define     USBF_USB_RSUM_INT		BIT(1)
+#define     USBF_USB_SPND_INT		BIT(2)
+#define     USBF_USB_USB_RST_INT	BIT(3)
+#define     USBF_USB_SOF_INT		BIT(4)
+#define     USBF_USB_SOF_ERROR_INT	BIT(5)
+#define     USBF_USB_SPEED_MODE_INT	BIT(6)
+#define     USBF_USB_EPN_INT(_n)	(BIT(8) << (_n)) /* n=0..15 */
+
+#define USBF_REG_USB_INT_ENA	0x024
+#define     USBF_USB_RSUM_EN		BIT(1)
+#define     USBF_USB_SPND_EN		BIT(2)
+#define     USBF_USB_USB_RST_EN		BIT(3)
+#define     USBF_USB_SOF_EN		BIT(4)
+#define     USBF_USB_SOF_ERROR_EN	BIT(5)
+#define     USBF_USB_SPEED_MODE_EN	BIT(6)
+#define     USBF_USB_EPN_EN(_n)		(BIT(8) << (_n)) /* n=0..15 */
+
+#define USBF_BASE_EP0		0x028
+/* EP0 registers offsets from Base + USBF_BASE_EP0 (EP0 regs area) */
+#define     USBF_REG_EP0_CONTROL	0x00
+#define         USBF_EP0_ONAK			BIT(0)
+#define         USBF_EP0_INAK			BIT(1)
+#define         USBF_EP0_STL			BIT(2)
+#define         USBF_EP0_PERR_NAK_CLR		BIT(3)
+#define         USBF_EP0_INAK_EN		BIT(4)
+#define         USBF_EP0_DW_MASK		(0x3 << 5)
+#define         USBF_EP0_DW(_s)			((_s) << 5)
+#define         USBF_EP0_DEND			BIT(7)
+#define         USBF_EP0_BCLR			BIT(8)
+#define         USBF_EP0_PIDCLR			BIT(9)
+#define         USBF_EP0_AUTO			BIT(16)
+#define         USBF_EP0_OVERSEL		BIT(17)
+#define         USBF_EP0_STGSEL			BIT(18)
+
+#define     USBF_REG_EP0_STATUS		0x04
+#define         USBF_EP0_SETUP_INT		BIT(0)
+#define         USBF_EP0_STG_START_INT		BIT(1)
+#define         USBF_EP0_STG_END_INT		BIT(2)
+#define         USBF_EP0_STALL_INT		BIT(3)
+#define         USBF_EP0_IN_INT			BIT(4)
+#define         USBF_EP0_OUT_INT		BIT(5)
+#define         USBF_EP0_OUT_OR_INT		BIT(6)
+#define         USBF_EP0_OUT_NULL_INT		BIT(7)
+#define         USBF_EP0_IN_EMPTY		BIT(8)
+#define         USBF_EP0_IN_FULL		BIT(9)
+#define         USBF_EP0_IN_DATA		BIT(10)
+#define         USBF_EP0_IN_NAK_INT		BIT(11)
+#define         USBF_EP0_OUT_EMPTY		BIT(12)
+#define         USBF_EP0_OUT_FULL		BIT(13)
+#define         USBF_EP0_OUT_NULL		BIT(14)
+#define         USBF_EP0_OUT_NAK_INT		BIT(15)
+#define         USBF_EP0_PERR_NAK_INT		BIT(16)
+#define         USBF_EP0_PERR_NAK		BIT(17)
+#define         USBF_EP0_PID			BIT(18)
+
+#define     USBF_REG_EP0_INT_ENA	0x08
+#define         USBF_EP0_SETUP_EN		BIT(0)
+#define         USBF_EP0_STG_START_EN		BIT(1)
+#define         USBF_EP0_STG_END_EN		BIT(2)
+#define         USBF_EP0_STALL_EN		BIT(3)
+#define         USBF_EP0_IN_EN			BIT(4)
+#define         USBF_EP0_OUT_EN			BIT(5)
+#define         USBF_EP0_OUT_OR_EN		BIT(6)
+#define         USBF_EP0_OUT_NULL_EN		BIT(7)
+#define         USBF_EP0_IN_NAK_EN		BIT(11)
+#define         USBF_EP0_OUT_NAK_EN		BIT(15)
+#define         USBF_EP0_PERR_NAK_EN		BIT(16)
+
+#define     USBF_REG_EP0_LENGTH		0x0C
+#define         USBF_EP0_LDATA			(0x7FF << 0)
+#define     USBF_REG_EP0_READ		0x10
+#define     USBF_REG_EP0_WRITE		0x14
+
+#define USBF_BASE_EPN(_n)	(0x040 + (_n) * 0x020)
+/* EPn registers offsets from Base + USBF_BASE_EPN(n-1). n=1..15 */
+#define     USBF_REG_EPN_CONTROL	0x000
+#define         USBF_EPN_ONAK			BIT(0)
+#define         USBF_EPN_OSTL			BIT(2)
+#define         USBF_EPN_ISTL			BIT(3)
+#define         USBF_EPN_OSTL_EN		BIT(4)
+#define         USBF_EPN_DW_MASK		(0x3 << 5)
+#define         USBF_EPN_DW(_s)			((_s) << 5)
+#define         USBF_EPN_DEND			BIT(7)
+#define         USBF_EPN_CBCLR			BIT(8)
+#define         USBF_EPN_BCLR			BIT(9)
+#define         USBF_EPN_OPIDCLR		BIT(10)
+#define         USBF_EPN_IPIDCLR		BIT(11)
+#define         USBF_EPN_AUTO			BIT(16)
+#define         USBF_EPN_OVERSEL		BIT(17)
+#define         USBF_EPN_MODE_MASK		(0x3 << 24)
+#define         USBF_EPN_MODE_BULK		(0x0 << 24)
+#define         USBF_EPN_MODE_INTR		(0x1 << 24)
+#define         USBF_EPN_MODE_ISO		(0x2 << 24)
+#define         USBF_EPN_DIR0			BIT(26)
+#define         USBF_EPN_BUF_TYPE_DOUBLE	BIT(30)
+#define         USBF_EPN_EN			BIT(31)
+
+#define     USBF_REG_EPN_STATUS		0x004
+#define         USBF_EPN_IN_EMPTY		BIT(0)
+#define         USBF_EPN_IN_FULL		BIT(1)
+#define         USBF_EPN_IN_DATA		BIT(2)
+#define         USBF_EPN_IN_INT			BIT(3)
+#define         USBF_EPN_IN_STALL_INT		BIT(4)
+#define         USBF_EPN_IN_NAK_ERR_INT		BIT(5)
+#define         USBF_EPN_IN_END_INT		BIT(7)
+#define         USBF_EPN_IPID			BIT(10)
+#define         USBF_EPN_OUT_EMPTY		BIT(16)
+#define         USBF_EPN_OUT_FULL		BIT(17)
+#define         USBF_EPN_OUT_NULL_INT		BIT(18)
+#define         USBF_EPN_OUT_INT		BIT(19)
+#define         USBF_EPN_OUT_STALL_INT		BIT(20)
+#define         USBF_EPN_OUT_NAK_ERR_INT	BIT(21)
+#define         USBF_EPN_OUT_OR_INT		BIT(22)
+#define         USBF_EPN_OUT_END_INT		BIT(23)
+#define         USBF_EPN_ISO_CRC		BIT(24)
+#define         USBF_EPN_ISO_OR			BIT(26)
+#define         USBF_EPN_OUT_NOTKN		BIT(27)
+#define         USBF_EPN_ISO_OPID		BIT(28)
+#define         USBF_EPN_ISO_PIDERR		BIT(29)
+
+#define     USBF_REG_EPN_INT_ENA	0x008
+#define         USBF_EPN_IN_EN			BIT(3)
+#define         USBF_EPN_IN_STALL_EN		BIT(4)
+#define         USBF_EPN_IN_NAK_ERR_EN		BIT(5)
+#define         USBF_EPN_IN_END_EN		BIT(7)
+#define         USBF_EPN_OUT_NULL_EN		BIT(18)
+#define         USBF_EPN_OUT_EN			BIT(19)
+#define         USBF_EPN_OUT_STALL_EN		BIT(20)
+#define         USBF_EPN_OUT_NAK_ERR_EN		BIT(21)
+#define         USBF_EPN_OUT_OR_EN		BIT(22)
+#define         USBF_EPN_OUT_END_EN		BIT(23)
+
+#define     USBF_REG_EPN_DMA_CTRL	0x00C
+#define         USBF_EPN_DMAMODE0		BIT(0)
+#define         USBF_EPN_DMA_EN			BIT(4)
+#define         USBF_EPN_STOP_SET		BIT(8)
+#define         USBF_EPN_BURST_SET		BIT(9)
+#define         USBF_EPN_DEND_SET		BIT(10)
+#define         USBF_EPN_STOP_MODE		BIT(11)
+
+#define     USBF_REG_EPN_PCKT_ADRS	0x010
+#define         USBF_EPN_MPKT(_l)		((_l) << 0)
+#define         USBF_EPN_BASEAD(_a)		((_a) << 16)
+
+#define     USBF_REG_EPN_LEN_DCNT	0x014
+#define         USBF_EPN_GET_LDATA(_r)		((_r) & 0x7FF)
+#define         USBF_EPN_SET_DMACNT(_c)		((_c) << 16)
+#define         USBF_EPN_GET_DMACNT(_r)		(((_r) >> 16) & 0x1ff)
+
+#define     USBF_REG_EPN_READ		0x018
+#define     USBF_REG_EPN_WRITE		0x01C
+
+/* AHB-EPC Bridge registers */
+#define USBF_REG_AHBSCTR	0x1000
+#define USBF_REG_AHBMCTR	0x1004
+#define     USBF_SYS_WBURST_TYPE	BIT(2)
+#define     USBF_SYS_ARBITER_CTR	BIT(31)
+
+#define USBF_REG_AHBBINT	0x1008
+#define     USBF_SYS_ERR_MASTER		 (0x0F << 0)
+#define     USBF_SYS_SBUS_ERRINT0	 BIT(4)
+#define     USBF_SYS_SBUS_ERRINT1	 BIT(5)
+#define     USBF_SYS_MBUS_ERRINT	 BIT(6)
+#define     USBF_SYS_VBUS_INT		 BIT(13)
+#define     USBF_SYS_DMA_ENDINT_EPN(_n)	 (BIT(16) << (_n)) /* _n=1..15 */
+
+#define USBF_REG_AHBBINTEN	0x100C
+#define     USBF_SYS_SBUS_ERRINT0EN	  BIT(4)
+#define     USBF_SYS_SBUS_ERRINT1EN	  BIT(5)
+#define     USBF_SYS_MBUS_ERRINTEN	  BIT(6)
+#define     USBF_SYS_VBUS_INTEN		  BIT(13)
+#define     USBF_SYS_DMA_ENDINTEN_EPN(_n) (BIT(16) << (_n)) /* _n=1..15 */
+
+#define USBF_REG_EPCTR		0x1010
+#define     USBF_SYS_EPC_RST		BIT(0)
+#define     USBF_SYS_PLL_RST		BIT(2)
+#define     USBF_SYS_PLL_LOCK		BIT(4)
+#define     USBF_SYS_PLL_RESUME		BIT(5)
+#define     USBF_SYS_VBUS_LEVEL		BIT(8)
+#define     USBF_SYS_DIRPD		BIT(12)
+
+#define USBF_REG_USBSSVER	0x1020
+#define USBF_REG_USBSSCONF	0x1024
+#define    USBF_SYS_DMA_AVAILABLE(_n)	(BIT(0) << (_n)) /* _n=0..15 */
+#define    USBF_SYS_EP_AVAILABLE(_n)	(BIT(16) << (_n)) /* _n=0..15 */
+
+#define USBF_BASE_DMA_EPN(_n)	(0x1110 + (_n) * 0x010)
+/* EPn DMA registers offsets from Base USBF_BASE_DMA_EPN(n-1). n=1..15*/
+#define     USBF_REG_DMA_EPN_DCR1	0x00
+#define         USBF_SYS_EPN_REQEN		BIT(0)
+#define         USBF_SYS_EPN_DIR0		BIT(1)
+#define         USBF_SYS_EPN_SET_DMACNT(_c)	((_c) << 16)
+#define         USBF_SYS_EPN_GET_DMACNT(_r)	(((_r) >> 16) & 0x0FF)
+
+#define     USBF_REG_DMA_EPN_DCR2	0x04
+#define         USBF_SYS_EPN_MPKT(_s)		((_s) << 0)
+#define         USBF_SYS_EPN_LMPKT(_l)		((_l) << 16)
+
+#define     USBF_REG_DMA_EPN_TADR	0x08
+
+/* USB request */
+struct usbf_req {
+	struct usb_request	req;
+	struct list_head	queue;
+	unsigned int		is_zero_sent : 1;
+	unsigned int		is_mapped : 1;
+	enum {
+		USBF_XFER_START,
+		USBF_XFER_WAIT_DMA,
+		USBF_XFER_SEND_NULL,
+		USBF_XFER_WAIT_END,
+		USBF_XFER_WAIT_DMA_SHORT,
+		USBF_XFER_WAIT_BRIDGE,
+	}			xfer_step;
+	size_t			dma_size;
+};
+
+/* USB Endpoint */
+struct usbf_ep {
+	struct usb_ep		ep;
+	char			name[32];
+	struct list_head	queue;
+	int			is_processing : 1;
+	int			is_in : 1;
+	struct			usbf_udc *udc;
+	void __iomem		*regs;
+	void __iomem		*dma_regs;
+	unsigned		id : 8;
+	unsigned		disabled : 1;
+	unsigned		is_wedged : 1;
+	unsigned		delayed_status : 1;
+	u32			status;
+	void			(*bridge_on_dma_end)(struct usbf_ep *ep);
+};
+
+enum usbf_ep0state {
+	EP0_IDLE,
+	EP0_IN_DATA_PHASE,
+	EP0_OUT_DATA_PHASE,
+	EP0_OUT_STATUS_START_PHASE,
+	EP0_OUT_STATUS_PHASE,
+	EP0_OUT_STATUS_END_PHASE,
+	EP0_IN_STATUS_START_PHASE,
+	EP0_IN_STATUS_PHASE,
+	EP0_IN_STATUS_END_PHASE,
+};
+
+struct usbf_udc {
+	struct usb_gadget		gadget;
+	struct usb_gadget_driver	*driver;
+	struct device			*dev;
+	void __iomem			*regs;
+	spinlock_t			lock;
+	bool				is_remote_wakeup;
+	bool				is_usb_suspended;
+	struct usbf_ep			ep[USBF_NUM_ENDPOINTS];
+	/* for EP0 control messages */
+	enum usbf_ep0state		ep0state;
+	struct usbf_req			setup_reply;
+	u8				ep0_buf[USBF_EP0_MAX_PCKT_SIZE];
+};
+
+struct usbf_ep_info {
+	const char		*name;
+	struct usb_ep_caps	caps;
+	u16			base_addr;
+	int			is_double : 1;
+	u16			maxpacket_limit;
+};
+
+#define USBF_SINGLE_BUFFER 0
+#define USBF_DOUBLE_BUFFER 1
+#define USBF_EP_INFO(_name, _caps, _base_addr, _is_double, _maxpacket_limit)  \
+	{                                                                     \
+		.name            = _name,                                     \
+		.caps            = _caps,                                     \
+		.base_addr       = _base_addr,                                \
+		.is_double       = _is_double,                                \
+		.maxpacket_limit = _maxpacket_limit,                          \
+	}
+
+/* This table is computed from the recommended values provided in the SOC
+ * datasheet. The buffer type (single/double) and the endpoint type cannot
+ * be changed. The mapping in internal RAM (base_addr and number of words)
+ * for each endpoints depends on the max packet size and the buffer type.
+ */
+static const struct usbf_ep_info usbf_ep_info[USBF_NUM_ENDPOINTS] = {
+	/* ep0: buf @0x0000 64 bytes, fixed 32 words */
+	[0] = USBF_EP_INFO("ep0-ctrl",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0000, USBF_SINGLE_BUFFER, USBF_EP0_MAX_PCKT_SIZE),
+	/* ep1: buf @0x0020, 2 buffers 512 bytes -> (512 * 2 / 4) words */
+	[1] = USBF_EP_INFO("ep1-bulk",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0020, USBF_DOUBLE_BUFFER, 512),
+	/* ep2: buf @0x0120, 2 buffers 512 bytes -> (512 * 2 / 4) words */
+	[2] = USBF_EP_INFO("ep2-bulk",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0120, USBF_DOUBLE_BUFFER, 512),
+	/* ep3: buf @0x0220, 1 buffer 512 bytes -> (512 * 2 / 4) words */
+	[3] = USBF_EP_INFO("ep3-bulk",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0220, USBF_SINGLE_BUFFER, 512),
+	/* ep4: buf @0x02A0, 1 buffer 512 bytes -> (512 * 1 / 4) words */
+	[4] = USBF_EP_INFO("ep4-bulk",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x02A0, USBF_SINGLE_BUFFER, 512),
+	/* ep5: buf @0x0320, 1 buffer 512 bytes -> (512 * 2 / 4) words */
+	[5] = USBF_EP_INFO("ep5-bulk",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0320, USBF_SINGLE_BUFFER, 512),
+	/* ep6: buf @0x03A0, 1 buffer 1024 bytes -> (1024 * 1 / 4) words */
+	[6] = USBF_EP_INFO("ep6-int",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_INT,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x03A0, USBF_SINGLE_BUFFER, 1024),
+	/* ep7: buf @0x04A0, 1 buffer 1024 bytes -> (1024 * 1 / 4) words */
+	[7] = USBF_EP_INFO("ep7-int",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_INT,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x04A0, USBF_SINGLE_BUFFER, 1024),
+	/* ep8: buf @0x0520, 1 buffer 1024 bytes -> (1024 * 1 / 4) words */
+	[8] = USBF_EP_INFO("ep8-int",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_INT,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0520, USBF_SINGLE_BUFFER, 1024),
+	/* ep9: buf @0x0620, 1 buffer 1024 bytes -> (1024 * 1 / 4) words */
+	[9] = USBF_EP_INFO("ep9-int",
+			   USB_EP_CAPS(USB_EP_CAPS_TYPE_INT,
+				       USB_EP_CAPS_DIR_ALL),
+			   0x0620, USBF_SINGLE_BUFFER, 1024),
+	/* ep10: buf @0x0720, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[10] = USBF_EP_INFO("ep10-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x0720, USBF_DOUBLE_BUFFER, 1024),
+	/* ep11: buf @0x0920, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[11] = USBF_EP_INFO("ep11-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x0920, USBF_DOUBLE_BUFFER, 1024),
+	/* ep12: buf @0x0B20, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[12] = USBF_EP_INFO("ep12-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x0B20, USBF_DOUBLE_BUFFER, 1024),
+	/* ep13: buf @0x0D20, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[13] = USBF_EP_INFO("ep13-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x0D20, USBF_DOUBLE_BUFFER, 1024),
+	/* ep14: buf @0x0F20, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[14] = USBF_EP_INFO("ep14-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x0F20, USBF_DOUBLE_BUFFER, 1024),
+	/* ep15: buf @0x1120, 2 buffers 1024 bytes -> (1024 * 2 / 4) words */
+	[15] = USBF_EP_INFO("ep15-iso",
+			    USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO,
+					USB_EP_CAPS_DIR_ALL),
+			    0x1120, USBF_DOUBLE_BUFFER, 1024),
+};
+
+static inline u32 usbf_reg_readl(struct usbf_udc *udc, uint offset)
+{
+	return readl(udc->regs + offset);
+}
+
+static inline void usbf_reg_writel(struct usbf_udc *udc, uint offset, u32 val)
+{
+	writel(val, udc->regs + offset);
+}
+
+static inline void usbf_reg_bitset(struct usbf_udc *udc, uint offset, u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_reg_readl(udc, offset);
+	tmp |= set;
+	usbf_reg_writel(udc, offset, tmp);
+}
+
+static inline void usbf_reg_bitclr(struct usbf_udc *udc, uint offset, u32 clr)
+{
+	u32 tmp;
+
+	tmp = usbf_reg_readl(udc, offset);
+	tmp &= ~clr;
+	usbf_reg_writel(udc, offset, tmp);
+}
+
+static inline void usbf_reg_clrset(struct usbf_udc *udc, uint offset,
+				   u32 clr, u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_reg_readl(udc, offset);
+	tmp &= ~clr;
+	tmp |= set;
+	usbf_reg_writel(udc, offset, tmp);
+}
+
+static inline u32 usbf_ep_reg_readl(struct usbf_ep *ep, uint offset)
+{
+	return readl(ep->regs + offset);
+}
+
+static inline void usbf_ep_reg_read_rep(struct usbf_ep *ep, uint offset,
+				       void *dst, uint count)
+{
+	readsl(ep->regs + offset, dst, count);
+}
+
+static inline void usbf_ep_reg_writel(struct usbf_ep *ep, uint offset, u32 val)
+{
+	writel(val, ep->regs + offset);
+}
+
+static inline void usbf_ep_reg_write_rep(struct usbf_ep *ep, uint offset,
+					 const void *src, uint count)
+{
+	writesl(ep->regs + offset, src, count);
+}
+
+static inline void usbf_ep_reg_bitset(struct usbf_ep *ep, uint offset, u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_reg_readl(ep, offset);
+	tmp |= set;
+	usbf_ep_reg_writel(ep, offset, tmp);
+}
+
+static inline void usbf_ep_reg_bitclr(struct usbf_ep *ep, uint offset, u32 clr)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_reg_readl(ep, offset);
+	tmp &= ~clr;
+	usbf_ep_reg_writel(ep, offset, tmp);
+}
+
+static inline void usbf_ep_reg_clrset(struct usbf_ep *ep, uint offset,
+				      u32 clr, u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_reg_readl(ep, offset);
+	tmp &= ~clr;
+	tmp |= set;
+	usbf_ep_reg_writel(ep, offset, tmp);
+}
+
+static inline u32 usbf_ep_dma_reg_readl(struct usbf_ep *ep, uint offset)
+{
+	return readl(ep->dma_regs + offset);
+}
+
+static inline void usbf_ep_dma_reg_writel(struct usbf_ep *ep, uint offset,
+					  u32 val)
+{
+	writel(val, ep->dma_regs + offset);
+}
+
+static inline void usbf_ep_dma_reg_bitset(struct usbf_ep *ep, uint offset,
+					  u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_dma_reg_readl(ep, offset);
+	tmp |= set;
+	usbf_ep_dma_reg_writel(ep, offset, tmp);
+}
+
+static inline void usbf_ep_dma_reg_bitclr(struct usbf_ep *ep, uint offset,
+					  u32 clr)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_dma_reg_readl(ep, offset);
+	tmp &= ~clr;
+	usbf_ep_dma_reg_writel(ep, offset, tmp);
+}
+
+static inline void usbf_ep_dma_reg_clrset(struct usbf_ep *ep, uint offset,
+					  u32 clr, u32 set)
+{
+	u32 tmp;
+
+	tmp = usbf_ep_dma_reg_readl(ep, offset);
+	tmp &= ~clr;
+	tmp |= set;
+	usbf_ep_dma_reg_writel(ep, offset, tmp);
+}
+
+static void usbf_ep0_send_null(struct usbf_ep *ep0, bool is_data1)
+{
+	u32 set;
+
+	set = USBF_EP0_DEND;
+	if (is_data1)
+		set |= USBF_EP0_PIDCLR;
+
+	usbf_ep_reg_bitset(ep0, USBF_REG_EP0_CONTROL, set);
+}
+
+static int usbf_ep0_pio_in(struct usbf_ep *ep0, struct usbf_req *req)
+{
+	unsigned int left;
+	unsigned int nb;
+	const void *buf;
+	u32 ctrl;
+	u32 last;
+
+	left = req->req.length - req->req.actual;
+
+	if (left == 0) {
+		if (!req->is_zero_sent) {
+			if (req->req.length == 0) {
+				TRACEEP(ep0, "send null\n");
+				usbf_ep0_send_null(ep0, false);
+				req->is_zero_sent = 1;
+				return -EINPROGRESS;
+			}
+			if ((req->req.actual % ep0->ep.maxpacket) == 0) {
+				if (req->req.zero) {
+					TRACEEP(ep0, "send null\n");
+					usbf_ep0_send_null(ep0, false);
+					req->is_zero_sent = 1;
+					return -EINPROGRESS;
+				}
+			}
+		}
+		return 0;
+	}
+
+	if (left > ep0->ep.maxpacket)
+		left = ep0->ep.maxpacket;
+
+	buf = req->req.buf;
+	buf += req->req.actual;
+
+	nb = left / sizeof(u32);
+	if (nb) {
+		usbf_ep_reg_write_rep(ep0, USBF_REG_EP0_WRITE, buf, nb);
+		buf += (nb * sizeof(u32));
+		req->req.actual += (nb * sizeof(u32));
+		left -= (nb * sizeof(u32));
+	}
+	ctrl = usbf_ep_reg_readl(ep0, USBF_REG_EP0_CONTROL);
+	ctrl &= ~USBF_EP0_DW_MASK;
+	if (left) {
+		memcpy(&last, buf, left);
+		usbf_ep_reg_writel(ep0, USBF_REG_EP0_WRITE, last);
+		ctrl |= USBF_EP0_DW(left);
+		req->req.actual += left;
+	}
+	usbf_ep_reg_writel(ep0, USBF_REG_EP0_CONTROL, ctrl | USBF_EP0_DEND);
+
+	TRACEEP(ep0, "send %u/%u\n", req->req.actual, req->req.length);
+
+	return -EINPROGRESS;
+}
+
+static int usbf_ep0_pio_out(struct usbf_ep *ep0, struct usbf_req *req)
+{
+	int req_status = 0;
+	unsigned int count;
+	unsigned int recv;
+	unsigned int left;
+	unsigned int nb;
+	void *buf;
+	u32 last;
+
+	if (ep0->status & USBF_EP0_OUT_INT) {
+		recv = usbf_ep_reg_readl(ep0, USBF_REG_EP0_LENGTH) & USBF_EP0_LDATA;
+		count = recv;
+
+		buf = req->req.buf;
+		buf += req->req.actual;
+
+		left = req->req.length - req->req.actual;
+
+		TRACEEP(ep0, "recv %u, left %u\n", count, left);
+
+		if (left > ep0->ep.maxpacket)
+			left = ep0->ep.maxpacket;
+
+		if (count > left) {
+			req_status = -EOVERFLOW;
+			count = left;
+		}
+
+		if (count) {
+			nb = count / sizeof(u32);
+			if (nb) {
+				usbf_ep_reg_read_rep(ep0, USBF_REG_EP0_READ,
+					buf, nb);
+				buf += (nb * sizeof(u32));
+				req->req.actual += (nb * sizeof(u32));
+				count -= (nb * sizeof(u32));
+			}
+			if (count) {
+				last = usbf_ep_reg_readl(ep0, USBF_REG_EP0_READ);
+				memcpy(buf, &last, count);
+				req->req.actual += count;
+			}
+		}
+		TRACEEP(ep0, "recv %u/%u\n", req->req.actual, req->req.length);
+
+		if (req_status) {
+			TRACEEP(ep0, "req.status=%d\n", req_status);
+			req->req.status = req_status;
+			return 0;
+		}
+
+		if (recv < ep0->ep.maxpacket) {
+			TRACEEP(ep0, "short packet\n");
+			/* This is a short packet -> It is the end */
+			req->req.status = 0;
+			return 0;
+		}
+
+		/* The Data stage of a control transfer from an endpoint to the
+		 * host is complete when the endpoint does one of the following:
+		 * - Has transferred exactly the expected amount of data
+		 * - Transfers a packet with a payload size less than
+		 *   wMaxPacketSize or transfers a zero-length packet
+		 */
+		if (req->req.actual == req->req.length) {
+			req->req.status = 0;
+			return 0;
+		}
+	}
+
+	if (ep0->status & USBF_EP0_OUT_NULL_INT) {
+		/* NULL packet received */
+		TRACEEP(ep0, "null packet\n");
+		if (req->req.actual != req->req.length) {
+			req->req.status = req->req.short_not_ok ?
+					  -EREMOTEIO : 0;
+		} else {
+			req->req.status = 0;
+		}
+		return 0;
+	}
+
+	return -EINPROGRESS;
+}
+
+static void usbf_ep0_fifo_flush(struct usbf_ep *ep0)
+{
+	u32 sts;
+	int ret;
+
+	usbf_ep_reg_bitset(ep0, USBF_REG_EP0_CONTROL, USBF_EP0_BCLR);
+
+	ret = readl_poll_timeout_atomic(ep0->regs + USBF_REG_EP0_STATUS, sts,
+		(sts & (USBF_EP0_IN_DATA | USBF_EP0_IN_EMPTY)) == USBF_EP0_IN_EMPTY,
+		0,  10000);
+	if (ret)
+		dev_err(ep0->udc->dev, "ep0 flush fifo timed out\n");
+
+}
+
+static void usbf_epn_send_null(struct usbf_ep *epn)
+{
+	usbf_ep_reg_bitset(epn, USBF_REG_EPN_CONTROL, USBF_EPN_DEND);
+}
+
+static void usbf_epn_send_residue(struct usbf_ep *epn, const void *buf,
+				  unsigned int size)
+{
+	u32 tmp;
+
+	memcpy(&tmp, buf, size);
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_WRITE, tmp);
+
+	usbf_ep_reg_clrset(epn, USBF_REG_EPN_CONTROL,
+				USBF_EPN_DW_MASK,
+				USBF_EPN_DW(size) | USBF_EPN_DEND);
+}
+
+static int usbf_epn_pio_in(struct usbf_ep *epn, struct usbf_req *req)
+{
+	unsigned int left;
+	unsigned int nb;
+	const void *buf;
+
+	left = req->req.length - req->req.actual;
+
+	if (left == 0) {
+		if (!req->is_zero_sent) {
+			if (req->req.length == 0) {
+				TRACEEP(epn, "ep%d send_null\n", epn->id);
+				usbf_epn_send_null(epn);
+				req->is_zero_sent = 1;
+				return -EINPROGRESS;
+			}
+			if ((req->req.actual % epn->ep.maxpacket) == 0) {
+				if (req->req.zero) {
+					TRACEEP(epn, "ep%d send_null\n",
+						epn->id);
+					usbf_epn_send_null(epn);
+					req->is_zero_sent = 1;
+					return -EINPROGRESS;
+				}
+			}
+		}
+		return 0;
+	}
+
+	if (left > epn->ep.maxpacket)
+		left = epn->ep.maxpacket;
+
+	buf = req->req.buf;
+	buf += req->req.actual;
+
+	nb = left / sizeof(u32);
+	if (nb) {
+		usbf_ep_reg_write_rep(epn, USBF_REG_EPN_WRITE, buf, nb);
+		buf += (nb * sizeof(u32));
+		req->req.actual += (nb * sizeof(u32));
+		left -= (nb * sizeof(u32));
+	}
+
+	if (left) {
+		usbf_epn_send_residue(epn, buf, left);
+		req->req.actual += left;
+	} else {
+		usbf_ep_reg_clrset(epn, USBF_REG_EPN_CONTROL,
+					USBF_EPN_DW_MASK,
+					USBF_EPN_DEND);
+	}
+
+	TRACEEP(epn, "ep%d send %u/%u\n", epn->id, req->req.actual,
+		req->req.length);
+
+	return -EINPROGRESS;
+}
+
+static void usbf_epn_enable_in_end_int(struct usbf_ep *epn)
+{
+	usbf_ep_reg_bitset(epn, USBF_REG_EPN_INT_ENA, USBF_EPN_IN_END_EN);
+}
+
+static int usbf_epn_dma_in(struct usbf_ep *epn, struct usbf_req *req)
+{
+	unsigned int left;
+	u32 npkt;
+	u32 lastpkt;
+	int ret;
+
+	if (!IS_ALIGNED((uintptr_t)req->req.buf, 4)) {
+		TRACEEP(epn, "ep%d buf unaligned -> fallback pio\n", epn->id);
+		return usbf_epn_pio_in(epn, req);
+	}
+
+	left = req->req.length - req->req.actual;
+
+	switch (req->xfer_step) {
+	default:
+	case USBF_XFER_START:
+		if (left == 0) {
+			TRACEEP(epn, "ep%d send null\n", epn->id);
+			usbf_epn_send_null(epn);
+			req->xfer_step = USBF_XFER_WAIT_END;
+			break;
+		}
+		if (left < 4) {
+			TRACEEP(epn, "ep%d send residue %u\n", epn->id, left);
+			usbf_epn_send_residue(epn,
+				req->req.buf + req->req.actual, left);
+			req->req.actual += left;
+			req->xfer_step = USBF_XFER_WAIT_END;
+			break;
+		}
+
+		ret = usb_gadget_map_request(&epn->udc->gadget, &req->req, 1);
+		if (ret < 0) {
+			dev_err(epn->udc->dev, "usb_gadget_map_request failed (%d)\n",
+				ret);
+			return ret;
+		}
+		req->is_mapped = 1;
+
+		npkt = DIV_ROUND_UP(left, epn->ep.maxpacket);
+		lastpkt = (left % epn->ep.maxpacket);
+		if (lastpkt == 0)
+			lastpkt = epn->ep.maxpacket;
+		lastpkt &= ~0x3; /* DMA is done on 32bit units */
+
+		usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_DCR2,
+			USBF_SYS_EPN_MPKT(epn->ep.maxpacket) | USBF_SYS_EPN_LMPKT(lastpkt));
+		usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_TADR,
+			req->req.dma);
+		usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_DCR1,
+			USBF_SYS_EPN_SET_DMACNT(npkt));
+		usbf_ep_dma_reg_bitset(epn, USBF_REG_DMA_EPN_DCR1,
+			USBF_SYS_EPN_REQEN);
+
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_LEN_DCNT, USBF_EPN_SET_DMACNT(npkt));
+
+		usbf_ep_reg_bitset(epn, USBF_REG_EPN_CONTROL, USBF_EPN_AUTO);
+
+		/* The end of DMA transfer at the USBF level needs to be handle
+		 * after the detection of the end of DMA transfer at the brige
+		 * level.
+		 * To force this sequence, EPN_IN_END_EN will be set by the
+		 * detection of the end of transfer at bridge level (ie. bridge
+		 * interrupt).
+		 */
+		usbf_ep_reg_bitclr(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_IN_EN | USBF_EPN_IN_END_EN);
+		epn->bridge_on_dma_end = usbf_epn_enable_in_end_int;
+
+		/* Clear any pending IN_END interrupt */
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS, ~(u32)USBF_EPN_IN_END_INT);
+
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_DMA_CTRL,
+			USBF_EPN_BURST_SET | USBF_EPN_DMAMODE0);
+		usbf_ep_reg_bitset(epn, USBF_REG_EPN_DMA_CTRL,
+			USBF_EPN_DMA_EN);
+
+		req->dma_size = (npkt - 1) * epn->ep.maxpacket + lastpkt;
+
+		TRACEEP(epn, "ep%d dma xfer %zu\n", epn->id, req->dma_size);
+
+		req->xfer_step = USBF_XFER_WAIT_DMA;
+		break;
+
+	case USBF_XFER_WAIT_DMA:
+		if (!(epn->status & USBF_EPN_IN_END_INT)) {
+			TRACEEP(epn, "ep%d dma not done\n", epn->id);
+			break;
+		}
+		TRACEEP(epn, "ep%d dma done\n", epn->id);
+
+		usb_gadget_unmap_request(&epn->udc->gadget, &req->req, 1);
+		req->is_mapped = 0;
+
+		usbf_ep_reg_bitclr(epn, USBF_REG_EPN_CONTROL, USBF_EPN_AUTO);
+
+		usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_IN_END_EN,
+			USBF_EPN_IN_EN);
+
+		req->req.actual += req->dma_size;
+
+		left = req->req.length - req->req.actual;
+		if (left) {
+			usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS, ~(u32)USBF_EPN_IN_INT);
+
+			TRACEEP(epn, "ep%d send residue %u\n", epn->id, left);
+			usbf_epn_send_residue(epn,
+				req->req.buf + req->req.actual, left);
+			req->req.actual += left;
+			req->xfer_step = USBF_XFER_WAIT_END;
+			break;
+		}
+
+		if (req->req.actual % epn->ep.maxpacket) {
+			/* last packet was a short packet. Tell the hardware to
+			 * send it right now.
+			 */
+			TRACEEP(epn, "ep%d send short\n", epn->id);
+
+			usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS,
+				~(u32)USBF_EPN_IN_INT);
+			usbf_ep_reg_bitset(epn, USBF_REG_EPN_CONTROL,
+				USBF_EPN_DEND);
+
+			req->xfer_step = USBF_XFER_WAIT_END;
+			break;
+		}
+
+		/* Last packet size was a maxpacket size
+		 * Send null packet if needed
+		 */
+		if (req->req.zero) {
+			req->xfer_step = USBF_XFER_SEND_NULL;
+			break;
+		}
+
+		/* No more action to do. Wait for the end of the USB transfer */
+		req->xfer_step = USBF_XFER_WAIT_END;
+		break;
+
+	case USBF_XFER_SEND_NULL:
+		TRACEEP(epn, "ep%d send null\n", epn->id);
+		usbf_epn_send_null(epn);
+		req->xfer_step = USBF_XFER_WAIT_END;
+		break;
+
+	case USBF_XFER_WAIT_END:
+		if (!(epn->status & USBF_EPN_IN_INT)) {
+			TRACEEP(epn, "ep%d end not done\n", epn->id);
+			break;
+		}
+		TRACEEP(epn, "ep%d send done %u/%u\n", epn->id,
+			req->req.actual, req->req.length);
+		req->xfer_step = USBF_XFER_START;
+		return 0;
+	}
+
+	return -EINPROGRESS;
+}
+
+static void usbf_epn_recv_residue(struct usbf_ep *epn, void *buf,
+				  unsigned int size)
+{
+	u32 last;
+
+	last = usbf_ep_reg_readl(epn, USBF_REG_EPN_READ);
+	memcpy(buf, &last, size);
+}
+
+static int usbf_epn_pio_out(struct usbf_ep *epn, struct usbf_req *req)
+{
+	int req_status = 0;
+	unsigned int count;
+	unsigned int recv;
+	unsigned int left;
+	unsigned int nb;
+	void *buf;
+
+	if (epn->status & USBF_EPN_OUT_INT) {
+		recv = USBF_EPN_GET_LDATA(
+			usbf_ep_reg_readl(epn, USBF_REG_EPN_LEN_DCNT));
+		count = recv;
+
+		buf = req->req.buf;
+		buf += req->req.actual;
+
+		left = req->req.length - req->req.actual;
+
+		TRACEEP(epn, "ep%d recv %u, left %u, mpkt %u\n", epn->id,
+			recv, left, epn->ep.maxpacket);
+
+		if (left > epn->ep.maxpacket)
+			left = epn->ep.maxpacket;
+
+		if (count > left) {
+			req_status = -EOVERFLOW;
+			count = left;
+		}
+
+		if (count) {
+			nb = count / sizeof(u32);
+			if (nb) {
+				usbf_ep_reg_read_rep(epn, USBF_REG_EPN_READ,
+					buf, nb);
+				buf += (nb * sizeof(u32));
+				req->req.actual += (nb * sizeof(u32));
+				count -= (nb * sizeof(u32));
+			}
+			if (count) {
+				usbf_epn_recv_residue(epn, buf, count);
+				req->req.actual += count;
+			}
+		}
+		TRACEEP(epn, "ep%d recv %u/%u\n", epn->id,
+			req->req.actual, req->req.length);
+
+		if (req_status) {
+			TRACEEP(epn, "ep%d req.status=%d\n", epn->id,
+				req_status);
+			req->req.status = req_status;
+			return 0;
+		}
+
+		if (recv < epn->ep.maxpacket) {
+			TRACEEP(epn, "ep%d short packet\n", epn->id);
+			/* This is a short packet -> It is the end */
+			req->req.status = 0;
+			return 0;
+		}
+
+		/* Request full -> complete */
+		if (req->req.actual == req->req.length) {
+			req->req.status = 0;
+			return 0;
+		}
+	}
+
+	if (epn->status & USBF_EPN_OUT_NULL_INT) {
+		/* NULL packet received */
+		TRACEEP(epn, "ep%d null packet\n", epn->id);
+		if (req->req.actual != req->req.length) {
+			req->req.status = req->req.short_not_ok ?
+					  -EREMOTEIO : 0;
+		} else {
+			req->req.status = 0;
+		}
+		return 0;
+	}
+
+	return -EINPROGRESS;
+}
+
+static void usbf_epn_enable_out_end_int(struct usbf_ep *epn)
+{
+	usbf_ep_reg_bitset(epn, USBF_REG_EPN_INT_ENA, USBF_EPN_OUT_END_EN);
+}
+
+static void usbf_epn_process_queue(struct usbf_ep *epn);
+
+static void usbf_epn_dma_out_send_dma(struct usbf_ep *epn, dma_addr_t addr, u32 npkt, bool is_short)
+{
+	usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_DCR2, USBF_SYS_EPN_MPKT(epn->ep.maxpacket));
+	usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_TADR, addr);
+
+	if (is_short) {
+		usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_DCR1,
+				USBF_SYS_EPN_SET_DMACNT(1) | USBF_SYS_EPN_DIR0);
+		usbf_ep_dma_reg_bitset(epn, USBF_REG_DMA_EPN_DCR1,
+				USBF_SYS_EPN_REQEN);
+
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_LEN_DCNT,
+				USBF_EPN_SET_DMACNT(0));
+
+		/* The end of DMA transfer at the USBF level needs to be handled
+		 * after the detection of the end of DMA transfer at the brige
+		 * level.
+		 * To force this sequence, enabling the OUT_END interrupt will
+		 * be donee by the detection of the end of transfer at bridge
+		 * level (ie. bridge interrupt).
+		 */
+		usbf_ep_reg_bitclr(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN | USBF_EPN_OUT_END_EN);
+		epn->bridge_on_dma_end = usbf_epn_enable_out_end_int;
+
+		/* Clear any pending OUT_END interrupt */
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS,
+			~(u32)USBF_EPN_OUT_END_INT);
+
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_DMA_CTRL,
+			USBF_EPN_STOP_MODE | USBF_EPN_STOP_SET | USBF_EPN_DMAMODE0);
+		usbf_ep_reg_bitset(epn, USBF_REG_EPN_DMA_CTRL,
+			USBF_EPN_DMA_EN);
+		return;
+	}
+
+	usbf_ep_dma_reg_writel(epn, USBF_REG_DMA_EPN_DCR1,
+		USBF_SYS_EPN_SET_DMACNT(npkt) | USBF_SYS_EPN_DIR0);
+	usbf_ep_dma_reg_bitset(epn, USBF_REG_DMA_EPN_DCR1,
+		USBF_SYS_EPN_REQEN);
+
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_LEN_DCNT,
+		USBF_EPN_SET_DMACNT(npkt));
+
+	/* Here, the bridge may or may not generate an interrupt to signal the
+	 * end of DMA transfer.
+	 * Keep only OUT_END interrupt and let handle the bridge later during
+	 * the OUT_END processing.
+	 */
+	usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+		USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN,
+		USBF_EPN_OUT_END_EN);
+
+	/* Disable bridge interrupt. It will be renabled later */
+	usbf_reg_bitclr(epn->udc, USBF_REG_AHBBINTEN,
+		USBF_SYS_DMA_ENDINTEN_EPN(epn->id));
+
+	/* Clear any pending DMA_END interrupt at bridge level */
+	usbf_reg_writel(epn->udc, USBF_REG_AHBBINT,
+		USBF_SYS_DMA_ENDINT_EPN(epn->id));
+
+	/* Clear any pending OUT_END interrupt */
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS,
+		~(u32)USBF_EPN_OUT_END_INT);
+
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_DMA_CTRL,
+		USBF_EPN_STOP_MODE | USBF_EPN_STOP_SET | USBF_EPN_DMAMODE0 | USBF_EPN_BURST_SET);
+	usbf_ep_reg_bitset(epn, USBF_REG_EPN_DMA_CTRL,
+		USBF_EPN_DMA_EN);
+}
+
+static size_t usbf_epn_dma_out_complete_dma(struct usbf_ep *epn, bool is_short)
+{
+	u32 dmacnt;
+	u32 tmp;
+	int ret;
+
+	/* Restore interrupt mask */
+	usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+		USBF_EPN_OUT_END_EN,
+		USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN);
+
+	if (is_short) {
+		/* Nothing more to do when the DMA was for a short packet */
+		return 0;
+	}
+
+	/* Enable the bridge interrupt */
+	usbf_reg_bitset(epn->udc, USBF_REG_AHBBINTEN,
+		USBF_SYS_DMA_ENDINTEN_EPN(epn->id));
+
+	tmp = usbf_ep_reg_readl(epn, USBF_REG_EPN_LEN_DCNT);
+	dmacnt = USBF_EPN_GET_DMACNT(tmp);
+
+	if (dmacnt) {
+		/* Some packet were not received (halted by a short or a null
+		 * packet.
+		 * The bridge never raises an interrupt in this case.
+		 * Wait for the end of transfer at bridge level
+		 */
+		ret = readl_poll_timeout_atomic(
+			epn->dma_regs + USBF_REG_DMA_EPN_DCR1,
+			tmp, (USBF_SYS_EPN_GET_DMACNT(tmp) == dmacnt),
+			0,  10000);
+		if (ret) {
+			dev_err(epn->udc->dev, "ep%d wait bridge timed out\n",
+				epn->id);
+		}
+
+		usbf_ep_dma_reg_bitclr(epn, USBF_REG_DMA_EPN_DCR1,
+			USBF_SYS_EPN_REQEN);
+
+		/* The dmacnt value tells how many packet were not transferred
+		 * from the maximum number of packet we set for the DMA transfer.
+		 * Compute the left DMA size based on this value.
+		 */
+		return dmacnt * epn->ep.maxpacket;
+	}
+
+	return 0;
+}
+
+static int usbf_epn_dma_out(struct usbf_ep *epn, struct usbf_req *req)
+{
+	unsigned int dma_left;
+	unsigned int count;
+	unsigned int recv;
+	unsigned int left;
+	u32 npkt;
+	int ret;
+
+	if (!IS_ALIGNED((uintptr_t)req->req.buf, 4)) {
+		TRACEEP(epn, "ep%d buf unaligned -> fallback pio\n", epn->id);
+		return usbf_epn_pio_out(epn, req);
+	}
+
+	switch (req->xfer_step) {
+	default:
+	case USBF_XFER_START:
+		if (epn->status & USBF_EPN_OUT_NULL_INT) {
+			TRACEEP(epn, "ep%d null packet\n", epn->id);
+			if (req->req.actual != req->req.length) {
+				req->req.status = req->req.short_not_ok ?
+					-EREMOTEIO : 0;
+			} else {
+				req->req.status = 0;
+			}
+			return 0;
+		}
+
+		if (!(epn->status & USBF_EPN_OUT_INT)) {
+			TRACEEP(epn, "ep%d OUT_INT not set -> spurious\n",
+				epn->id);
+			break;
+		}
+
+		recv = USBF_EPN_GET_LDATA(
+			usbf_ep_reg_readl(epn, USBF_REG_EPN_LEN_DCNT));
+		if (!recv) {
+			TRACEEP(epn, "ep%d recv = 0 -> spurious\n",
+				epn->id);
+			break;
+		}
+
+		left = req->req.length - req->req.actual;
+
+		TRACEEP(epn, "ep%d recv %u, left %u, mpkt %u\n", epn->id,
+			recv, left, epn->ep.maxpacket);
+
+		if (recv > left) {
+			dev_err(epn->udc->dev, "ep%d overflow (%u/%u)\n",
+				epn->id, recv, left);
+			req->req.status = -EOVERFLOW;
+			return -EOVERFLOW;
+		}
+
+		if (recv < epn->ep.maxpacket) {
+			/* Short packet received */
+			TRACEEP(epn, "ep%d short packet\n", epn->id);
+			if (recv <= 3) {
+				usbf_epn_recv_residue(epn,
+					req->req.buf + req->req.actual, recv);
+				req->req.actual += recv;
+
+				TRACEEP(epn, "ep%d recv done %u/%u\n", epn->id,
+					req->req.actual, req->req.length);
+
+				req->xfer_step = USBF_XFER_START;
+				return 0;
+			}
+
+			ret = usb_gadget_map_request(&epn->udc->gadget, &req->req, 0);
+			if (ret < 0) {
+				dev_err(epn->udc->dev, "map request failed (%d)\n",
+					ret);
+				return ret;
+			}
+			req->is_mapped = 1;
+
+			usbf_epn_dma_out_send_dma(epn,
+				req->req.dma + req->req.actual,
+				1, true);
+			req->dma_size = recv & ~0x3;
+
+			TRACEEP(epn, "ep%d dma short xfer %zu\n", epn->id,
+				req->dma_size);
+
+			req->xfer_step = USBF_XFER_WAIT_DMA_SHORT;
+			break;
+		}
+
+		ret = usb_gadget_map_request(&epn->udc->gadget, &req->req, 0);
+		if (ret < 0) {
+			dev_err(epn->udc->dev, "map request failed (%d)\n",
+				ret);
+			return ret;
+		}
+		req->is_mapped = 1;
+
+		/* Use the maximum DMA size according to the request buffer.
+		 * We will adjust the received size later at the end of the DMA
+		 * transfer with the left size computed from
+		 * usbf_epn_dma_out_complete_dma().
+		 */
+		npkt = left / epn->ep.maxpacket;
+		usbf_epn_dma_out_send_dma(epn,
+				req->req.dma + req->req.actual,
+				npkt, false);
+		req->dma_size = npkt * epn->ep.maxpacket;
+
+		TRACEEP(epn, "ep%d dma xfer %zu (%u)\n", epn->id,
+			req->dma_size, npkt);
+
+		req->xfer_step = USBF_XFER_WAIT_DMA;
+		break;
+
+	case USBF_XFER_WAIT_DMA_SHORT:
+		if (!(epn->status & USBF_EPN_OUT_END_INT)) {
+			TRACEEP(epn, "ep%d dma short not done\n", epn->id);
+			break;
+		}
+		TRACEEP(epn, "ep%d dma short done\n", epn->id);
+
+		usbf_epn_dma_out_complete_dma(epn, true);
+
+		usb_gadget_unmap_request(&epn->udc->gadget, &req->req, 0);
+		req->is_mapped = 0;
+
+		req->req.actual += req->dma_size;
+
+		recv = USBF_EPN_GET_LDATA(
+			usbf_ep_reg_readl(epn, USBF_REG_EPN_LEN_DCNT));
+
+		count = recv & 0x3;
+		if (count) {
+			TRACEEP(epn, "ep%d recv residue %u\n", epn->id,
+				count);
+			usbf_epn_recv_residue(epn,
+				req->req.buf + req->req.actual, count);
+			req->req.actual += count;
+		}
+
+		TRACEEP(epn, "ep%d recv done %u/%u\n", epn->id,
+			req->req.actual, req->req.length);
+
+		req->xfer_step = USBF_XFER_START;
+		return 0;
+
+	case USBF_XFER_WAIT_DMA:
+		if (!(epn->status & USBF_EPN_OUT_END_INT)) {
+			TRACEEP(epn, "ep%d dma not done\n", epn->id);
+			break;
+		}
+		TRACEEP(epn, "ep%d dma done\n", epn->id);
+
+		dma_left = usbf_epn_dma_out_complete_dma(epn, false);
+		if (dma_left) {
+			/* Adjust the final DMA size with */
+			count = req->dma_size - dma_left;
+
+			TRACEEP(epn, "ep%d dma xfer done %u\n", epn->id, count);
+
+			req->req.actual += count;
+
+			if (epn->status & USBF_EPN_OUT_NULL_INT) {
+				/* DMA was stopped by a null packet reception */
+				TRACEEP(epn, "ep%d dma stopped by null pckt\n",
+					epn->id);
+				usb_gadget_unmap_request(&epn->udc->gadget,
+							 &req->req, 0);
+				req->is_mapped = 0;
+
+				usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS,
+					~(u32)USBF_EPN_OUT_NULL_INT);
+
+				if (req->req.actual != req->req.length) {
+					req->req.status = req->req.short_not_ok ?
+						  -EREMOTEIO : 0;
+				} else {
+					req->req.status = 0;
+				}
+				TRACEEP(epn, "ep%d recv done %u/%u\n", epn->id,
+					req->req.actual, req->req.length);
+				req->xfer_step = USBF_XFER_START;
+				return 0;
+			}
+
+			recv = USBF_EPN_GET_LDATA(
+				usbf_ep_reg_readl(epn, USBF_REG_EPN_LEN_DCNT));
+			left = req->req.length - req->req.actual;
+			if (recv > left) {
+				dev_err(epn->udc->dev,
+					"ep%d overflow (%u/%u)\n", epn->id,
+					recv, left);
+				req->req.status = -EOVERFLOW;
+				usb_gadget_unmap_request(&epn->udc->gadget,
+							 &req->req, 0);
+				req->is_mapped = 0;
+
+				req->xfer_step = USBF_XFER_START;
+				return -EOVERFLOW;
+			}
+
+			if (recv > 3) {
+				usbf_epn_dma_out_send_dma(epn,
+					req->req.dma + req->req.actual,
+					1, true);
+				req->dma_size = recv & ~0x3;
+
+				TRACEEP(epn, "ep%d dma short xfer %zu\n", epn->id,
+					req->dma_size);
+
+				req->xfer_step = USBF_XFER_WAIT_DMA_SHORT;
+				break;
+			}
+
+			usb_gadget_unmap_request(&epn->udc->gadget, &req->req, 0);
+			req->is_mapped = 0;
+
+			count = recv & 0x3;
+			if (count) {
+				TRACEEP(epn, "ep%d recv residue %u\n", epn->id,
+					count);
+				usbf_epn_recv_residue(epn,
+					req->req.buf + req->req.actual, count);
+				req->req.actual += count;
+			}
+
+			TRACEEP(epn, "ep%d recv done %u/%u\n", epn->id,
+				req->req.actual, req->req.length);
+
+			req->xfer_step = USBF_XFER_START;
+			return 0;
+		}
+
+		/* Process queue at bridge interrupt only */
+		usbf_ep_reg_bitclr(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_OUT_END_EN | USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN);
+		epn->status = 0;
+		epn->bridge_on_dma_end = usbf_epn_process_queue;
+
+		req->xfer_step = USBF_XFER_WAIT_BRIDGE;
+		break;
+
+	case USBF_XFER_WAIT_BRIDGE:
+		TRACEEP(epn, "ep%d bridge transfers done\n", epn->id);
+
+		/* Restore interrupt mask */
+		usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_OUT_END_EN,
+			USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN);
+
+		usb_gadget_unmap_request(&epn->udc->gadget, &req->req, 0);
+		req->is_mapped = 0;
+
+		req->req.actual += req->dma_size;
+
+		req->xfer_step = USBF_XFER_START;
+		left = req->req.length - req->req.actual;
+		if (!left) {
+			/* No more data can be added to the buffer */
+			TRACEEP(epn, "ep%d recv done %u/%u\n", epn->id,
+				req->req.actual, req->req.length);
+			return 0;
+		}
+		TRACEEP(epn, "ep%d recv done %u/%u, wait more data\n", epn->id,
+			req->req.actual, req->req.length);
+		break;
+	}
+
+	return -EINPROGRESS;
+}
+
+static void usbf_epn_dma_stop(struct usbf_ep *epn)
+{
+	usbf_ep_dma_reg_bitclr(epn, USBF_REG_DMA_EPN_DCR1, USBF_SYS_EPN_REQEN);
+
+	/* In the datasheet:
+	 *   If EP[m]_REQEN = 0b is set during DMA transfer, AHB-EPC stops DMA
+	 *   after 1 packet transfer completed.
+	 *   Therefore, wait sufficient time for ensuring DMA transfer
+	 *   completion. The WAIT time depends on the system, especially AHB
+	 *   bus activity
+	 * So arbitrary 10ms would be sufficient.
+	 */
+	mdelay(10);
+
+	usbf_ep_reg_bitclr(epn, USBF_REG_EPN_DMA_CTRL, USBF_EPN_DMA_EN);
+}
+
+static void usbf_epn_dma_abort(struct usbf_ep *epn,  struct usbf_req *req)
+{
+	TRACEEP(epn, "ep%d %s dma abort\n", epn->id, epn->is_in ? "in" : "out");
+
+	epn->bridge_on_dma_end = NULL;
+
+	usbf_epn_dma_stop(epn);
+
+	usb_gadget_unmap_request(&epn->udc->gadget, &req->req,
+				 epn->is_in ? 1 : 0);
+	req->is_mapped = 0;
+
+	usbf_ep_reg_bitclr(epn, USBF_REG_EPN_CONTROL, USBF_EPN_AUTO);
+
+	if (epn->is_in) {
+		usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_IN_END_EN,
+			USBF_EPN_IN_EN);
+	} else {
+		usbf_ep_reg_clrset(epn, USBF_REG_EPN_INT_ENA,
+			USBF_EPN_OUT_END_EN,
+			USBF_EPN_OUT_EN | USBF_EPN_OUT_NULL_EN);
+	}
+
+	/* As dma is stopped, be sure that no DMA interrupt are pending */
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS,
+		USBF_EPN_IN_END_INT | USBF_EPN_OUT_END_INT);
+
+	usbf_reg_writel(epn->udc, USBF_REG_AHBBINT, USBF_SYS_DMA_ENDINT_EPN(epn->id));
+
+	/* Enable DMA interrupt the bridge level */
+	usbf_reg_bitset(epn->udc, USBF_REG_AHBBINTEN,
+		USBF_SYS_DMA_ENDINTEN_EPN(epn->id));
+
+	/* Reset transfer step */
+	req->xfer_step = USBF_XFER_START;
+}
+
+static void usbf_epn_fifo_flush(struct usbf_ep *epn)
+{
+	u32 ctrl;
+	u32 sts;
+	int ret;
+
+	TRACEEP(epn, "ep%d %s fifo flush\n", epn->id, epn->is_in ? "in" : "out");
+
+	ctrl = usbf_ep_reg_readl(epn, USBF_REG_EPN_CONTROL);
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_CONTROL, ctrl | USBF_EPN_BCLR);
+
+	if (ctrl & USBF_EPN_DIR0)
+		return;
+
+	ret = readl_poll_timeout_atomic(epn->regs + USBF_REG_EPN_STATUS, sts,
+		(sts & (USBF_EPN_IN_DATA | USBF_EPN_IN_EMPTY)) == USBF_EPN_IN_EMPTY,
+		0,  10000);
+	if (ret)
+		dev_err(epn->udc->dev, "ep%d flush fifo timed out\n", epn->id);
+}
+
+static void usbf_ep_req_done(struct usbf_ep *ep, struct usbf_req *req,
+			     int status)
+{
+	list_del_init(&req->queue);
+
+	if (status) {
+		req->req.status = status;
+	} else {
+		if (req->req.status == -EINPROGRESS)
+			req->req.status = status;
+	}
+
+	TRACEEP(ep, "ep%d %s req done length %u/%u, status=%d\n", ep->id,
+		ep->is_in ? "in" : "out",
+		req->req.actual, req->req.length, req->req.status);
+
+	if (req->is_mapped)
+		usbf_epn_dma_abort(ep, req);
+
+	spin_unlock(&ep->udc->lock);
+	usb_gadget_giveback_request(&ep->ep, &req->req);
+	spin_lock(&ep->udc->lock);
+}
+
+static void usbf_ep_nuke(struct usbf_ep *ep, int status)
+{
+	struct usbf_req *req;
+
+	TRACEEP(ep, "ep%d %s nuke status %d\n", ep->id,
+		ep->is_in ? "in" : "out",
+		status);
+
+	while (!list_empty(&ep->queue)) {
+		req = list_first_entry(&ep->queue, struct usbf_req, queue);
+		usbf_ep_req_done(ep, req, status);
+	}
+
+	if (ep->id == 0)
+		usbf_ep0_fifo_flush(ep);
+	else
+		usbf_epn_fifo_flush(ep);
+}
+
+static bool usbf_ep_is_stalled(struct usbf_ep *ep)
+{
+	u32 ctrl;
+
+	if (ep->id == 0) {
+		ctrl = usbf_ep_reg_readl(ep, USBF_REG_EP0_CONTROL);
+		return (ctrl & USBF_EP0_STL) ? true : false;
+	}
+
+	ctrl = usbf_ep_reg_readl(ep, USBF_REG_EPN_CONTROL);
+	if (ep->is_in)
+		return (ctrl & USBF_EPN_ISTL) ? true : false;
+
+	return (ctrl & USBF_EPN_OSTL) ? true : false;
+}
+
+static int usbf_epn_start_queue(struct usbf_ep *epn)
+{
+	struct usbf_req *req;
+	int ret;
+
+	if (usbf_ep_is_stalled(epn))
+		return 0;
+
+	req = list_first_entry_or_null(&epn->queue, struct usbf_req, queue);
+
+	if (epn->is_in) {
+		if (req && !epn->is_processing) {
+			ret = epn->dma_regs ?
+				usbf_epn_dma_in(epn, req) :
+				usbf_epn_pio_in(epn, req);
+			if (ret != -EINPROGRESS) {
+				dev_err(epn->udc->dev,
+					"queued next request not in progress\n");
+					/* The request cannot be completed (ie
+					 * ret == 0) on the first call.
+					 * stall and nuke the endpoint
+					 */
+				return ret ? ret : -EIO;
+			}
+		}
+	} else {
+		if (req) {
+			/* Clear ONAK to accept OUT tokens */
+			usbf_ep_reg_bitclr(epn, USBF_REG_EPN_CONTROL,
+				USBF_EPN_ONAK);
+
+			/* Enable interrupts */
+			usbf_ep_reg_bitset(epn, USBF_REG_EPN_INT_ENA,
+				USBF_EPN_OUT_INT | USBF_EPN_OUT_NULL_INT);
+		} else {
+			/* Disable incoming data and interrupt.
+			 * They will be enable on next usb_eb_queue call
+			 */
+			usbf_ep_reg_bitset(epn, USBF_REG_EPN_CONTROL,
+				USBF_EPN_ONAK);
+			usbf_ep_reg_bitclr(epn, USBF_REG_EPN_INT_ENA,
+				USBF_EPN_OUT_INT | USBF_EPN_OUT_NULL_INT);
+		}
+	}
+	return 0;
+}
+
+static int usbf_ep_process_queue(struct usbf_ep *ep)
+{
+	int (*usbf_ep_xfer)(struct usbf_ep *ep, struct usbf_req *req);
+	struct usbf_req *req;
+	int is_processing;
+	int ret;
+
+	if (ep->is_in) {
+		usbf_ep_xfer = usbf_ep0_pio_in;
+		if (ep->id) {
+			usbf_ep_xfer = ep->dma_regs ?
+					usbf_epn_dma_in : usbf_epn_pio_in;
+		}
+	} else {
+		usbf_ep_xfer = usbf_ep0_pio_out;
+		if (ep->id) {
+			usbf_ep_xfer = ep->dma_regs ?
+					usbf_epn_dma_out : usbf_epn_pio_out;
+		}
+	}
+
+	req = list_first_entry_or_null(&ep->queue, struct usbf_req, queue);
+	if (!req) {
+		dev_err(ep->udc->dev,
+			"no request available for ep%d %s process\n", ep->id,
+			ep->is_in ? "in" : "out");
+		return -ENOENT;
+	}
+
+	do {
+		/* Were going to read the FIFO for this current request.
+		 * NAK any other incoming data to avoid a race condition if no
+		 * more request are available.
+		 */
+		if (!ep->is_in && ep->id != 0) {
+			usbf_ep_reg_bitset(ep, USBF_REG_EPN_CONTROL,
+				USBF_EPN_ONAK);
+		}
+
+		ret = usbf_ep_xfer(ep, req);
+		if (ret == -EINPROGRESS) {
+			if (!ep->is_in && ep->id != 0) {
+				/* The current request needs more data.
+				 * Allow incoming data
+				 */
+				usbf_ep_reg_bitclr(ep, USBF_REG_EPN_CONTROL,
+					USBF_EPN_ONAK);
+			}
+			return ret;
+		}
+
+		is_processing = ep->is_processing;
+		ep->is_processing = 1;
+		usbf_ep_req_done(ep, req, ret);
+		ep->is_processing = is_processing;
+
+		if (ret) {
+			/* An error was detected during the request transfer.
+			 * Any pending DMA transfers were aborted by the
+			 * usbf_ep_req_done() call.
+			 * It's time to flush the fifo
+			 */
+			if (ep->id == 0)
+				usbf_ep0_fifo_flush(ep);
+			else
+				usbf_epn_fifo_flush(ep);
+		}
+
+		req = list_first_entry_or_null(&ep->queue, struct usbf_req,
+					       queue);
+
+		if (ep->is_in)
+			continue;
+
+		if (ep->id != 0) {
+			if (req) {
+				/* An other request is available.
+				 * Allow incoming data
+				 */
+				usbf_ep_reg_bitclr(ep, USBF_REG_EPN_CONTROL,
+					USBF_EPN_ONAK);
+			} else {
+				/* No request queued. Disable interrupts.
+				 * They will be enabled on usb_ep_queue
+				 */
+				usbf_ep_reg_bitclr(ep, USBF_REG_EPN_INT_ENA,
+					USBF_EPN_OUT_INT | USBF_EPN_OUT_NULL_INT);
+			}
+		}
+		/* Do not recall usbf_ep_xfer() */
+		return req ? -EINPROGRESS : 0;
+
+	} while (req);
+
+	return 0;
+}
+
+static void usbf_ep_stall(struct usbf_ep *ep, bool stall)
+{
+	struct usbf_req *first;
+
+	TRACEEP(ep, "ep%d %s %s\n", ep->id,
+		ep->is_in ? "in" : "out",
+		stall ? "stall" : "unstall");
+
+	if (ep->id == 0) {
+		if (stall)
+			usbf_ep_reg_bitset(ep, USBF_REG_EP0_CONTROL, USBF_EP0_STL);
+		else
+			usbf_ep_reg_bitclr(ep, USBF_REG_EP0_CONTROL, USBF_EP0_STL);
+		return;
+	}
+
+	if (stall) {
+		if (ep->is_in)
+			usbf_ep_reg_bitset(ep, USBF_REG_EPN_CONTROL,
+				USBF_EPN_ISTL);
+		else
+			usbf_ep_reg_bitset(ep, USBF_REG_EPN_CONTROL,
+				USBF_EPN_OSTL | USBF_EPN_OSTL_EN);
+	} else {
+		first = list_first_entry_or_null(&ep->queue, struct usbf_req, queue);
+		if (first && first->is_mapped) {
+			/* This can appear if the host halts an endpoint using
+			 * SET_FEATURE and then un-halts the endpoint
+			 */
+			usbf_epn_dma_abort(ep, first);
+		}
+		usbf_epn_fifo_flush(ep);
+		if (ep->is_in) {
+			usbf_ep_reg_clrset(ep, USBF_REG_EPN_CONTROL,
+				USBF_EPN_ISTL,
+				USBF_EPN_IPIDCLR);
+		} else {
+			usbf_ep_reg_clrset(ep, USBF_REG_EPN_CONTROL,
+				USBF_EPN_OSTL,
+				USBF_EPN_OSTL_EN | USBF_EPN_OPIDCLR);
+		}
+		usbf_epn_start_queue(ep);
+	}
+}
+
+static void usbf_ep0_enable(struct usbf_ep *ep0)
+{
+	usbf_ep_reg_writel(ep0, USBF_REG_EP0_CONTROL, USBF_EP0_INAK_EN | USBF_EP0_BCLR);
+
+	usbf_ep_reg_writel(ep0, USBF_REG_EP0_INT_ENA,
+		USBF_EP0_SETUP_EN | USBF_EP0_STG_START_EN | USBF_EP0_STG_END_EN |
+		USBF_EP0_OUT_EN | USBF_EP0_OUT_NULL_EN | USBF_EP0_IN_EN);
+
+	ep0->udc->ep0state = EP0_IDLE;
+	ep0->disabled = 0;
+
+	/* enable interrupts for the ep0 */
+	usbf_reg_bitset(ep0->udc, USBF_REG_USB_INT_ENA, USBF_USB_EPN_EN(0));
+}
+
+static int usbf_epn_enable(struct usbf_ep *epn)
+{
+	u32 base_addr;
+	u32 ctrl;
+
+	base_addr = usbf_ep_info[epn->id].base_addr;
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_PCKT_ADRS,
+		USBF_EPN_BASEAD(base_addr) | USBF_EPN_MPKT(epn->ep.maxpacket));
+
+	/* OUT transfer interrupt are enabled during usb_ep_queue */
+	if (epn->is_in) {
+		/* Will be changed in DMA processing */
+		usbf_ep_reg_writel(epn, USBF_REG_EPN_INT_ENA, USBF_EPN_IN_EN);
+	}
+
+	/* Clear, set endpoint direction, set IN/OUT STL, and enable
+	 * Send NAK for Data out as request are not queued yet
+	 */
+	ctrl = USBF_EPN_EN | USBF_EPN_BCLR;
+	if (epn->is_in)
+		ctrl |= USBF_EPN_OSTL | USBF_EPN_OSTL_EN;
+	else
+		ctrl |= USBF_EPN_DIR0 | USBF_EPN_ISTL | USBF_EPN_OSTL_EN | USBF_EPN_ONAK;
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_CONTROL, ctrl);
+
+	return 0;
+}
+
+static int usbf_ep_enable(struct usb_ep *_ep,
+			  const struct usb_endpoint_descriptor *desc)
+{
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	struct usbf_udc *udc = ep->udc;
+	unsigned long flags;
+	int ret;
+
+	if (ep->id == 0) {
+		TRACEEP(ep, "ep0 invalid call\n");
+		return -EINVAL;
+	}
+
+	if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+		TRACEEP(ep, "ep%d bad descriptor\n", ep->id);
+		return -EINVAL;
+	}
+
+	TRACEEP(ep, "ep%d %s mpkts %d\n", ep->id,
+		usb_endpoint_dir_in(desc) ? "in" : "out",
+		usb_endpoint_maxp(desc));
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	ep->is_in = usb_endpoint_dir_in(desc);
+	ep->ep.maxpacket = usb_endpoint_maxp(desc);
+
+	ret = usbf_epn_enable(ep);
+	if (ret)
+		goto end;
+
+	ep->disabled = 0;
+
+	/* enable interrupts for this endpoint */
+	usbf_reg_bitset(udc, USBF_REG_USB_INT_ENA, USBF_USB_EPN_EN(ep->id));
+
+	/* enable DMA interrupt at bridge level if DMA is used */
+	if (ep->dma_regs) {
+		ep->bridge_on_dma_end = NULL;
+		usbf_reg_bitset(udc, USBF_REG_AHBBINTEN,
+			USBF_SYS_DMA_ENDINTEN_EPN(ep->id));
+	}
+
+	ret = 0;
+end:
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return ret;
+}
+
+static int usbf_epn_disable(struct usbf_ep *epn)
+{
+	/* Disable interrupts */
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_INT_ENA, 0);
+
+	/* Disable endpoint */
+	usbf_ep_reg_bitclr(epn, USBF_REG_EPN_CONTROL, USBF_EPN_EN);
+
+	/* remove anything that was pending */
+	usbf_ep_nuke(epn, -ESHUTDOWN);
+
+	return 0;
+}
+
+static int usbf_ep_disable(struct usb_ep *_ep)
+{
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	struct usbf_udc *udc = ep->udc;
+	unsigned long flags;
+	int ret;
+
+	if (ep->id == 0) {
+		TRACEEP(ep, "ep0 invalid call\n");
+		return -EINVAL;
+	}
+
+	TRACEEP(ep, "ep%d %s mpkts %d\n", ep->id,
+		ep->is_in ? "in" : "out", ep->ep.maxpacket);
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	ep->disabled = 1;
+	/* Disable DMA interrupt */
+	if (ep->dma_regs) {
+		usbf_reg_bitclr(udc, USBF_REG_AHBBINTEN,
+			USBF_SYS_DMA_ENDINTEN_EPN(ep->id));
+		ep->bridge_on_dma_end = NULL;
+	}
+	/* disable interrupts for this endpoint */
+	usbf_reg_bitclr(udc, USBF_REG_USB_INT_ENA, USBF_USB_EPN_EN(ep->id));
+	/* and the endpoint itself */
+	ret = usbf_epn_disable(ep);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return ret;
+}
+
+static int usbf_ep0_queue(struct usbf_ep *ep0, struct usbf_req *req,
+			  gfp_t gfp_flags)
+{
+	int ret;
+
+	req->req.actual = 0;
+	req->req.status = -EINPROGRESS;
+	req->is_zero_sent = 0;
+
+	list_add_tail(&req->queue, &ep0->queue);
+
+	if (ep0->udc->ep0state == EP0_IN_STATUS_START_PHASE)
+		return 0;
+
+	if (!ep0->is_in)
+		return 0;
+
+	if (ep0->udc->ep0state == EP0_IN_STATUS_PHASE) {
+		if (req->req.length) {
+			dev_err(ep0->udc->dev,
+				"request lng %u for ep0 in status phase\n",
+				req->req.length);
+			return -EINVAL;
+		}
+		ep0->delayed_status = 0;
+	}
+	if (!ep0->is_processing) {
+		ret = usbf_ep0_pio_in(ep0, req);
+		if (ret != -EINPROGRESS) {
+			dev_err(ep0->udc->dev,
+				"queued request not in progress\n");
+			/* The request cannot be completed (ie
+			 * ret == 0) on the first call
+			 */
+			return ret ? ret : -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int usbf_epn_queue(struct usbf_ep *ep, struct usbf_req *req,
+			  gfp_t gfp_flags)
+{
+	int was_empty;
+	int ret;
+
+	if (ep->disabled) {
+		dev_err(ep->udc->dev, "ep%d request queue while disable\n",
+			ep->id);
+		return -ESHUTDOWN;
+	}
+
+	req->req.actual = 0;
+	req->req.status = -EINPROGRESS;
+	req->is_zero_sent = 0;
+	req->xfer_step = USBF_XFER_START;
+
+	was_empty = list_empty(&ep->queue);
+	list_add_tail(&req->queue, &ep->queue);
+	if (was_empty) {
+		ret = usbf_epn_start_queue(ep);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static int usbf_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+			 gfp_t gfp_flags)
+{
+	struct usbf_req *req = container_of(_req, struct usbf_req, req);
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	struct usbf_udc *udc = ep->udc;
+	unsigned long flags;
+	int ret;
+
+	if (!_req || !_req->buf) {
+		TRACEEP(ep, "ep%d invalid request\n", ep->id);
+		return -EINVAL;
+	}
+
+	if (!udc || !udc->driver) {
+		TRACEEP(ep, "ep%d invalid device\n", ep->id);
+		return -EINVAL;
+	}
+
+	TRACEEP(ep, "ep%d %s req queue length %u, zero %u, short_not_ok %u\n",
+		ep->id, ep->is_in ? "in" : "out",
+		req->req.length, req->req.zero, req->req.short_not_ok);
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	if (ep->id == 0)
+		ret = usbf_ep0_queue(ep, req, gfp_flags);
+	else
+		ret = usbf_epn_queue(ep, req, gfp_flags);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return ret;
+}
+
+static int usbf_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct usbf_req *req = container_of(_req, struct usbf_req, req);
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	unsigned long flags;
+	int is_processing;
+	int first;
+	int ret;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	TRACEEP(ep, "ep%d %s req dequeue length %u/%u\n",
+		ep->id, ep->is_in ? "in" : "out",
+		req->req.actual, req->req.length);
+
+	first = list_is_first(&req->queue, &ep->queue);
+
+	/* Complete the request but avoid any operation that could be done
+	 * if a new request is queued during the request completion
+	 */
+	is_processing = ep->is_processing;
+	ep->is_processing = 1;
+	usbf_ep_req_done(ep, req, -ECONNRESET);
+	ep->is_processing = is_processing;
+
+	if (first) {
+		/* The first item in the list was dequeued.
+		 * This item could already be submitted to the hardware.
+		 * So, flush the fifo
+		 */
+		if (ep->id)
+			usbf_epn_fifo_flush(ep);
+		else
+			usbf_ep0_fifo_flush(ep);
+	}
+
+	if (ep->id == 0) {
+		/* We dequeue a request on ep0. On this endpoint, we can have
+		 * 1 request related to the data stage and/or 1 request
+		 * related to the status stage.
+		 * We dequeue one of them and so the USB control transaction
+		 * is no more coherent. The simple way to be consistent after
+		 * dequeuing is to stall and nuke the endpoint and wait the
+		 * next SETUP packet.
+		 */
+		usbf_ep_stall(ep, true);
+		usbf_ep_nuke(ep, -ECONNRESET);
+		ep->udc->ep0state = EP0_IDLE;
+		goto end;
+	}
+
+	if (!first)
+		goto end;
+
+	ret = usbf_epn_start_queue(ep);
+	if (ret) {
+		usbf_ep_stall(ep, true);
+		usbf_ep_nuke(ep, -EIO);
+	}
+end:
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return 0;
+}
+
+static struct usb_request *usbf_ep_alloc_request(struct usb_ep *_ep,
+						 gfp_t gfp_flags)
+{
+	struct usbf_req *req;
+
+	if (!_ep)
+		return NULL;
+
+	req = kzalloc(sizeof(*req), gfp_flags);
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void usbf_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct usbf_req *req;
+	unsigned long flags;
+	struct usbf_ep *ep;
+
+	if (!_ep || !_req)
+		return;
+
+	req = container_of(_req, struct usbf_req, req);
+	ep = container_of(_ep, struct usbf_ep, ep);
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	list_del_init(&req->queue);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	kfree(req);
+}
+
+static int usbf_ep_set_halt(struct usb_ep *_ep, int halt)
+{
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	unsigned long flags;
+	int ret;
+
+	if (ep->id == 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	if (!list_empty(&ep->queue)) {
+		ret = -EAGAIN;
+		goto end;
+	}
+
+	usbf_ep_stall(ep, halt);
+	if (!halt)
+		ep->is_wedged = 0;
+
+	ret = 0;
+end:
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return ret;
+}
+
+static int usbf_ep_set_wedge(struct usb_ep *_ep)
+{
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+	unsigned long flags;
+	int ret;
+
+	if (ep->id == 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	if (!list_empty(&ep->queue)) {
+		ret = -EAGAIN;
+		goto end;
+	}
+	usbf_ep_stall(ep, 1);
+	ep->is_wedged = 1;
+
+	ret = 0;
+end:
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return ret;
+}
+
+static struct usb_ep_ops usbf_ep_ops = {
+	.enable = usbf_ep_enable,
+	.disable = usbf_ep_disable,
+	.queue = usbf_ep_queue,
+	.dequeue = usbf_ep_dequeue,
+	.set_halt = usbf_ep_set_halt,
+	.set_wedge = usbf_ep_set_wedge,
+	.alloc_request = usbf_ep_alloc_request,
+	.free_request = usbf_ep_free_request,
+};
+
+static void usbf_ep0_req_complete(struct usb_ep *_ep, struct usb_request *_req)
+{
+}
+
+static void usbf_ep0_fill_req(struct usbf_ep *ep0, struct usbf_req *req,
+			      void *buf, unsigned int length,
+			      void (*complete)(struct usb_ep *_ep,
+					       struct usb_request *_req))
+{
+	if (buf && length)
+		memcpy(ep0->udc->ep0_buf, buf, length);
+
+	req->req.buf = ep0->udc->ep0_buf;
+	req->req.length = length;
+	req->req.dma = 0;
+	req->req.zero = true;
+	req->req.complete = complete ? complete : usbf_ep0_req_complete;
+	req->req.status = -EINPROGRESS;
+	req->req.context = NULL;
+	req->req.actual = 0;
+}
+
+static struct usbf_ep *usbf_get_ep_by_addr(struct usbf_udc *udc, u8 address)
+{
+	struct usbf_ep *ep;
+	unsigned int i;
+
+	if ((address & USB_ENDPOINT_NUMBER_MASK) == 0)
+		return &udc->ep[0];
+
+	for (i = 1; i < ARRAY_SIZE(udc->ep); i++) {
+		ep = &udc->ep[i];
+
+		if (!ep->ep.desc)
+			continue;
+
+		if (ep->ep.desc->bEndpointAddress == address)
+			return ep;
+	}
+
+	return NULL;
+}
+
+static int usbf_req_delegate(struct usbf_udc *udc,
+			     const struct usb_ctrlrequest *ctrlrequest)
+{
+	int ret;
+
+	spin_unlock(&udc->lock);
+	ret = udc->driver->setup(&udc->gadget, ctrlrequest);
+	spin_lock(&udc->lock);
+	if (ret < 0) {
+		TRACEEP(&udc->ep[0], "udc driver setup failed %d\n", ret);
+		return ret;
+	}
+	if (ret == USB_GADGET_DELAYED_STATUS) {
+		TRACEEP(&udc->ep[0], "delayed status set\n");
+		udc->ep[0].delayed_status = 1;
+		return 0;
+	}
+	return ret;
+}
+
+static int usbf_req_get_status(struct usbf_udc *udc,
+			       const struct usb_ctrlrequest *ctrlrequest)
+{
+	struct usbf_ep *ep;
+	u16 status_data;
+	u16 wLength;
+	u16 wValue;
+	u16 wIndex;
+
+	wValue  = le16_to_cpu(ctrlrequest->wValue);
+	wLength = le16_to_cpu(ctrlrequest->wLength);
+	wIndex  = le16_to_cpu(ctrlrequest->wIndex);
+
+	switch (ctrlrequest->bRequestType) {
+	case USB_DIR_IN | USB_RECIP_DEVICE | USB_TYPE_STANDARD:
+		if ((wValue != 0) || (wIndex != 0) || (wLength != 2))
+			goto delegate;
+
+		status_data = 0;
+		if (udc->gadget.is_selfpowered)
+			status_data |= BIT(USB_DEVICE_SELF_POWERED);
+
+		if (udc->is_remote_wakeup)
+			status_data |= BIT(USB_DEVICE_REMOTE_WAKEUP);
+
+		break;
+
+	case USB_DIR_IN | USB_RECIP_ENDPOINT | USB_TYPE_STANDARD:
+		if ((wValue != 0) || (wLength != 2))
+			goto delegate;
+
+		ep = usbf_get_ep_by_addr(udc, wIndex);
+		if (!ep)
+			return -EINVAL;
+
+		status_data = 0;
+		if (usbf_ep_is_stalled(ep))
+			status_data |= cpu_to_le16(1);
+		break;
+
+	case USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_STANDARD:
+		if ((wValue != 0) || (wLength != 2))
+			goto delegate;
+		status_data = 0;
+		break;
+
+	default:
+		goto delegate;
+	}
+
+	usbf_ep0_fill_req(&udc->ep[0], &udc->setup_reply, &status_data,
+			  sizeof(status_data), NULL);
+	usbf_ep0_queue(&udc->ep[0], &udc->setup_reply, GFP_ATOMIC);
+
+	return 0;
+
+delegate:
+	return usbf_req_delegate(udc, ctrlrequest);
+}
+
+static int usbf_req_clear_set_feature(struct usbf_udc *udc,
+				      const struct usb_ctrlrequest *ctrlrequest,
+				      bool is_set)
+{
+	struct usbf_ep *ep;
+	u16 wLength;
+	u16 wValue;
+	u16 wIndex;
+
+	wValue  = le16_to_cpu(ctrlrequest->wValue);
+	wLength = le16_to_cpu(ctrlrequest->wLength);
+	wIndex  = le16_to_cpu(ctrlrequest->wIndex);
+
+	switch (ctrlrequest->bRequestType) {
+	case USB_DIR_OUT | USB_RECIP_DEVICE:
+		if ((wIndex != 0) || (wLength != 0))
+			goto delegate;
+
+		if (wValue != cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+			goto delegate;
+
+		udc->is_remote_wakeup = is_set;
+		break;
+
+	case USB_DIR_OUT | USB_RECIP_ENDPOINT:
+		if (wLength != 0)
+			goto delegate;
+
+		ep = usbf_get_ep_by_addr(udc, wIndex);
+		if (!ep)
+			return -EINVAL;
+
+		if ((ep->id == 0) && is_set) {
+			/* Endpoint 0 cannot be halted (stalled)
+			 * Returning an error code leads to a STALL on this ep0
+			 * but keep the automate in a consistent state.
+			 */
+			return -EINVAL;
+		}
+		if (ep->is_wedged && !is_set) {
+			/* Ignore CLEAR_FEATURE(HALT ENDPOINT) when the
+			 * endpoint is wedged
+			 */
+			break;
+		}
+		usbf_ep_stall(ep, is_set);
+		break;
+
+	default:
+		goto delegate;
+	}
+
+	return 0;
+
+delegate:
+	return usbf_req_delegate(udc, ctrlrequest);
+}
+
+static void usbf_ep0_req_set_address_complete(struct usb_ep *_ep,
+					      struct usb_request *_req)
+{
+	struct usbf_ep *ep = container_of(_ep, struct usbf_ep, ep);
+
+	/* The status phase of the SET_ADDRESS request is completed ... */
+	if (_req->status == 0) {
+		/* ... without any errors -> Signaled the state to the core. */
+		usb_gadget_set_state(&ep->udc->gadget, USB_STATE_ADDRESS);
+	}
+
+	/* In case of request failure, there is no need to revert the address
+	 * value set to the hardware as the hardware will take care of the
+	 * value only if the status stage is completed normally.
+	 */
+}
+
+static int usbf_req_set_address(struct usbf_udc *udc,
+				const struct usb_ctrlrequest *ctrlrequest)
+{
+	u16 wLength;
+	u16 wValue;
+	u16 wIndex;
+	u32 addr;
+
+	wValue  = le16_to_cpu(ctrlrequest->wValue);
+	wLength = le16_to_cpu(ctrlrequest->wLength);
+	wIndex  = le16_to_cpu(ctrlrequest->wIndex);
+
+	if (ctrlrequest->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
+		goto delegate;
+
+	if ((wIndex != 0) || (wLength != 0) || (wValue > 127))
+		return -EINVAL;
+
+	addr = wValue;
+	/* The hardware will take care of this USB address after the status
+	 * stage of the SET_ADDRESS request is completed normally.
+	 * It is safe to write it now
+	 */
+	usbf_reg_writel(udc, USBF_REG_USB_ADDRESS, USBF_USB_SET_USB_ADDR(addr));
+
+	/* Queued the status request */
+	usbf_ep0_fill_req(&udc->ep[0], &udc->setup_reply, NULL, 0,
+			  usbf_ep0_req_set_address_complete);
+	usbf_ep0_queue(&udc->ep[0], &udc->setup_reply, GFP_ATOMIC);
+
+	return 0;
+
+delegate:
+	return usbf_req_delegate(udc, ctrlrequest);
+}
+
+static int usbf_req_set_configuration(struct usbf_udc *udc,
+				      const struct usb_ctrlrequest *ctrlrequest)
+{
+	u16 wLength;
+	u16 wValue;
+	u16 wIndex;
+	int ret;
+
+	ret = usbf_req_delegate(udc, ctrlrequest);
+	if (ret)
+		return ret;
+
+	wValue  = le16_to_cpu(ctrlrequest->wValue);
+	wLength = le16_to_cpu(ctrlrequest->wLength);
+	wIndex  = le16_to_cpu(ctrlrequest->wIndex);
+
+	if ((ctrlrequest->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE)) ||
+	    (wIndex != 0) || (wLength != 0)) {
+		/* No error detected by driver->setup() but it is not an USB2.0
+		 * Ch9 SET_CONFIGURATION.
+		 * Nothing more to do
+		 */
+		return 0;
+	}
+
+	if (wValue & 0x00FF) {
+		usbf_reg_bitset(udc, USBF_REG_USB_CONTROL, USBF_USB_CONF);
+	} else {
+		usbf_reg_bitclr(udc, USBF_REG_USB_CONTROL, USBF_USB_CONF);
+		/* Go back to Address State */
+		spin_unlock(&udc->lock);
+		usb_gadget_set_state(&udc->gadget, USB_STATE_ADDRESS);
+		spin_lock(&udc->lock);
+	}
+
+	return 0;
+}
+
+static int usbf_handle_ep0_setup(struct usbf_ep *ep0)
+{
+	union {
+		struct usb_ctrlrequest ctrlreq;
+		u32 raw[2];
+	} crq;
+	struct usbf_udc *udc = ep0->udc;
+	int ret;
+
+	/* Read setup data (ie the USB control request) */
+	crq.raw[0] = usbf_reg_readl(udc, USBF_REG_SETUP_DATA0);
+	crq.raw[1] = usbf_reg_readl(udc, USBF_REG_SETUP_DATA1);
+
+	TRACEEP(ep0,
+		"req%02x.%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\n",
+		crq.ctrlreq.bRequestType, crq.ctrlreq.bRequest,
+		crq.ctrlreq.wValue, crq.ctrlreq.wIndex, crq.ctrlreq.wLength);
+
+	/* Set current EP0 state according to the received request */
+	if (crq.ctrlreq.wLength) {
+		if (crq.ctrlreq.bRequestType & USB_DIR_IN) {
+			udc->ep0state = EP0_IN_DATA_PHASE;
+			usbf_ep_reg_clrset(ep0, USBF_REG_EP0_CONTROL,
+				USBF_EP0_INAK,
+				USBF_EP0_INAK_EN);
+			ep0->is_in = 1;
+		} else {
+			udc->ep0state = EP0_OUT_DATA_PHASE;
+			usbf_ep_reg_bitclr(ep0, USBF_REG_EP0_CONTROL,
+				USBF_EP0_ONAK);
+			ep0->is_in = 0;
+		}
+	} else {
+		udc->ep0state = EP0_IN_STATUS_START_PHASE;
+		ep0->is_in = 1;
+	}
+
+	/* We starts a new control transfer -> Clear the delayed status flag */
+	ep0->delayed_status = 0;
+
+	if ((crq.ctrlreq.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
+		/* This is not a USB standard request -> delelate */
+		goto delegate;
+	}
+
+	switch (crq.ctrlreq.bRequest) {
+	case USB_REQ_GET_STATUS:
+		ret = usbf_req_get_status(udc, &crq.ctrlreq);
+		break;
+
+	case USB_REQ_CLEAR_FEATURE:
+		ret = usbf_req_clear_set_feature(udc, &crq.ctrlreq, false);
+		break;
+
+	case USB_REQ_SET_FEATURE:
+		ret = usbf_req_clear_set_feature(udc, &crq.ctrlreq, true);
+		break;
+
+	case USB_REQ_SET_ADDRESS:
+		ret = usbf_req_set_address(udc, &crq.ctrlreq);
+		break;
+
+	case USB_REQ_SET_CONFIGURATION:
+		ret = usbf_req_set_configuration(udc, &crq.ctrlreq);
+		break;
+
+	default:
+		goto delegate;
+	}
+
+	return ret;
+
+delegate:
+	return usbf_req_delegate(udc, &crq.ctrlreq);
+}
+
+static int usbf_handle_ep0_data_status(struct usbf_ep *ep0,
+				  const char *ep0state_name,
+				  enum usbf_ep0state next_ep0state)
+{
+	struct usbf_udc *udc = ep0->udc;
+	int ret;
+
+	ret = usbf_ep_process_queue(ep0);
+	switch (ret) {
+	case -ENOENT:
+		dev_err(udc->dev,
+			"no request available for ep0 %s phase\n",
+			ep0state_name);
+		break;
+	case -EINPROGRESS:
+		/* More data needs to be processed */
+		ret = 0;
+		break;
+	case 0:
+		/* All requests in the queue are processed */
+		udc->ep0state = next_ep0state;
+		break;
+	default:
+		dev_err(udc->dev,
+			"process queue failed for ep0 %s phase (%d)\n",
+			ep0state_name, ret);
+		break;
+	}
+	return ret;
+}
+
+static int usbf_handle_ep0_out_status_start(struct usbf_ep *ep0)
+{
+	struct usbf_udc *udc = ep0->udc;
+	struct usbf_req *req;
+
+	usbf_ep_reg_clrset(ep0, USBF_REG_EP0_CONTROL,
+				USBF_EP0_ONAK,
+				USBF_EP0_PIDCLR);
+	ep0->is_in = 0;
+
+	req = list_first_entry_or_null(&ep0->queue, struct usbf_req, queue);
+	if (!req) {
+		usbf_ep0_fill_req(ep0, &udc->setup_reply, NULL, 0, NULL);
+		usbf_ep0_queue(ep0, &udc->setup_reply, GFP_ATOMIC);
+	} else {
+		if (req->req.length) {
+			dev_err(udc->dev,
+				"queued request length %u for ep0 out status phase\n",
+				req->req.length);
+		}
+	}
+	udc->ep0state = EP0_OUT_STATUS_PHASE;
+	return 0;
+}
+
+static int usbf_handle_ep0_in_status_start(struct usbf_ep *ep0)
+{
+	struct usbf_udc *udc = ep0->udc;
+	struct usbf_req *req;
+	int ret;
+
+	usbf_ep_reg_clrset(ep0, USBF_REG_EP0_CONTROL,
+				USBF_EP0_INAK,
+				USBF_EP0_INAK_EN | USBF_EP0_PIDCLR);
+	ep0->is_in = 1;
+
+	/* Queue request for status if needed */
+	req = list_first_entry_or_null(&ep0->queue, struct usbf_req, queue);
+	if (!req) {
+		if (ep0->delayed_status) {
+			TRACEEP(ep0,
+				"EP0_IN_STATUS_START_PHASE ep0->delayed_status set\n");
+			udc->ep0state = EP0_IN_STATUS_PHASE;
+			return 0;
+		}
+
+		usbf_ep0_fill_req(ep0, &udc->setup_reply, NULL,
+			  0, NULL);
+		usbf_ep0_queue(ep0, &udc->setup_reply,
+			       GFP_ATOMIC);
+
+		req = list_first_entry_or_null(&ep0->queue, struct usbf_req, queue);
+	} else {
+		if (req->req.length) {
+			dev_err(udc->dev,
+				"queued request length %u for ep0 in status phase\n",
+				req->req.length);
+		}
+	}
+
+	ret = usbf_ep0_pio_in(ep0, req);
+	if (ret != -EINPROGRESS) {
+		usbf_ep_req_done(ep0, req, ret);
+		udc->ep0state = EP0_IN_STATUS_END_PHASE;
+		return 0;
+	}
+
+	udc->ep0state = EP0_IN_STATUS_PHASE;
+	return 0;
+}
+
+static void usbf_ep0_interrupt(struct usbf_ep *ep0)
+{
+	struct usbf_udc *udc = ep0->udc;
+	u32 sts, prev_sts;
+	int prev_ep0state;
+	int ret;
+
+	ep0->status = usbf_ep_reg_readl(ep0, USBF_REG_EP0_STATUS);
+	usbf_ep_reg_writel(ep0, USBF_REG_EP0_STATUS, ~ep0->status);
+
+	TRACEEP(ep0, "ep0 status=0x%08x, enable=%08x\n, ctrl=0x%08x\n",
+		ep0->status,
+		usbf_ep_reg_readl(ep0, USBF_REG_EP0_INT_ENA),
+		usbf_ep_reg_readl(ep0, USBF_REG_EP0_CONTROL));
+
+	sts = ep0->status & (USBF_EP0_SETUP_INT | USBF_EP0_IN_INT | USBF_EP0_OUT_INT |
+			     USBF_EP0_OUT_NULL_INT | USBF_EP0_STG_START_INT |
+			     USBF_EP0_STG_END_INT);
+
+	ret = 0;
+	do {
+		TRACEEP(ep0, "udc->ep0state=%d\n", udc->ep0state);
+
+		prev_sts = sts;
+		prev_ep0state = udc->ep0state;
+		switch (udc->ep0state) {
+		case EP0_IDLE:
+			if (!(sts & USBF_EP0_SETUP_INT))
+				break;
+
+			sts &= ~USBF_EP0_SETUP_INT;
+			TRACEEP(ep0, "handle setup\n");
+			ret = usbf_handle_ep0_setup(ep0);
+			break;
+
+		case EP0_IN_DATA_PHASE:
+			if (!(sts & USBF_EP0_IN_INT))
+				break;
+
+			sts &= ~USBF_EP0_IN_INT;
+			TRACEEP(ep0, "handle in data phase\n");
+			ret = usbf_handle_ep0_data_status(ep0,
+				"in data", EP0_OUT_STATUS_START_PHASE);
+			break;
+
+		case EP0_OUT_STATUS_START_PHASE:
+			if (!(sts & USBF_EP0_STG_START_INT))
+				break;
+
+			sts &= ~USBF_EP0_STG_START_INT;
+			TRACEEP(ep0, "handle out status start phase\n");
+			ret = usbf_handle_ep0_out_status_start(ep0);
+			break;
+
+		case EP0_OUT_STATUS_PHASE:
+			if (!(sts & (USBF_EP0_OUT_INT | USBF_EP0_OUT_NULL_INT)))
+				break;
+
+			sts &= ~(USBF_EP0_OUT_INT | USBF_EP0_OUT_NULL_INT);
+			TRACEEP(ep0, "handle out status phase\n");
+			ret = usbf_handle_ep0_data_status(ep0,
+				"out status",
+				EP0_OUT_STATUS_END_PHASE);
+			break;
+
+		case EP0_OUT_STATUS_END_PHASE:
+			if (!(sts & (USBF_EP0_STG_END_INT | USBF_EP0_SETUP_INT)))
+				break;
+
+			sts &= ~USBF_EP0_STG_END_INT;
+			TRACEEP(ep0, "handle out status end phase\n");
+			udc->ep0state = EP0_IDLE;
+			break;
+
+		case EP0_OUT_DATA_PHASE:
+			if (!(sts & (USBF_EP0_OUT_INT | USBF_EP0_OUT_NULL_INT)))
+				break;
+
+			sts &= ~(USBF_EP0_OUT_INT | USBF_EP0_OUT_NULL_INT);
+			TRACEEP(ep0, "handle out data phase\n");
+			ret = usbf_handle_ep0_data_status(ep0,
+				"out data", EP0_IN_STATUS_START_PHASE);
+			break;
+
+		case EP0_IN_STATUS_START_PHASE:
+			if (!(sts & USBF_EP0_STG_START_INT))
+				break;
+
+			sts &= ~USBF_EP0_STG_START_INT;
+			TRACEEP(ep0, "handle in status start phase\n");
+			ret = usbf_handle_ep0_in_status_start(ep0);
+			break;
+
+		case EP0_IN_STATUS_PHASE:
+			if (!(sts & USBF_EP0_IN_INT))
+				break;
+
+			sts &= ~USBF_EP0_IN_INT;
+			TRACEEP(ep0, "handle in status phase\n");
+			ret = usbf_handle_ep0_data_status(ep0,
+				"in status", EP0_IN_STATUS_END_PHASE);
+			break;
+
+		case EP0_IN_STATUS_END_PHASE:
+			if (!(sts & (USBF_EP0_STG_END_INT | USBF_EP0_SETUP_INT)))
+				break;
+
+			sts &= ~USBF_EP0_STG_END_INT;
+			TRACEEP(ep0, "handle in status end\n");
+			udc->ep0state = EP0_IDLE;
+			break;
+
+		default:
+			udc->ep0state = EP0_IDLE;
+			break;
+		}
+
+		if (ret) {
+			TRACEEP(ep0, "failed (%d)\n", ret);
+			/* Failure -> stall.
+			 * This stall state will be automatically cleared when
+			 * the IP receives the next SETUP packet
+			 */
+			usbf_ep_stall(ep0, true);
+
+			/* Remove anything that was pending */
+			usbf_ep_nuke(ep0, -EPROTO);
+
+			udc->ep0state = EP0_IDLE;
+			break;
+		}
+
+	} while ((prev_ep0state != udc->ep0state) || (prev_sts != sts));
+
+	TRACEEP(ep0, "done udc->ep0state=%d, status=0x%08x. next=0x%08x\n",
+		udc->ep0state, sts,
+		usbf_ep_reg_readl(ep0, USBF_REG_EP0_STATUS));
+}
+
+static void usbf_epn_process_queue(struct usbf_ep *epn)
+{
+	int ret;
+
+	ret = usbf_ep_process_queue(epn);
+	switch (ret) {
+	case -ENOENT:
+		dev_warn(epn->udc->dev, "ep%d %s, no request available\n",
+			epn->id, epn->is_in ? "in" : "out");
+		break;
+	case -EINPROGRESS:
+		/* More data needs to be processed */
+		ret = 0;
+		break;
+	case 0:
+		/* All requests in the queue are processed */
+		break;
+	default:
+		dev_err(epn->udc->dev, "ep%d %s, process queue failed (%d)\n",
+			epn->id, epn->is_in ? "in" : "out", ret);
+		break;
+	}
+
+	if (ret) {
+		TRACEEP(epn, "ep%d %s failed (%d)\n", epn->id,
+			epn->is_in ? "in" : "out", ret);
+		usbf_ep_stall(epn, true);
+		usbf_ep_nuke(epn, ret);
+	}
+}
+
+static void usbf_epn_interrupt(struct usbf_ep *epn)
+{
+	u32 sts;
+	u32 ena;
+
+	epn->status = usbf_ep_reg_readl(epn, USBF_REG_EPN_STATUS);
+	ena = usbf_ep_reg_readl(epn, USBF_REG_EPN_INT_ENA);
+	usbf_ep_reg_writel(epn, USBF_REG_EPN_STATUS, ~(epn->status & ena));
+
+	TRACEEP(epn, "ep%d %s status=0x%08x, enable=%08x\n, ctrl=0x%08x\n",
+		epn->id, epn->is_in ? "in" : "out", epn->status, ena,
+		usbf_ep_reg_readl(epn, USBF_REG_EPN_CONTROL));
+
+	if (epn->disabled) {
+		dev_warn(epn->udc->dev, "ep%d %s, interrupt while disabled\n",
+			epn->id, epn->is_in ? "in" : "out");
+		return;
+	}
+
+	sts = epn->status & ena;
+
+	if (sts & (USBF_EPN_IN_END_INT | USBF_EPN_IN_INT)) {
+		sts &= ~(USBF_EPN_IN_END_INT | USBF_EPN_IN_INT);
+		TRACEEP(epn, "ep%d %s process queue (in interrupts)\n",
+			epn->id, epn->is_in ? "in" : "out");
+		usbf_epn_process_queue(epn);
+	}
+
+	if (sts & (USBF_EPN_OUT_END_INT | USBF_EPN_OUT_INT | USBF_EPN_OUT_NULL_INT)) {
+		sts &= ~(USBF_EPN_OUT_END_INT | USBF_EPN_OUT_INT | USBF_EPN_OUT_NULL_INT);
+		TRACEEP(epn, "ep%d %s process queue (out interrupts)\n",
+			epn->id, epn->is_in ? "in" : "out");
+		usbf_epn_process_queue(epn);
+	}
+
+	TRACEEP(epn, "ep%d %s done status=0x%08x. next=0x%08x\n",
+		epn->id, epn->is_in ? "in" : "out",
+		sts, usbf_ep_reg_readl(epn, USBF_REG_EPN_STATUS));
+}
+
+static void usbf_ep_reset(struct usbf_ep *ep)
+{
+	ep->status = 0;
+	/* Remove anything that was pending */
+	usbf_ep_nuke(ep, -ESHUTDOWN);
+}
+
+static void usbf_reset(struct usbf_udc *udc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(udc->ep); i++) {
+		if (udc->ep[i].disabled)
+			continue;
+
+		usbf_ep_reset(&udc->ep[i]);
+	}
+
+	if (usbf_reg_readl(udc, USBF_REG_USB_STATUS) & USBF_USB_SPEED_MODE)
+		udc->gadget.speed = USB_SPEED_HIGH;
+	else
+		udc->gadget.speed = USB_SPEED_FULL;
+
+	/* Remote wakeup feature must be disabled on USB bus reset */
+	udc->is_remote_wakeup = false;
+
+	/* Enable endpoint zero */
+	usbf_ep0_enable(&udc->ep[0]);
+
+	if (udc->driver) {
+		/* Signal the reset */
+		spin_unlock(&udc->lock);
+		usb_gadget_udc_reset(&udc->gadget, udc->driver);
+		spin_lock(&udc->lock);
+	}
+}
+
+static void usbf_driver_suspend(struct usbf_udc *udc)
+{
+	if (udc->is_usb_suspended) {
+		TRACE("already suspended\n");
+		return;
+	}
+
+	TRACE("do usb suspend\n");
+	udc->is_usb_suspended = true;
+
+	if (udc->driver && udc->driver->suspend) {
+		spin_unlock(&udc->lock);
+		udc->driver->suspend(&udc->gadget);
+		spin_lock(&udc->lock);
+
+		/* The datasheet tells to set the USB_CONTROL register SUSPEND
+		 * bit when the USB bus suspend is detected.
+		 * This bit stops the clocks (clocks for EPC, SIE, USBPHY) but
+		 * these clocks seems not used only by the USB device. Some
+		 * UARTs can be lost ...
+		 * So, do not set the USB_CONTROL register SUSPEND bit.
+		 */
+	}
+}
+
+static void usbf_driver_resume(struct usbf_udc *udc)
+{
+	if (!udc->is_usb_suspended)
+		return;
+
+	TRACE("do usb resume\n");
+	udc->is_usb_suspended = false;
+
+	if (udc->driver && udc->driver->resume) {
+		spin_unlock(&udc->lock);
+		udc->driver->resume(&udc->gadget);
+		spin_lock(&udc->lock);
+	}
+}
+
+static irqreturn_t usbf_epc_irq(int irq, void *_udc)
+{
+	struct usbf_udc *udc = (struct usbf_udc *)_udc;
+	unsigned long flags;
+	struct usbf_ep *ep;
+	u32 int_sts;
+	u32 int_en;
+	int i;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	int_en = usbf_reg_readl(udc, USBF_REG_USB_INT_ENA);
+	int_sts = usbf_reg_readl(udc, USBF_REG_USB_INT_STA) & int_en;
+	usbf_reg_writel(udc, USBF_REG_USB_INT_STA, ~int_sts);
+
+	TRACE("int_sts=0x%08x\n", int_sts);
+
+	if (int_sts & USBF_USB_RSUM_INT) {
+		TRACE("handle resume\n");
+		usbf_driver_resume(udc);
+	}
+
+	if (int_sts & USBF_USB_USB_RST_INT) {
+		TRACE("handle bus reset\n");
+		usbf_driver_resume(udc);
+		usbf_reset(udc);
+	}
+
+	if (int_sts & USBF_USB_SPEED_MODE_INT) {
+		if (usbf_reg_readl(udc, USBF_REG_USB_STATUS) & USBF_USB_SPEED_MODE)
+			udc->gadget.speed = USB_SPEED_HIGH;
+		else
+			udc->gadget.speed = USB_SPEED_FULL;
+		TRACE("handle speed change (%s)\n",
+		      udc->gadget.speed == USB_SPEED_HIGH ? "High" : "Full");
+	}
+
+	if (int_sts & USBF_USB_EPN_INT(0)) {
+		usbf_driver_resume(udc);
+		usbf_ep0_interrupt(&udc->ep[0]);
+	}
+
+	for (i = 1; i < ARRAY_SIZE(udc->ep); i++) {
+		ep = &udc->ep[i];
+
+		if (int_sts & USBF_USB_EPN_INT(i)) {
+			usbf_driver_resume(udc);
+			usbf_epn_interrupt(ep);
+		}
+	}
+
+	if (int_sts & USBF_USB_SPND_INT) {
+		TRACE("handle suspend\n");
+		usbf_driver_suspend(udc);
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t usbf_ahb_epc_irq(int irq, void *_udc)
+{
+	struct usbf_udc *udc = (struct usbf_udc *)_udc;
+	unsigned long flags;
+	struct usbf_ep *epn;
+	u32 sysbint;
+	void (*ep_action)(struct usbf_ep *epn);
+	int i;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* Read and ack interrupts */
+	sysbint = usbf_reg_readl(udc, USBF_REG_AHBBINT);
+	usbf_reg_writel(udc, USBF_REG_AHBBINT, sysbint);
+
+	if ((sysbint & USBF_SYS_VBUS_INT) == USBF_SYS_VBUS_INT) {
+		if (usbf_reg_readl(udc, USBF_REG_EPCTR) & USBF_SYS_VBUS_LEVEL) {
+			TRACE("handle vbus (1)\n");
+			spin_unlock(&udc->lock);
+			usb_udc_vbus_handler(&udc->gadget, true);
+			usb_gadget_set_state(&udc->gadget, USB_STATE_POWERED);
+			spin_lock(&udc->lock);
+		} else {
+			TRACE("handle vbus (0)\n");
+			udc->is_usb_suspended = false;
+			spin_unlock(&udc->lock);
+			usb_udc_vbus_handler(&udc->gadget, false);
+			usb_gadget_set_state(&udc->gadget,
+					     USB_STATE_NOTATTACHED);
+			spin_lock(&udc->lock);
+		}
+	}
+
+	for (i = 1; i < ARRAY_SIZE(udc->ep); i++) {
+		if (sysbint & USBF_SYS_DMA_ENDINT_EPN(i)) {
+			epn = &udc->ep[i];
+			TRACEEP(epn,
+				"ep%d handle DMA complete. action=%ps\n",
+				epn->id, epn->bridge_on_dma_end);
+			ep_action = epn->bridge_on_dma_end;
+			if (ep_action) {
+				epn->bridge_on_dma_end = NULL;
+				ep_action(epn);
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int usbf_udc_start(struct usb_gadget *gadget,
+			  struct usb_gadget_driver *driver)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+	unsigned long flags;
+
+	dev_info(udc->dev, "start (driver '%s')\n", driver->driver.name);
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* hook up the driver */
+	udc->driver = driver;
+
+	/* Enable VBUS interrupt */
+	usbf_reg_writel(udc, USBF_REG_AHBBINTEN, USBF_SYS_VBUS_INTEN);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int usbf_udc_stop(struct usb_gadget *gadget)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* Disable VBUS interrupt */
+	usbf_reg_writel(udc, USBF_REG_AHBBINTEN, 0);
+
+	udc->driver = NULL;
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	dev_info(udc->dev, "stopped\n");
+
+	return 0;
+}
+
+static int usbf_get_frame(struct usb_gadget *gadget)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+
+	return USBF_USB_GET_FRAME(usbf_reg_readl(udc, USBF_REG_USB_ADDRESS));
+}
+
+static void usbf_attach(struct usbf_udc *udc)
+{
+	/* Enable USB signal to Function PHY
+	 * D+ signal Pull-up
+	 * Disable endpoint 0, it will be automatically enable when a USB reset
+	 * is received.
+	 * Disable the other endpoints
+	 */
+	usbf_reg_clrset(udc, USBF_REG_USB_CONTROL,
+		USBF_USB_CONNECTB | USBF_USB_DEFAULT | USBF_USB_CONF,
+		USBF_USB_PUE2);
+
+	/* Enable reset and mode change interrupts */
+	usbf_reg_bitset(udc, USBF_REG_USB_INT_ENA,
+		USBF_USB_USB_RST_EN | USBF_USB_SPEED_MODE_EN | USBF_USB_RSUM_EN | USBF_USB_SPND_EN);
+}
+
+static void usbf_detach(struct usbf_udc *udc)
+{
+	int i;
+
+	/* Disable interrupts */
+	usbf_reg_writel(udc, USBF_REG_USB_INT_ENA, 0);
+
+	for (i = 0; i < ARRAY_SIZE(udc->ep); i++) {
+		if (udc->ep[i].disabled)
+			continue;
+
+		usbf_ep_reset(&udc->ep[i]);
+	}
+
+	/* Disable USB signal to Function PHY
+	 * Do not Pull-up D+ signal
+	 * Disable endpoint 0
+	 * Disable the other endpoints
+	 */
+	usbf_reg_clrset(udc, USBF_REG_USB_CONTROL,
+		USBF_USB_PUE2 | USBF_USB_DEFAULT | USBF_USB_CONF,
+		USBF_USB_CONNECTB);
+}
+
+static int usbf_pullup(struct usb_gadget *gadget, int is_on)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+	unsigned long flags;
+
+	TRACE("is_on=%d\n", is_on);
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (is_on)
+		usbf_attach(udc);
+	else
+		usbf_detach(udc);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int usbf_udc_set_selfpowered(struct usb_gadget *gadget,
+				    int is_selfpowered)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	gadget->is_selfpowered = (is_selfpowered != 0);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int usbf_udc_wakeup(struct usb_gadget *gadget)
+{
+	struct usbf_udc *udc = container_of(gadget, struct usbf_udc, gadget);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	if (!udc->is_remote_wakeup) {
+		TRACE("remote wakeup not allowed\n");
+		ret = -EINVAL;
+		goto end;
+	}
+
+	TRACE("do wakeup\n");
+
+	/* Send the resume signal */
+	usbf_reg_bitset(udc, USBF_REG_USB_CONTROL, USBF_USB_RSUM_IN);
+	usbf_reg_bitclr(udc, USBF_REG_USB_CONTROL, USBF_USB_RSUM_IN);
+
+	ret = 0;
+end:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return ret;
+}
+
+static struct usb_gadget_ops usbf_gadget_ops = {
+	.get_frame = usbf_get_frame,
+	.pullup = usbf_pullup,
+	.udc_start = usbf_udc_start,
+	.udc_stop = usbf_udc_stop,
+	.set_selfpowered = usbf_udc_set_selfpowered,
+	.wakeup = usbf_udc_wakeup,
+};
+
+static int usbf_epn_check(struct usbf_ep *epn)
+{
+	const char *type_txt;
+	const char *buf_txt;
+	int ret = 0;
+	u32 ctrl;
+
+	ctrl = usbf_ep_reg_readl(epn, USBF_REG_EPN_CONTROL);
+
+	switch (ctrl & USBF_EPN_MODE_MASK) {
+	case USBF_EPN_MODE_BULK:
+		type_txt = "bulk";
+		if (epn->ep.caps.type_control || epn->ep.caps.type_iso ||
+		    !epn->ep.caps.type_bulk || epn->ep.caps.type_int) {
+			dev_err(epn->udc->dev,
+				"ep%d caps mismatch, bulk expected\n", epn->id);
+			ret = -EINVAL;
+		}
+		break;
+	case USBF_EPN_MODE_INTR:
+		type_txt = "intr";
+		if (epn->ep.caps.type_control || epn->ep.caps.type_iso ||
+		    epn->ep.caps.type_bulk || !epn->ep.caps.type_int) {
+			dev_err(epn->udc->dev,
+				"ep%d caps mismatch, int expected\n", epn->id);
+			ret = -EINVAL;
+		}
+		break;
+	case USBF_EPN_MODE_ISO:
+		type_txt = "iso";
+		if (epn->ep.caps.type_control || !epn->ep.caps.type_iso ||
+		    epn->ep.caps.type_bulk || epn->ep.caps.type_int) {
+			dev_err(epn->udc->dev,
+				"ep%d caps mismatch, iso expected\n", epn->id);
+			ret = -EINVAL;
+		}
+		break;
+	default:
+		type_txt = "unknown";
+		dev_err(epn->udc->dev, "ep%d unknown type\n", epn->id);
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ctrl & USBF_EPN_BUF_TYPE_DOUBLE) {
+		buf_txt = "double";
+		if (!usbf_ep_info[epn->id].is_double) {
+			dev_err(epn->udc->dev,
+				"ep%d buffer mismatch, double expected\n",
+				epn->id);
+			ret = -EINVAL;
+		}
+	} else {
+		buf_txt = "single";
+		if (usbf_ep_info[epn->id].is_double) {
+			dev_err(epn->udc->dev,
+				"ep%d buffer mismatch, single expected\n",
+				epn->id);
+			ret = -EINVAL;
+		}
+	}
+
+	dev_dbg(epn->udc->dev, "ep%d (%s) %s, %s buffer %u, checked %s\n",
+		 epn->id, epn->ep.name, type_txt, buf_txt,
+		 epn->ep.maxpacket_limit, ret ? "failed" : "ok");
+
+	return ret;
+}
+
+static int usbf_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct usbf_udc *udc;
+	struct usbf_ep *ep;
+	int usb_role;
+	int irq;
+	int ret;
+	int i;
+
+	usb_role = r9a06g032_sysctrl_get_usb_role();
+	if (usb_role < 0)
+		return usb_role;
+	if (usb_role != USB_ROLE_DEVICE) {
+		dev_warn(dev, "USB device disabled\n");
+		return -ENODEV;
+	}
+
+	udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL);
+	if (!udc)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, udc);
+
+	udc->dev = dev;
+	spin_lock_init(&udc->lock);
+
+	udc->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(udc->regs))
+		return PTR_ERR(udc->regs);
+
+	devm_pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret < 0)
+		return ret;
+
+	dev_info(dev, "USBF version: %08x\n",
+		usbf_reg_readl(udc, USBF_REG_USBSSVER));
+
+	/* Resetting the PLL is handled via the clock driver as it has common
+	 * registers with USB Host
+	 */
+	usbf_reg_bitclr(udc, USBF_REG_EPCTR, USBF_SYS_EPC_RST);
+
+	/* modify in register gadget process */
+	udc->gadget.speed = USB_SPEED_FULL;
+	udc->gadget.max_speed = USB_SPEED_HIGH;
+	udc->gadget.ops = &usbf_gadget_ops;
+
+	udc->gadget.name = dev->driver->name;
+	udc->gadget.dev.parent = dev;
+	udc->gadget.ep0 = &udc->ep[0].ep;
+
+	/* The hardware DMA controller needs dma addresses aligned on 32bit.
+	 * A fallback to pio is done if DMA addresses are not aligned.
+	 */
+	udc->gadget.quirk_avoids_skb_reserve = 1;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+	/* we have a canned request structure to allow sending packets as reply
+	 * to get_status requests
+	 */
+	INIT_LIST_HEAD(&udc->setup_reply.queue);
+
+	for (i = 0; i < ARRAY_SIZE(udc->ep); i++) {
+		ep = &udc->ep[i];
+
+		if (!(usbf_reg_readl(udc, USBF_REG_USBSSCONF) &
+		      USBF_SYS_EP_AVAILABLE(i))) {
+			continue;
+		}
+
+		INIT_LIST_HEAD(&ep->queue);
+
+		ep->id = i;
+		ep->disabled = 1;
+		ep->udc = udc;
+		ep->ep.ops = &usbf_ep_ops;
+		ep->ep.name = usbf_ep_info[i].name;
+		ep->ep.caps = usbf_ep_info[i].caps;
+		usb_ep_set_maxpacket_limit(&ep->ep,
+					   usbf_ep_info[i].maxpacket_limit);
+
+		if (ep->id == 0) {
+			ep->regs = ep->udc->regs + USBF_BASE_EP0;
+		} else {
+			ep->regs = ep->udc->regs + USBF_BASE_EPN(ep->id - 1);
+			ret = usbf_epn_check(ep);
+			if (ret)
+				return ret;
+			if (usbf_reg_readl(udc, USBF_REG_USBSSCONF) &
+			    USBF_SYS_DMA_AVAILABLE(i)) {
+				ep->dma_regs = ep->udc->regs +
+					       USBF_BASE_DMA_EPN(ep->id - 1);
+			}
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+		}
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+	ret = devm_request_irq(dev, irq, usbf_epc_irq, 0, "usbf-epc", udc);
+	if (ret) {
+		dev_err(dev, "cannot request irq %d err %d\n", irq, ret);
+		return ret;
+	}
+
+	irq = platform_get_irq(pdev, 1);
+	if (irq < 0)
+		return irq;
+	ret = devm_request_irq(dev, irq, usbf_ahb_epc_irq, 0, "usbf-ahb-epc", udc);
+	if (ret) {
+		dev_err(dev, "cannot request irq %d err %d\n", irq, ret);
+		return ret;
+	}
+
+	usbf_reg_bitset(udc, USBF_REG_AHBMCTR, USBF_SYS_WBURST_TYPE);
+
+	usbf_reg_bitset(udc, USBF_REG_USB_CONTROL,
+		USBF_USB_INT_SEL | USBF_USB_SOF_RCV | USBF_USB_SOF_CLK_MODE);
+
+	ret = usb_add_gadget_udc(dev, &udc->gadget);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int usbf_remove(struct platform_device *pdev)
+{
+	struct usbf_udc *udc = platform_get_drvdata(pdev);
+
+	usb_del_gadget_udc(&udc->gadget);
+
+	pm_runtime_put(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id usbf_match[] = {
+	{ .compatible = "renesas,rzn1-usbf" },
+	{} /* sentinel */
+};
+MODULE_DEVICE_TABLE(of, usbf_match);
+
+static struct platform_driver udc_driver = {
+	.driver = {
+		.name = "usbf_renesas",
+		.owner = THIS_MODULE,
+		.of_match_table = usbf_match,
+	},
+	.probe          = usbf_probe,
+	.remove         = usbf_remove,
+};
+
+module_platform_driver(udc_driver);
+
+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
+MODULE_DESCRIPTION("Renesas R-Car Gen3 & RZ/N1 USB Function driver");
+MODULE_LICENSE("GPL");
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
                   ` (4 preceding siblings ...)
  2022-11-14 11:15 ` [PATCH v2 5/7] usb: gadget: udc: add Renesas RZ/N1 USBF controller support Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-15 13:16   ` Krzysztof Kozlowski
  2022-11-16  8:51   ` Geert Uytterhoeven
  2022-11-14 11:15 ` [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry Herve Codina
  6 siblings, 2 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Add the USBF controller available in the r9a06g032 SoC.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index 563024c9a4ae..a4bb069457a3 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
 			};
 		};
 
+		udc: usb@4001e000 {
+			compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
+			reg = <0x4001e000 0x2000>;
+			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&sysctrl R9A06G032_HCLK_USBF>,
+				 <&sysctrl R9A06G032_HCLK_USBPM>;
+			clock-names = "hclkf", "hclkpm";
+			power-domains = <&sysctrl>;
+			status = "disabled";
+		};
+
 		pci_usb: pci@40030000 {
 			compatible = "renesas,pci-r9a06g032", "renesas,pci-rzn1";
 			device_type = "pci";
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry
  2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
                   ` (5 preceding siblings ...)
  2022-11-14 11:15 ` [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node Herve Codina
@ 2022-11-14 11:15 ` Herve Codina
  2022-11-15 12:20   ` kernel test robot
  6 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-14 11:15 UTC (permalink / raw)
  To: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Herve Codina, Greg Kroah-Hartman,
	Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

After contributing the driver, add myself as the maintainer
for Renesas RZ/N1 USBF controller.

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 379945f82a64..9ccac3275a88 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17627,6 +17627,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
 F:	drivers/rtc/rtc-rzn1.c
 
+RENESAS RZ/N1 USBF CONTROLLER DRIVER
+M:	Herve Codina <herve.codina@bootlin.com>
+L:	linux-renesas-soc@vger.kernel.org
+L:	linux-usb@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/usb/renesas,usbf.yaml
+F:	drivers/usb/gadget/udc/renesas_usbf.c
+
 RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
 M:	Miquel Raynal <miquel.raynal@bootlin.com>
 L:	linux-mtd@lists.infradead.org
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property
  2022-11-14 11:15 ` [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property Herve Codina
@ 2022-11-14 13:32   ` Geert Uytterhoeven
  0 siblings, 0 replies; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-14 13:32 UTC (permalink / raw)
  To: Herve Codina
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Hervé,

On Mon, Nov 14, 2022 at 12:15 PM Herve Codina <herve.codina@bootlin.com> wrote:
>
> Handle the h2mode property and forces the CFG_USB[H2MODE] bit
> accordingly.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Thanks for the update!

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Minor nit below.

> @@ -966,6 +967,26 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
>         clocks->reg = of_iomap(np, 0);
>         if (WARN_ON(!clocks->reg))
>                 return -ENOMEM;
> +
> +       error = of_property_read_u32(np, "renesas,h2mode", &h2mode);
> +       if (!error) {
> +               usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB);
> +               switch (h2mode) {
> +               case 0:
> +                       /* 1 host, 1 device */
> +                       usb &= ~R9A06G032_SYSCTRL_USB_H2MODE;
> +                       break;
> +               case 1:
> +                       /* 2 hosts */
> +                       usb |= R9A06G032_SYSCTRL_USB_H2MODE;
> +                       break;
> +               default:
> +                       dev_err(dev, "invalid h2mode %d\n", h2mode);

%u

> +                       return -EINVAL;
> +               }
> +               writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB);
> +       }
> +
>         for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) {
>                 const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i];
>                 const char *parent_name = d->source ?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role
  2022-11-14 11:15 ` [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role Herve Codina
@ 2022-11-14 13:33   ` Geert Uytterhoeven
  0 siblings, 0 replies; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-14 13:33 UTC (permalink / raw)
  To: Herve Codina
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On Mon, Nov 14, 2022 at 12:15 PM Herve Codina <herve.codina@bootlin.com> wrote:
> The usb role retrieved is determined from the CFG_USB[H2MODE]
> value. The CFG_USB register is located within the system
> controller.
>
> We need a helper to get the usb role based on H2MODE value from
> the CFG_USB register without syscon.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-14 11:15 ` [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property Herve Codina
@ 2022-11-14 13:33   ` Geert Uytterhoeven
  2022-11-15 13:05   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-14 13:33 UTC (permalink / raw)
  To: Herve Codina
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On Mon, Nov 14, 2022 at 12:15 PM Herve Codina <herve.codina@bootlin.com> wrote:
> Add the h2mode property to force the USBs mode ie:
>  - 2 hosts
> or
>  - 1 host and 1 device
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry
  2022-11-14 11:15 ` [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry Herve Codina
@ 2022-11-15 12:20   ` kernel test robot
  2022-11-15 13:24     ` Herve Codina
  0 siblings, 1 reply; 47+ messages in thread
From: kernel test robot @ 2022-11-15 12:20 UTC (permalink / raw)
  To: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams
  Cc: oe-kbuild-all, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

[-- Attachment #1: Type: text/plain, Size: 1685 bytes --]

Hi Herve,

I love your patch! Perhaps something to improve:

[auto build test WARNING on geert-renesas-drivers/renesas-clk]
[also build test WARNING on usb/usb-testing usb/usb-next usb/usb-linus geert-renesas-devel/next linus/master v6.1-rc5 next-20221114]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Herve-Codina/Add-the-Renesas-USBF-controller-support/20221114-192136
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk
patch link:    https://lore.kernel.org/r/20221114111513.1436165-8-herve.codina%40bootlin.com
patch subject: [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry
reproduce:
        # https://github.com/intel-lab-lkp/linux/commit/2d4ab4c37cc32d82286869f7ec4ee5247354db88
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Herve-Codina/Add-the-Renesas-USBF-controller-support/20221114-192136
        git checkout 2d4ab4c37cc32d82286869f7ec4ee5247354db88
        make menuconfig
        # enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, CONFIG_WARN_ABI_ERRORS
        make htmldocs

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/usb/renesas,usbf.yaml

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 6.1.0-rc1 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc-11 (Debian 11.3.0-8) 11.3.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=110300
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23900
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23900
CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_ZSTD=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
# CONFIG_KERNEL_ZSTD is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SYSVIPC is not set
# CONFIG_WATCH_QUEUE is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
# CONFIG_USELIB is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# end of IRQ subsystem

CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y

#
# Timers subsystem
#
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
# end of Timers subsystem

CONFIG_HAVE_EBPF_JIT=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y

#
# BPF subsystem
#
# CONFIG_BPF_SYSCALL is not set
# end of BPF subsystem

CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_DYNAMIC is not set

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_PSI is not set
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
# end of RCU Subsystem

# CONFIG_IKCONFIG is not set
# CONFIG_IKHEADERS is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y

#
# Scheduler features
#
# end of Scheduler features

CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_ARCH_SUPPORTS_INT128=y
# CONFIG_CGROUPS is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_TIME_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BOOT_CONFIG is not set
# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_SYSCTL=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
# CONFIG_EXPERT is not set
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_RSEQ=y
# CONFIG_EMBEDDED is not set
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# end of Kernel Performance Events And Counters

# CONFIG_PROFILING is not set
# end of General setup

CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_MMU=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=28
CONFIG_ARCH_MMAP_RND_BITS_MAX=32
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_NR_GPIO=1024
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_PGTABLE_LEVELS=4
CONFIG_CC_HAS_SANE_STACKPROTECTOR=y

#
# Processor type and features
#
# CONFIG_SMP is not set
CONFIG_X86_FEATURE_NAMES=y
CONFIG_X86_MPPARSE=y
# CONFIG_GOLDFISH is not set
# CONFIG_X86_CPU_RESCTRL is not set
# CONFIG_X86_EXTENDED_PLATFORM is not set
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
# CONFIG_HYPERVISOR_GUEST is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_IA32_FEAT_CTL=y
CONFIG_X86_VMX_FEATURE_NAMES=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_ZHAOXIN=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_NR_CPUS_RANGE_BEGIN=1
CONFIG_NR_CPUS_RANGE_END=1
CONFIG_NR_CPUS_DEFAULT=1
CONFIG_NR_CPUS=1
CONFIG_UP_LATE_INIT=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
# CONFIG_X86_MCE is not set

#
# Performance monitoring
#
# CONFIG_PERF_EVENTS_AMD_POWER is not set
# CONFIG_PERF_EVENTS_AMD_UNCORE is not set
# CONFIG_PERF_EVENTS_AMD_BRS is not set
# end of Performance monitoring

CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_X86_VSYSCALL_EMULATION=y
# CONFIG_X86_IOPL_IOPERM is not set
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
# CONFIG_X86_5LEVEL is not set
CONFIG_X86_DIRECT_GBPAGES=y
# CONFIG_AMD_MEM_ENCRYPT is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_X86_UMIP=y
CONFIG_CC_HAS_IBT=y
# CONFIG_X86_KERNEL_IBT is not set
# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set
CONFIG_X86_INTEL_TSX_MODE_OFF=y
# CONFIG_X86_INTEL_TSX_MODE_ON is not set
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x200000
CONFIG_LEGACY_VSYSCALL_XONLY=y
# CONFIG_LEGACY_VSYSCALL_NONE is not set
# CONFIG_CMDLINE_BOOL is not set
CONFIG_MODIFY_LDT_SYSCALL=y
# CONFIG_STRICT_SIGALTSTACK_SIZE is not set
CONFIG_HAVE_LIVEPATCH=y
# end of Processor type and features

CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y
# CONFIG_SPECULATION_MITIGATIONS is not set
CONFIG_ARCH_HAS_ADD_PAGES=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y

#
# Power management and ACPI options
#
# CONFIG_SUSPEND is not set
# CONFIG_PM is not set
CONFIG_ARCH_SUPPORTS_ACPI=y
# CONFIG_ACPI is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
# end of CPU Frequency scaling

#
# CPU Idle
#
# CONFIG_CPU_IDLE is not set
# end of CPU Idle
# end of Power management and ACPI options

#
# Bus options (PCI etc.)
#
CONFIG_ISA_DMA_API=y
# end of Bus options (PCI etc.)

#
# Binary Emulations
#
# CONFIG_IA32_EMULATION is not set
# CONFIG_X86_X32_ABI is not set
# end of Binary Emulations

CONFIG_HAVE_KVM=y
# CONFIG_VIRTUALIZATION is not set
CONFIG_AS_AVX512=y
CONFIG_AS_SHA1_NI=y
CONFIG_AS_SHA256_NI=y
CONFIG_AS_TPAUSE=y

#
# General architecture-dependent options
#
CONFIG_GENERIC_ENTRY=y
# CONFIG_JUMP_LABEL is not set
# CONFIG_STATIC_CALL_SELFTEST is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_RUST=y
CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
# CONFIG_SECCOMP is not set
CONFIG_HAVE_ARCH_STACKLEAK=y
CONFIG_HAVE_STACKPROTECTOR=y
# CONFIG_STACKPROTECTOR is not set
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
CONFIG_LTO_NONE=y
CONFIG_ARCH_SUPPORTS_CFI_CLANG=y
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
CONFIG_HAVE_CONTEXT_TRACKING_USER=y
CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOVE_PUD=y
CONFIG_HAVE_MOVE_PMD=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y
CONFIG_HAVE_ARCH_HUGE_VMAP=y
CONFIG_HAVE_ARCH_HUGE_VMALLOC=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS=28
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_HAVE_OBJTOOL=y
CONFIG_HAVE_JUMP_LABEL_HACK=y
CONFIG_HAVE_NOINSTR_HACK=y
CONFIG_HAVE_NOINSTR_VALIDATION=y
CONFIG_HAVE_UACCESS_VALIDATION=y
CONFIG_HAVE_STACK_VALIDATION=y
CONFIG_HAVE_RELIABLE_STACKTRACE=y
# CONFIG_COMPAT_32BIT_TIME is not set
CONFIG_HAVE_ARCH_VMAP_STACK=y
# CONFIG_VMAP_STACK is not set
CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
CONFIG_RANDOMIZE_KSTACK_OFFSET=y
# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
CONFIG_ARCH_HAS_MEM_ENCRYPT=y
CONFIG_HAVE_STATIC_CALL=y
CONFIG_HAVE_STATIC_CALL_INLINE=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y
CONFIG_ARCH_HAS_ELFCORE_COMPAT=y
CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
CONFIG_DYNAMIC_SIGFRAME=y
CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y

#
# GCOV-based kernel profiling
#
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
# CONFIG_GCC_PLUGINS is not set
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
# CONFIG_BLK_DEV_ZONED is not set
# CONFIG_BLK_WBT is not set
# CONFIG_BLK_SED_OPAL is not set
# CONFIG_BLK_INLINE_ENCRYPTION is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
# end of Partition Types

#
# IO Schedulers
#
# CONFIG_MQ_IOSCHED_DEADLINE is not set
# CONFIG_MQ_IOSCHED_KYBER is not set
# CONFIG_IOSCHED_BFQ is not set
# end of IO Schedulers

CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y

#
# Executable file formats
#
# CONFIG_BINFMT_ELF is not set
# CONFIG_BINFMT_SCRIPT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_COREDUMP=y
# end of Executable file formats

#
# Memory Management options
#
# CONFIG_SWAP is not set

#
# SLAB allocator options
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLAB_MERGE_DEFAULT is not set
# CONFIG_SLAB_FREELIST_RANDOM is not set
# CONFIG_SLAB_FREELIST_HARDENED is not set
# CONFIG_SLUB_STATS is not set
# end of SLAB allocator options

# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
CONFIG_HAVE_FAST_GUP=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
# CONFIG_COMPACTION is not set
# CONFIG_PAGE_REPORTING is not set
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANTS_THP_SWAP=y
# CONFIG_TRANSPARENT_HUGEPAGE is not set
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
# CONFIG_CMA is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
# CONFIG_IDLE_PAGE_TRACKING is not set
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_ARCH_HAS_PTE_DEVMAP=y
CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_PERCPU_STATS is not set

#
# GUP_TEST needs to have DEBUG_FS enabled
#
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_SECRETMEM=y
# CONFIG_ANON_VMA_NAME is not set
# CONFIG_USERFAULTFD is not set
# CONFIG_LRU_GEN is not set

#
# Data Access Monitoring
#
# CONFIG_DAMON is not set
# end of Data Access Monitoring
# end of Memory Management options

# CONFIG_NET is not set

#
# Device Drivers
#
CONFIG_HAVE_EISA=y
# CONFIG_EISA is not set
CONFIG_HAVE_PCI=y
# CONFIG_PCI is not set
# CONFIG_PCCARD is not set

#
# Generic Driver Options
#
# CONFIG_UEVENT_HELPER is not set
# CONFIG_DEVTMPFS is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set

#
# Firmware loader
#
CONFIG_FW_LOADER=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_FW_LOADER_USER_HELPER is not set
# CONFIG_FW_LOADER_COMPRESS is not set
# CONFIG_FW_UPLOAD is not set
# end of Firmware loader

CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
# end of Generic Driver Options

#
# Bus devices
#
# CONFIG_ARM_INTEGRATOR_LM is not set
# CONFIG_BT1_APB is not set
# CONFIG_BT1_AXI is not set
# CONFIG_HISILICON_LPC is not set
# CONFIG_INTEL_IXP4XX_EB is not set
# CONFIG_QCOM_EBI2 is not set
# CONFIG_MHI_BUS is not set
# CONFIG_MHI_BUS_EP is not set
# end of Bus devices

#
# Firmware Drivers
#

#
# ARM System Control and Management Interface Protocol
#
# CONFIG_ARM_SCMI_PROTOCOL is not set
# end of ARM System Control and Management Interface Protocol

# CONFIG_EDD is not set
CONFIG_FIRMWARE_MEMMAP=y
# CONFIG_DMIID is not set
# CONFIG_DMI_SYSFS is not set
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_FW_CFG_SYSFS is not set
# CONFIG_SYSFB_SIMPLEFB is not set
# CONFIG_BCM47XX_NVRAM is not set
# CONFIG_GOOGLE_FIRMWARE is not set

#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers

# CONFIG_GNSS is not set
# CONFIG_MTD is not set
# CONFIG_OF is not set
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set

#
# NVME Support
#
# CONFIG_NVME_FC is not set
# end of NVME Support

#
# Misc devices
#
# CONFIG_DUMMY_IRQ is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_QCOM_COINCELL is not set
# CONFIG_SRAM is not set
# CONFIG_XILINX_SDFEC is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_93CX6 is not set
# end of EEPROM support

#
# Texas Instruments shared transport line discipline
#
# end of Texas Instruments shared transport line discipline

#
# Altera FPGA firmware download module (requires I2C)
#
# CONFIG_ECHO is not set
# CONFIG_PVPANIC is not set
# end of Misc devices

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# end of SCSI device support

# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# end of IEEE 1394 (FireWire) support

# CONFIG_MACINTOSH_DRIVERS is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
# CONFIG_RMI4_CORE is not set

#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
# CONFIG_GAMEPORT is not set
# end of Hardware I/O ports
# end of Input device support

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_LDISC_AUTOLOAD is not set

#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_MESON is not set
# CONFIG_SERIAL_CLPS711X is not set
# CONFIG_SERIAL_SAMSUNG is not set
# CONFIG_SERIAL_TEGRA is not set
# CONFIG_SERIAL_IMX is not set
# CONFIG_SERIAL_UARTLITE is not set
# CONFIG_SERIAL_SH_SCI is not set
# CONFIG_SERIAL_MSM is not set
# CONFIG_SERIAL_VT8500 is not set
# CONFIG_SERIAL_OMAP is not set
# CONFIG_SERIAL_LANTIQ is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_BCM63XX is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_MXS_AUART is not set
# CONFIG_SERIAL_MPS2_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_SERIAL_FSL_LINFLEXUART is not set
# CONFIG_SERIAL_ST_ASC is not set
# CONFIG_SERIAL_STM32 is not set
# CONFIG_SERIAL_OWL is not set
# CONFIG_SERIAL_RDA is not set
# CONFIG_SERIAL_LITEUART is not set
# CONFIG_SERIAL_SUNPLUS is not set
# end of Serial drivers

# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NULL_TTY is not set
# CONFIG_SERIAL_DEV_BUS is not set
# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_ASPEED_KCS_IPMI_BMC is not set
# CONFIG_NPCM7XX_KCS_IPMI_BMC is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_MWAVE is not set
# CONFIG_DEVMEM is not set
# CONFIG_NVRAM is not set
# CONFIG_HANGCHECK_TIMER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices

#
# I2C support
#
# CONFIG_I2C is not set
# end of I2C support

# CONFIG_I3C is not set
# CONFIG_SPI is not set
# CONFIG_SPMI is not set
# CONFIG_HSI is not set
# CONFIG_PPS is not set

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK_OPTIONAL=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
# end of PTP clock support

# CONFIG_PINCTRL is not set
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_RESET is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_SUN4I_GPADC is not set
# CONFIG_MFD_AT91_USART is not set
# CONFIG_MFD_MADERA is not set
# CONFIG_MFD_EXYNOS_LPASS is not set
# CONFIG_MFD_MXS_LRADC is not set
# CONFIG_MFD_MX25_TSADC is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_MT6397 is not set
# CONFIG_MFD_PM8XXX is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_SUN6I_PRCM is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_TQMX86 is not set
# CONFIG_MFD_STM32_LPTIMER is not set
# CONFIG_MFD_STM32_TIMERS is not set
# end of Multifunction device drivers

# CONFIG_REGULATOR is not set
# CONFIG_RC_CORE is not set

#
# CEC support
#
# CONFIG_MEDIA_CEC_SUPPORT is not set
# end of CEC support

# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_IMX_IPUV3_CORE is not set
# CONFIG_DRM is not set

#
# ARM devices
#
# end of ARM devices

#
# Frame buffer Devices
#
# CONFIG_FB is not set
# CONFIG_MMP_DISP is not set
# end of Frame buffer Devices

#
# Backlight & LCD device support
#
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
# end of Backlight & LCD device support

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
# end of Console display driver support
# end of Graphics support

# CONFIG_SOUND is not set

#
# HID support
#
# CONFIG_HID is not set
# end of HID support

CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set

#
# DMABUF options
#
# CONFIG_SYNC_FILE is not set
# CONFIG_DMABUF_HEAPS is not set
# end of DMABUF options

# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_VFIO is not set
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set

#
# Microsoft Hyper-V guest support
#
# end of Microsoft Hyper-V guest support

# CONFIG_GREYBUS is not set
# CONFIG_COMEDI is not set
# CONFIG_STAGING is not set
# CONFIG_CHROME_PLATFORMS is not set
# CONFIG_MELLANOX_PLATFORM is not set
# CONFIG_OLPC_XO175 is not set
# CONFIG_SURFACE_PLATFORMS is not set
# CONFIG_X86_PLATFORM_DEVICES is not set
# CONFIG_COMMON_CLK is not set
# CONFIG_HWSPINLOCK is not set

#
# Clock Source drivers
#
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
# CONFIG_BCM2835_TIMER is not set
# CONFIG_BCM_KONA_TIMER is not set
# CONFIG_DAVINCI_TIMER is not set
# CONFIG_DIGICOLOR_TIMER is not set
# CONFIG_OMAP_DM_TIMER is not set
# CONFIG_DW_APB_TIMER is not set
# CONFIG_FTTMR010_TIMER is not set
# CONFIG_IXP4XX_TIMER is not set
# CONFIG_MESON6_TIMER is not set
# CONFIG_OWL_TIMER is not set
# CONFIG_RDA_TIMER is not set
# CONFIG_SUN4I_TIMER is not set
# CONFIG_TEGRA_TIMER is not set
# CONFIG_VT8500_TIMER is not set
# CONFIG_NPCM7XX_TIMER is not set
# CONFIG_ASM9260_TIMER is not set
# CONFIG_CLKSRC_DBX500_PRCMU is not set
# CONFIG_CLPS711X_TIMER is not set
# CONFIG_MXS_TIMER is not set
# CONFIG_NSPIRE_TIMER is not set
# CONFIG_INTEGRATOR_AP_TIMER is not set
# CONFIG_CLKSRC_PISTACHIO is not set
# CONFIG_CLKSRC_STM32_LP is not set
# CONFIG_ARMV7M_SYSTICK is not set
# CONFIG_ATMEL_PIT is not set
# CONFIG_ATMEL_ST is not set
# CONFIG_CLKSRC_SAMSUNG_PWM is not set
# CONFIG_FSL_FTM_TIMER is not set
# CONFIG_OXNAS_RPS_TIMER is not set
# CONFIG_MTK_TIMER is not set
# CONFIG_SH_TIMER_CMT is not set
# CONFIG_SH_TIMER_MTU2 is not set
# CONFIG_RENESAS_OSTM is not set
# CONFIG_SH_TIMER_TMU is not set
# CONFIG_EM_TIMER_STI is not set
# CONFIG_CLKSRC_PXA is not set
# CONFIG_TIMER_IMX_SYS_CTR is not set
# CONFIG_CLKSRC_ST_LPC is not set
# CONFIG_GXP_TIMER is not set
# CONFIG_MSC313E_TIMER is not set
# CONFIG_MICROCHIP_PIT64B is not set
# end of Clock Source drivers

# CONFIG_MAILBOX is not set
# CONFIG_IOMMU_SUPPORT is not set

#
# Remoteproc drivers
#
# CONFIG_REMOTEPROC is not set
# end of Remoteproc drivers

#
# Rpmsg drivers
#
# CONFIG_RPMSG_VIRTIO is not set
# end of Rpmsg drivers

#
# SOC (System On Chip) specific Drivers
#

#
# Amlogic SoC drivers
#
# CONFIG_MESON_CANVAS is not set
# CONFIG_MESON_CLK_MEASURE is not set
# CONFIG_MESON_GX_SOCINFO is not set
# CONFIG_MESON_MX_SOCINFO is not set
# end of Amlogic SoC drivers

#
# Apple SoC drivers
#
# CONFIG_APPLE_SART is not set
# end of Apple SoC drivers

#
# ASPEED SoC drivers
#
# CONFIG_ASPEED_LPC_CTRL is not set
# CONFIG_ASPEED_LPC_SNOOP is not set
# CONFIG_ASPEED_UART_ROUTING is not set
# CONFIG_ASPEED_P2A_CTRL is not set
# CONFIG_ASPEED_SOCINFO is not set
# end of ASPEED SoC drivers

# CONFIG_AT91_SOC_ID is not set
# CONFIG_AT91_SOC_SFR is not set

#
# Broadcom SoC drivers
#
# CONFIG_SOC_BCM63XX is not set
# CONFIG_SOC_BRCMSTB is not set
# end of Broadcom SoC drivers

#
# NXP/Freescale QorIQ SoC drivers
#
# end of NXP/Freescale QorIQ SoC drivers

#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers

#
# i.MX SoC drivers
#
# CONFIG_SOC_IMX8M is not set
# CONFIG_SOC_IMX9 is not set
# end of i.MX SoC drivers

#
# IXP4xx SoC drivers
#
# CONFIG_IXP4XX_QMGR is not set
# CONFIG_IXP4XX_NPE is not set
# end of IXP4xx SoC drivers

#
# Enable LiteX SoC Builder specific drivers
#
# CONFIG_LITEX_SOC_CONTROLLER is not set
# end of Enable LiteX SoC Builder specific drivers

#
# MediaTek SoC drivers
#
# CONFIG_MTK_CMDQ is not set
# CONFIG_MTK_DEVAPC is not set
# CONFIG_MTK_INFRACFG is not set
# CONFIG_MTK_MMSYS is not set
# end of MediaTek SoC drivers

#
# Qualcomm SoC drivers
#
# CONFIG_QCOM_GENI_SE is not set
# CONFIG_QCOM_GSBI is not set
# CONFIG_QCOM_LLCC is not set
# CONFIG_QCOM_RPMH is not set
# CONFIG_QCOM_SPM is not set
# CONFIG_QCOM_ICC_BWMON is not set
# end of Qualcomm SoC drivers

# CONFIG_SOC_RENESAS is not set
# CONFIG_ROCKCHIP_GRF is not set
# CONFIG_SOC_SAMSUNG is not set
# CONFIG_SOC_TI is not set
# CONFIG_UX500_SOC_ID is not set

#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers

# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_PWM is not set

#
# IRQ chip support
#
# CONFIG_AL_FIC is not set
# CONFIG_RENESAS_INTC_IRQPIN is not set
# CONFIG_RENESAS_IRQC is not set
# CONFIG_RENESAS_RZA1_IRQC is not set
# CONFIG_RENESAS_RZG2L_IRQC is not set
# CONFIG_SL28CPLD_INTC is not set
# CONFIG_TS4800_IRQ is not set
# CONFIG_INGENIC_TCU_IRQ is not set
# CONFIG_IRQ_UNIPHIER_AIDET is not set
# CONFIG_MESON_IRQ_GPIO is not set
# CONFIG_IMX_IRQSTEER is not set
# CONFIG_IMX_INTMUX is not set
# CONFIG_EXYNOS_IRQ_COMBINER is not set
# CONFIG_MST_IRQ is not set
# CONFIG_MCHP_EIC is not set
# CONFIG_SUNPLUS_SP7021_INTC is not set
# end of IRQ chip support

# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set

#
# PHY Subsystem
#
# CONFIG_GENERIC_PHY is not set
# CONFIG_PHY_PISTACHIO_USB is not set
# CONFIG_PHY_CAN_TRANSCEIVER is not set

#
# PHY drivers for Broadcom platforms
#
# CONFIG_PHY_BCM63XX_USBH is not set
# CONFIG_BCM_KONA_USB2_PHY is not set
# end of PHY drivers for Broadcom platforms

# CONFIG_PHY_HI6220_USB is not set
# CONFIG_PHY_HI3660_USB is not set
# CONFIG_PHY_HI3670_USB is not set
# CONFIG_PHY_HI3670_PCIE is not set
# CONFIG_PHY_HISTB_COMBPHY is not set
# CONFIG_PHY_HISI_INNO_USB2 is not set
# CONFIG_PHY_PXA_28NM_HSIC is not set
# CONFIG_PHY_PXA_28NM_USB2 is not set
# CONFIG_PHY_PXA_USB is not set
# CONFIG_PHY_MMP3_USB is not set
# CONFIG_PHY_MMP3_HSIC is not set
# CONFIG_PHY_MT7621_PCI is not set
# CONFIG_PHY_RALINK_USB is not set
# CONFIG_PHY_RCAR_GEN3_USB3 is not set
# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set
# CONFIG_PHY_ROCKCHIP_PCIE is not set
# CONFIG_PHY_ROCKCHIP_SNPS_PCIE3 is not set
# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
# CONFIG_PHY_SAMSUNG_USB2 is not set
# CONFIG_PHY_ST_SPEAR1310_MIPHY is not set
# CONFIG_PHY_ST_SPEAR1340_MIPHY is not set
# CONFIG_PHY_TEGRA194_P2U is not set
# CONFIG_PHY_DA8XX_USB is not set
# CONFIG_OMAP_CONTROL_PHY is not set
# CONFIG_TI_PIPE3 is not set
# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set
# CONFIG_PHY_INTEL_KEEMBAY_USB is not set
# CONFIG_PHY_INTEL_LGM_EMMC is not set
# CONFIG_PHY_XILINX_ZYNQMP is not set
# end of PHY Subsystem

# CONFIG_POWERCAP is not set
# CONFIG_MCB is not set

#
# Performance monitor support
#
# CONFIG_ARM_CCN is not set
# CONFIG_ARM_CMN is not set
# CONFIG_FSL_IMX8_DDR_PMU is not set
# CONFIG_XGENE_PMU is not set
# CONFIG_ARM_DMC620_PMU is not set
# CONFIG_MARVELL_CN10K_TAD_PMU is not set
# CONFIG_ALIBABA_UNCORE_DRW_PMU is not set
# CONFIG_MARVELL_CN10K_DDR_PMU is not set
# end of Performance monitor support

# CONFIG_RAS is not set

#
# Android
#
# CONFIG_ANDROID_BINDER_IPC is not set
# end of Android

# CONFIG_DAX is not set
# CONFIG_NVMEM is not set

#
# HW tracing support
#
# CONFIG_STM is not set
# CONFIG_INTEL_TH is not set
# end of HW tracing support

# CONFIG_FPGA is not set
# CONFIG_TEE is not set
# CONFIG_SIOX is not set
# CONFIG_SLIMBUS is not set
# CONFIG_INTERCONNECT is not set
# CONFIG_COUNTER is not set
# CONFIG_PECI is not set
# CONFIG_HTE is not set
# end of Device Drivers

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_VALIDATE_FS_PARSER is not set
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_EXPORTFS=y
# CONFIG_EXPORTFS_BLOCK_OPS is not set
CONFIG_FILE_LOCKING=y
# CONFIG_FS_ENCRYPTION is not set
# CONFIG_FS_VERITY is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_FUSE_FS is not set
# CONFIG_OVERLAY_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set
# end of Caches

#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
# end of CD-ROM/DVD Filesystems

#
# DOS/FAT/EXFAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EXFAT_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS3_FS is not set
# end of DOS/FAT/EXFAT/NT Filesystems

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
# CONFIG_PROC_CHILDREN is not set
CONFIG_PROC_PID_ARCH_STATUS=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
# CONFIG_CONFIGFS_FS is not set
# end of Pseudo filesystems

# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NLS is not set
# CONFIG_UNICODE is not set
CONFIG_IO_WQ=y
# end of File systems

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
# CONFIG_HARDENED_USERCOPY is not set
# CONFIG_FORTIFY_SOURCE is not set
# CONFIG_STATIC_USERMODEHELPER is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,bpf"

#
# Kernel hardening options
#

#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
# CONFIG_ZERO_CALL_USED_REGS is not set
# end of Memory initialization

CONFIG_RANDSTRUCT_NONE=y
# end of Kernel hardening options
# end of Security options

# CONFIG_CRYPTO is not set

#
# Library routines
#
# CONFIG_PACKING is not set
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
# CONFIG_CORDIC is not set
# CONFIG_PRIME_NUMBERS is not set
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
CONFIG_ARCH_USE_SYM_ANNOTATIONS=y

#
# Crypto library routines
#
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
# CONFIG_CRYPTO_LIB_CHACHA is not set
# CONFIG_CRYPTO_LIB_CURVE25519 is not set
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11
# CONFIG_CRYPTO_LIB_POLY1305 is not set
# end of Crypto library routines

# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC64_ROCKSOFT is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC4 is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
# CONFIG_CRC8 is not set
# CONFIG_RANDOM32_SELFTEST is not set
# CONFIG_XZ_DEC is not set
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_SWIOTLB=y
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_IRQ_POLL is not set
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_VDSO_TIME_NS=y
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAS_COPY_MC=y
CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_SBITMAP=y
# CONFIG_PARMAN is not set
# CONFIG_OBJAGG is not set
# end of Library routines

#
# Kernel hacking
#

#
# printk and dmesg options
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_PRINTK_CALLER is not set
# CONFIG_STACKTRACE_BUILD_ID is not set
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DYNAMIC_DEBUG_CORE is not set
# CONFIG_SYMBOLIC_ERRNAME is not set
CONFIG_DEBUG_BUGVERBOSE=y
# end of printk and dmesg options

# CONFIG_DEBUG_KERNEL is not set

#
# Compile-time checks and compiler options
#
CONFIG_AS_HAS_NON_CONST_LEB128=y
CONFIG_FRAME_WARN=2048
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HEADERS_INSTALL is not set
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_OBJTOOL=y
# end of Compile-time checks and compiler options

#
# Generic Kernel Debugging Instruments
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_FS is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
# CONFIG_UBSAN is not set
CONFIG_HAVE_ARCH_KCSAN=y
CONFIG_HAVE_KCSAN_COMPILER=y
# end of Generic Kernel Debugging Instruments

#
# Networking Debugging
#
# end of Networking Debugging

#
# Memory Debugging
#
# CONFIG_PAGE_EXTENSION is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_PAGE_TABLE_CHECK is not set
# CONFIG_PAGE_POISONING is not set
# CONFIG_DEBUG_RODATA_TEST is not set
CONFIG_ARCH_HAS_DEBUG_WX=y
# CONFIG_DEBUG_WX is not set
CONFIG_GENERIC_PTDUMP=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
# CONFIG_DEBUG_VM_PGTABLE is not set
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# CONFIG_KASAN is not set
CONFIG_HAVE_ARCH_KFENCE=y
# CONFIG_KFENCE is not set
CONFIG_HAVE_ARCH_KMSAN=y
# end of Memory Debugging

#
# Debug Oops, Lockups and Hangs
#
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
# end of Debug Oops, Lockups and Hangs

#
# Scheduler Debugging
#
# end of Scheduler Debugging

# CONFIG_DEBUG_TIMEKEEPING is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_WW_MUTEX_SELFTEST is not set
# end of Lock Debugging (spinlocks, mutexes, etc...)

# CONFIG_DEBUG_IRQFLAGS is not set
CONFIG_STACKTRACE=y
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set

#
# Debug kernel data structures
#
# CONFIG_BUG_ON_DATA_CORRUPTION is not set
# end of Debug kernel data structures

#
# RCU Debugging
#
# end of RCU Debugging

CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_RETHOOK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_OBJTOOL_MCOUNT=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y

#
# x86 Debugging
#
# CONFIG_X86_VERBOSE_BOOTUP is not set
CONFIG_EARLY_PRINTK=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_UNWINDER_ORC=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
# end of x86 Debugging

#
# Kernel Testing and Coverage
#
# CONFIG_KUNIT is not set
CONFIG_ARCH_HAS_KCOV=y
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
# CONFIG_KCOV is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_ARCH_USE_MEMTEST=y
# CONFIG_MEMTEST is not set
# end of Kernel Testing and Coverage

#
# Rust hacking
#
# end of Rust hacking

CONFIG_WARN_MISSING_DOCUMENTS=y
CONFIG_WARN_ABI_ERRORS=y
# end of Kernel hacking

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-14 11:15 ` [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property Herve Codina
  2022-11-14 13:33   ` Geert Uytterhoeven
@ 2022-11-15 13:05   ` Krzysztof Kozlowski
  2022-11-15 13:07     ` Krzysztof Kozlowski
  1 sibling, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 13:05 UTC (permalink / raw)
  To: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 14/11/2022 12:15, Herve Codina wrote:
> Add the h2mode property to force the USBs mode ie:
>  - 2 hosts
> or
>  - 1 host and 1 device
> 
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> index 95bf485c6cec..f9e0a58aa4fb 100644
> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> @@ -39,6 +39,16 @@ properties:
>    '#power-domain-cells':
>      const: 0
>  
> +  renesas,h2mode:
> +    description: |
> +      Configure the USBs mode.
> +        - <0> : the USBs are in 1 host and 1 device mode.
> +        - <1> : the USBs are in 2 host mode.
> +      If the property is not present, the value used is the one already present
> +      in the CFG_USB register (from reset or set by the bootloader).
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 1]

0/1 are quite cryptic. Why not making it a string which is easy to read
and understand? Can be something like "two-hosts" and "one-host". Or
anything you find more readable...

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-15 13:05   ` Krzysztof Kozlowski
@ 2022-11-15 13:07     ` Krzysztof Kozlowski
  2022-11-15 14:04       ` Herve Codina
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 13:07 UTC (permalink / raw)
  To: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 15/11/2022 14:05, Krzysztof Kozlowski wrote:
> On 14/11/2022 12:15, Herve Codina wrote:
>> Add the h2mode property to force the USBs mode ie:
>>  - 2 hosts
>> or
>>  - 1 host and 1 device
>>
>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
>> ---
>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
>>  1 file changed, 10 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>> index 95bf485c6cec..f9e0a58aa4fb 100644
>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>> @@ -39,6 +39,16 @@ properties:
>>    '#power-domain-cells':
>>      const: 0
>>  
>> +  renesas,h2mode:
>> +    description: |
>> +      Configure the USBs mode.
>> +        - <0> : the USBs are in 1 host and 1 device mode.
>> +        - <1> : the USBs are in 2 host mode.
>> +      If the property is not present, the value used is the one already present
>> +      in the CFG_USB register (from reset or set by the bootloader).
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [0, 1]
> 
> 0/1 are quite cryptic. Why not making it a string which is easy to read
> and understand? Can be something like "two-hosts" and "one-host". Or
> anything you find more readable...

...but actually you should rather make it a property of your USB
controller, not clock controller. You have two controllers and we have a
generic property for them - dr_mode.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding
  2022-11-14 11:15 ` [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding Herve Codina
@ 2022-11-15 13:13   ` Krzysztof Kozlowski
  2022-11-15 13:29     ` Herve Codina
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 13:13 UTC (permalink / raw)
  To: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 14/11/2022 12:15, Herve Codina wrote:
> The Renesas RZ/N1 USBF controller is an USB2.0 device controller
> (UDC) available in the Renesas r9a06g032 SoC (RZ/N1 family).

Subject: drop redundant, second "binding".

> 
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
>  .../bindings/usb/renesas,rzn1-usbf.yaml       | 68 +++++++++++++++++++
>  1 file changed, 68 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> new file mode 100644
> index 000000000000..b67e9cea2522
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> @@ -0,0 +1,68 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/usb/renesas,rzn1-usbf.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/N1 SoCs USBF (USB Function) controller binding

Drop "binding"

With two above:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-14 11:15 ` [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node Herve Codina
@ 2022-11-15 13:16   ` Krzysztof Kozlowski
  2022-11-15 13:27     ` Herve Codina
  2022-11-15 14:11     ` Geert Uytterhoeven
  2022-11-16  8:51   ` Geert Uytterhoeven
  1 sibling, 2 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 13:16 UTC (permalink / raw)
  To: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams
  Cc: linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 14/11/2022 12:15, Herve Codina wrote:
> Add the USBF controller available in the r9a06g032 SoC.
> 
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
>  arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
> index 563024c9a4ae..a4bb069457a3 100644
> --- a/arch/arm/boot/dts/r9a06g032.dtsi
> +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> @@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
>  			};
>  		};
>  
> +		udc: usb@4001e000 {
> +			compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
> +			reg = <0x4001e000 0x2000>;
> +			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&sysctrl R9A06G032_HCLK_USBF>,
> +				 <&sysctrl R9A06G032_HCLK_USBPM>;
> +			clock-names = "hclkf", "hclkpm";
> +			power-domains = <&sysctrl>;
> +			status = "disabled";

If you provided all resources (clocks, power domains etc), why disabling it?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry
  2022-11-15 12:20   ` kernel test robot
@ 2022-11-15 13:24     ` Herve Codina
  0 siblings, 0 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-15 13:24 UTC (permalink / raw)
  To: kernel test robot
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, oe-kbuild-all, linux-renesas-soc, linux-clk,
	devicetree, linux-kernel, linux-usb, Thomas Petazzoni,
	Miquel Raynal

Hi All,

On Tue, 15 Nov 2022 20:20:33 +0800
kernel test robot <lkp@intel.com> wrote:

> Hi Herve,
> 
> I love your patch! Perhaps something to improve:
> 
> [auto build test WARNING on geert-renesas-drivers/renesas-clk]
> [also build test WARNING on usb/usb-testing usb/usb-next usb/usb-linus geert-renesas-devel/next linus/master v6.1-rc5 next-20221114]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Herve-Codina/Add-the-Renesas-USBF-controller-support/20221114-192136
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk
> patch link:    https://lore.kernel.org/r/20221114111513.1436165-8-herve.codina%40bootlin.com
> patch subject: [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry
> reproduce:
>         # https://github.com/intel-lab-lkp/linux/commit/2d4ab4c37cc32d82286869f7ec4ee5247354db88
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Herve-Codina/Add-the-Renesas-USBF-controller-support/20221114-192136
>         git checkout 2d4ab4c37cc32d82286869f7ec4ee5247354db88
>         make menuconfig
>         # enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, CONFIG_WARN_ABI_ERRORS
>         make htmldocs
> 
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <lkp@intel.com>
> 
> All warnings (new ones prefixed by >>):
> 
> >> Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/usb/renesas,usbf.yaml  
> 

Oops, I renamed a file and missed the MAINTAINER file update.
Will be fixed in v3.

Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-15 13:16   ` Krzysztof Kozlowski
@ 2022-11-15 13:27     ` Herve Codina
  2022-11-15 15:09       ` Herve Codina
  2022-11-15 14:11     ` Geert Uytterhoeven
  1 sibling, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-15 13:27 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, 15 Nov 2022 14:16:27 +0100
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:

> On 14/11/2022 12:15, Herve Codina wrote:
> > Add the USBF controller available in the r9a06g032 SoC.
> > 
> > Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > ---
> >  arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
> > index 563024c9a4ae..a4bb069457a3 100644
> > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > @@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
> >  			};
> >  		};
> >  
> > +		udc: usb@4001e000 {
> > +			compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
> > +			reg = <0x4001e000 0x2000>;
> > +			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&sysctrl R9A06G032_HCLK_USBF>,
> > +				 <&sysctrl R9A06G032_HCLK_USBPM>;
> > +			clock-names = "hclkf", "hclkpm";
> > +			power-domains = <&sysctrl>;
> > +			status = "disabled";  
> 
> If you provided all resources (clocks, power domains etc), why disabling it?

Because I forgot to remove the 'status' property ...
'status' will be simply removed in v3.
Sorry for this mistake.

Thanks for the review,
Hervé


-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding
  2022-11-15 13:13   ` Krzysztof Kozlowski
@ 2022-11-15 13:29     ` Herve Codina
  0 siblings, 0 replies; 47+ messages in thread
From: Herve Codina @ 2022-11-15 13:29 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On Tue, 15 Nov 2022 14:13:00 +0100
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:

> On 14/11/2022 12:15, Herve Codina wrote:
> > The Renesas RZ/N1 USBF controller is an USB2.0 device controller
> > (UDC) available in the Renesas r9a06g032 SoC (RZ/N1 family).  
> 
> Subject: drop redundant, second "binding".
> 
> > 
> > Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > ---
> >  .../bindings/usb/renesas,rzn1-usbf.yaml       | 68 +++++++++++++++++++
> >  1 file changed, 68 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> > new file mode 100644
> > index 000000000000..b67e9cea2522
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
> > @@ -0,0 +1,68 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/usb/renesas,rzn1-usbf.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Renesas RZ/N1 SoCs USBF (USB Function) controller binding  
> 
> Drop "binding"
> 
> With two above:
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> 
> Best regards,
> Krzysztof
> 

"binding" will be dropped as suggested in v3.
Thanks for the review.

Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-15 13:07     ` Krzysztof Kozlowski
@ 2022-11-15 14:04       ` Herve Codina
  2022-11-18 10:23         ` Herve Codina
  0 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-15 14:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, 15 Nov 2022 14:07:52 +0100
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:

> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:
> > On 14/11/2022 12:15, Herve Codina wrote:  
> >> Add the h2mode property to force the USBs mode ie:
> >>  - 2 hosts
> >> or
> >>  - 1 host and 1 device
> >>
> >> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> >> ---
> >>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
> >>  1 file changed, 10 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >> index 95bf485c6cec..f9e0a58aa4fb 100644
> >> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >> @@ -39,6 +39,16 @@ properties:
> >>    '#power-domain-cells':
> >>      const: 0
> >>  
> >> +  renesas,h2mode:
> >> +    description: |
> >> +      Configure the USBs mode.
> >> +        - <0> : the USBs are in 1 host and 1 device mode.
> >> +        - <1> : the USBs are in 2 host mode.
> >> +      If the property is not present, the value used is the one already present
> >> +      in the CFG_USB register (from reset or set by the bootloader).
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +    enum: [0, 1]  
> > 
> > 0/1 are quite cryptic. Why not making it a string which is easy to read
> > and understand? Can be something like "two-hosts" and "one-host". Or
> > anything you find more readable...  
> 
> ...but actually you should rather make it a property of your USB
> controller, not clock controller. You have two controllers and we have a
> generic property for them - dr_mode.
> 
> Best regards,
> Krzysztof
> 

IMHO, this property in the USB controllers does not make sense.
Indeed each controller cannot have a different 'mode'.
Some controllers are USB host only (EHCI and OHCI) and the USBF
controller I worked on is device only.
'h2mode' allows to choose between host or device on one of the USB
but not at the USB controller level.

This property should be handle outside the USB controller nodes.

Currently, this node (declared as a clock node) is in fact a sysctrl
node and can do some configuration not related to clocks.

I agree with you something related to choosing USB Host/Device in
a clock node seems strange.

Some discussion were already opened related to this property and how
to handle it:
  https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
  https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/

Regards,
Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-15 13:16   ` Krzysztof Kozlowski
  2022-11-15 13:27     ` Herve Codina
@ 2022-11-15 14:11     ` Geert Uytterhoeven
  2022-11-15 14:58       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-15 14:11 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, Nov 15, 2022 at 2:16 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 14/11/2022 12:15, Herve Codina wrote:
> > Add the USBF controller available in the r9a06g032 SoC.
> >
> > Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > ---
> >  arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
> > index 563024c9a4ae..a4bb069457a3 100644
> > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > @@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
> >                       };
> >               };
> >
> > +             udc: usb@4001e000 {
> > +                     compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
> > +                     reg = <0x4001e000 0x2000>;
> > +                     interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
> > +                                  <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&sysctrl R9A06G032_HCLK_USBF>,
> > +                              <&sysctrl R9A06G032_HCLK_USBPM>;
> > +                     clock-names = "hclkf", "hclkpm";
> > +                     power-domains = <&sysctrl>;
> > +                     status = "disabled";
>
> If you provided all resources (clocks, power domains etc), why disabling it?

Doesn't this depend on wiring on the board, and providing pin control
in the board DTS?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-15 14:11     ` Geert Uytterhoeven
@ 2022-11-15 14:58       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 14:58 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 15/11/2022 15:11, Geert Uytterhoeven wrote:
>>> +             udc: usb@4001e000 {
>>> +                     compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
>>> +                     reg = <0x4001e000 0x2000>;
>>> +                     interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
>>> +                                  <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>>> +                     clocks = <&sysctrl R9A06G032_HCLK_USBF>,
>>> +                              <&sysctrl R9A06G032_HCLK_USBPM>;
>>> +                     clock-names = "hclkf", "hclkpm";
>>> +                     power-domains = <&sysctrl>;
>>> +                     status = "disabled";
>>
>> If you provided all resources (clocks, power domains etc), why disabling it?
> 
> Doesn't this depend on wiring on the board, and providing pin control
> in the board DTS?
> 

Yes, that could be the reason, so if this was the intention, it's fine.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-15 13:27     ` Herve Codina
@ 2022-11-15 15:09       ` Herve Codina
  2022-11-15 16:30         ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-15 15:09 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof

On Tue, 15 Nov 2022 14:27:54 +0100
Herve Codina <herve.codina@bootlin.com> wrote:

> Hi Krzysztof,
> 
> On Tue, 15 Nov 2022 14:16:27 +0100
> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> 
> > On 14/11/2022 12:15, Herve Codina wrote:  
> > > Add the USBF controller available in the r9a06g032 SoC.
> > > 
> > > Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > > ---
> > >  arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
> > >  1 file changed, 12 insertions(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
> > > index 563024c9a4ae..a4bb069457a3 100644
> > > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > > @@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
> > >  			};
> > >  		};
> > >  
> > > +		udc: usb@4001e000 {
> > > +			compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
> > > +			reg = <0x4001e000 0x2000>;
> > > +			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&sysctrl R9A06G032_HCLK_USBF>,
> > > +				 <&sysctrl R9A06G032_HCLK_USBPM>;
> > > +			clock-names = "hclkf", "hclkpm";
> > > +			power-domains = <&sysctrl>;
> > > +			status = "disabled";    
> > 
> > If you provided all resources (clocks, power domains etc), why disabling it?  
> 
> Because I forgot to remove the 'status' property ...
> 'status' will be simply removed in v3.
> Sorry for this mistake.
> 
> Thanks for the review,
> Hervé
> 

I said something completely wrong for this point.

status is set disabled because it is a .dtsi and can be
included by several dts to represent a board.
This node (USB device) can be wired on some board and not on
some others.
So, the node will be enabled in each dts board that has the USBF
device wired and used.

Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-15 15:09       ` Herve Codina
@ 2022-11-15 16:30         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-15 16:30 UTC (permalink / raw)
  To: Herve Codina
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 15/11/2022 16:09, Herve Codina wrote:
> Hi Krzysztof
> 
> On Tue, 15 Nov 2022 14:27:54 +0100
> Herve Codina <herve.codina@bootlin.com> wrote:
> 
>> Hi Krzysztof,
>>
>> On Tue, 15 Nov 2022 14:16:27 +0100
>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>
>>> On 14/11/2022 12:15, Herve Codina wrote:  
>>>> Add the USBF controller available in the r9a06g032 SoC.
>>>>
>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
>>>> ---
>>>>  arch/arm/boot/dts/r9a06g032.dtsi | 12 ++++++++++++
>>>>  1 file changed, 12 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
>>>> index 563024c9a4ae..a4bb069457a3 100644
>>>> --- a/arch/arm/boot/dts/r9a06g032.dtsi
>>>> +++ b/arch/arm/boot/dts/r9a06g032.dtsi
>>>> @@ -117,6 +117,18 @@ dmamux: dma-router@a0 {
>>>>  			};
>>>>  		};
>>>>  
>>>> +		udc: usb@4001e000 {
>>>> +			compatible = "renesas,r9a06g032-usbf", "renesas,rzn1-usbf";
>>>> +			reg = <0x4001e000 0x2000>;
>>>> +			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
>>>> +				     <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>>>> +			clocks = <&sysctrl R9A06G032_HCLK_USBF>,
>>>> +				 <&sysctrl R9A06G032_HCLK_USBPM>;
>>>> +			clock-names = "hclkf", "hclkpm";
>>>> +			power-domains = <&sysctrl>;
>>>> +			status = "disabled";    
>>>
>>> If you provided all resources (clocks, power domains etc), why disabling it?  
>>
>> Because I forgot to remove the 'status' property ...
>> 'status' will be simply removed in v3.
>> Sorry for this mistake.
>>
>> Thanks for the review,
>> Hervé
>>
> 
> I said something completely wrong for this point.
> 
> status is set disabled because it is a .dtsi and can be
> included by several dts to represent a board.
> This node (USB device) can be wired on some board and not on
> some others.
> So, the node will be enabled in each dts board that has the USBF
> device wired and used.

So it depends on having the connector? Yes, makes sense as well.
Actually my recommendation was about internal parts of OS, which usually
do not require anything from board. I missed the part that it is an USB...

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node
  2022-11-14 11:15 ` [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node Herve Codina
  2022-11-15 13:16   ` Krzysztof Kozlowski
@ 2022-11-16  8:51   ` Geert Uytterhoeven
  1 sibling, 0 replies; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-16  8:51 UTC (permalink / raw)
  To: Herve Codina
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On Mon, Nov 14, 2022 at 12:15 PM Herve Codina <herve.codina@bootlin.com> wrote:
> Add the USBF controller available in the r9a06g032 SoC.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-15 14:04       ` Herve Codina
@ 2022-11-18 10:23         ` Herve Codina
  2022-11-21 11:43           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-18 10:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof, Geert,

On Tue, 15 Nov 2022 15:04:17 +0100
Herve Codina <herve.codina@bootlin.com> wrote:

> Hi Krzysztof,
> 
> On Tue, 15 Nov 2022 14:07:52 +0100
> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> 
> > On 15/11/2022 14:05, Krzysztof Kozlowski wrote:  
> > > On 14/11/2022 12:15, Herve Codina wrote:    
> > >> Add the h2mode property to force the USBs mode ie:
> > >>  - 2 hosts
> > >> or
> > >>  - 1 host and 1 device
> > >>
> > >> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> > >> ---
> > >>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
> > >>  1 file changed, 10 insertions(+)
> > >>
> > >> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> > >> index 95bf485c6cec..f9e0a58aa4fb 100644
> > >> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> > >> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> > >> @@ -39,6 +39,16 @@ properties:
> > >>    '#power-domain-cells':
> > >>      const: 0
> > >>  
> > >> +  renesas,h2mode:
> > >> +    description: |
> > >> +      Configure the USBs mode.
> > >> +        - <0> : the USBs are in 1 host and 1 device mode.
> > >> +        - <1> : the USBs are in 2 host mode.
> > >> +      If the property is not present, the value used is the one already present
> > >> +      in the CFG_USB register (from reset or set by the bootloader).
> > >> +    $ref: /schemas/types.yaml#/definitions/uint32
> > >> +    enum: [0, 1]    
> > > 
> > > 0/1 are quite cryptic. Why not making it a string which is easy to read
> > > and understand? Can be something like "two-hosts" and "one-host". Or
> > > anything you find more readable...    
> > 
> > ...but actually you should rather make it a property of your USB
> > controller, not clock controller. You have two controllers and we have a
> > generic property for them - dr_mode.
> > 
> > Best regards,
> > Krzysztof
> >   
> 
> IMHO, this property in the USB controllers does not make sense.
> Indeed each controller cannot have a different 'mode'.
> Some controllers are USB host only (EHCI and OHCI) and the USBF
> controller I worked on is device only.
> 'h2mode' allows to choose between host or device on one of the USB
> but not at the USB controller level.
> 
> This property should be handle outside the USB controller nodes.
> 
> Currently, this node (declared as a clock node) is in fact a sysctrl
> node and can do some configuration not related to clocks.
> 
> I agree with you something related to choosing USB Host/Device in
> a clock node seems strange.
> 
> Some discussion were already opened related to this property and how
> to handle it:
>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
> 

We advanced on this topic.

First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
the devicetree/bindings/clock/ directory, this node is really
a 'system controller' node:
- title: Renesas RZ/N1D (R9A06G032) System Controller
- compatible: renesas,r9a06g032-sysctrl

It handles clocks, power domains, some DMA routing, ...

Now, the property 'h2mode' allows to choose between:
  - 2 USB hosts
or
  - 1 USB host and 1 USB device.

This switching is system wide and has no reason to be done in
one specific USB controller. It can impact multiple devices and
PLL settings.

The 'renesas,r9a06g032-sysctrl' node, as the system control
node of our system, is the best candidate to handle the property.

In order to be less cryptic in the property value, what do you
think about:
  renesas,h2mode:
    - one-dev : the USBs are in 1 host and 1 device mode.
    - only-hosts : the USBs are in 2 hosts mode.

With these details and change on the property value,
Is it ok for you to have the 'renesas,h2mode' property
in the 'renesas,r9a06g032-sysctrl' node ?


Regards,
Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-18 10:23         ` Herve Codina
@ 2022-11-21 11:43           ` Krzysztof Kozlowski
  2022-11-21 15:59             ` Herve Codina
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-21 11:43 UTC (permalink / raw)
  To: Herve Codina
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 18/11/2022 11:23, Herve Codina wrote:
> Hi Krzysztof, Geert,
> 
> On Tue, 15 Nov 2022 15:04:17 +0100
> Herve Codina <herve.codina@bootlin.com> wrote:
> 
>> Hi Krzysztof,
>>
>> On Tue, 15 Nov 2022 14:07:52 +0100
>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>
>>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:  
>>>> On 14/11/2022 12:15, Herve Codina wrote:    
>>>>> Add the h2mode property to force the USBs mode ie:
>>>>>  - 2 hosts
>>>>> or
>>>>>  - 1 host and 1 device
>>>>>
>>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
>>>>> ---
>>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
>>>>>  1 file changed, 10 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
>>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>> @@ -39,6 +39,16 @@ properties:
>>>>>    '#power-domain-cells':
>>>>>      const: 0
>>>>>  
>>>>> +  renesas,h2mode:
>>>>> +    description: |
>>>>> +      Configure the USBs mode.
>>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
>>>>> +        - <1> : the USBs are in 2 host mode.
>>>>> +      If the property is not present, the value used is the one already present
>>>>> +      in the CFG_USB register (from reset or set by the bootloader).
>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>>> +    enum: [0, 1]    
>>>>
>>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
>>>> and understand? Can be something like "two-hosts" and "one-host". Or
>>>> anything you find more readable...    
>>>
>>> ...but actually you should rather make it a property of your USB
>>> controller, not clock controller. You have two controllers and we have a
>>> generic property for them - dr_mode.
>>>
>>> Best regards,
>>> Krzysztof
>>>   
>>
>> IMHO, this property in the USB controllers does not make sense.
>> Indeed each controller cannot have a different 'mode'.
>> Some controllers are USB host only (EHCI and OHCI) and the USBF
>> controller I worked on is device only.
>> 'h2mode' allows to choose between host or device on one of the USB
>> but not at the USB controller level.
>>
>> This property should be handle outside the USB controller nodes.
>>
>> Currently, this node (declared as a clock node) is in fact a sysctrl
>> node and can do some configuration not related to clocks.
>>
>> I agree with you something related to choosing USB Host/Device in
>> a clock node seems strange.
>>
>> Some discussion were already opened related to this property and how
>> to handle it:
>>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
>>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
>>
> 
> We advanced on this topic.
> 
> First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
> the devicetree/bindings/clock/ directory, this node is really
> a 'system controller' node:
> - title: Renesas RZ/N1D (R9A06G032) System Controller
> - compatible: renesas,r9a06g032-sysctrl
> 
> It handles clocks, power domains, some DMA routing, ...
> 
> Now, the property 'h2mode' allows to choose between:
>   - 2 USB hosts
> or
>   - 1 USB host and 1 USB device.
> 
> This switching is system wide and has no reason to be done in
> one specific USB controller. It can impact multiple devices and
> PLL settings.
> 
> The 'renesas,r9a06g032-sysctrl' node, as the system control
> node of our system, is the best candidate to handle the property.

Not necessarily. IIUC, you have:

1. sysctrl with some register(s) for choosing device mode
2. usb device or host at one address
3. usb host at separate address

If so then:
A. Pretty often we have wrapper nodes for this purpose (USB, phy
wrappers or glues) which are usually needed to configure something for a
generic block (like Synopsys etc).

B. Pretty often the device (so your USB host or device) needs to poke
something in system controller registers, e.g. for power or some other
setup.

Your case looks a lot like (B). We have many, many of such examples
already. Actually it is exactly like that, except that it affects
possibility of another device (e.g. choosing USB device blocks having
host there).

C. It looks a bit like a multi-serial-protocol interfaces (so
UART+I2C+SPI). The difference is that such cases have all these nodes
defined as a children of the protocol-wrapping device. Not here.

I would propose to go with (B) unless of course it's causes some crazy
architecture/code choices. Why? Because with exception of (C) we should
not define properties which represent DT node choices. IOW, Choosing a
node and compatible (e.g. usb controller as device) is enough to
describe the hardware. No need for other properties to control some
register in other block.


> 
> In order to be less cryptic in the property value, what do you
> think about:
>   renesas,h2mode:
>     - one-dev : the USBs are in 1 host and 1 device mode.
>     - only-hosts : the USBs are in 2 hosts mode.

Name looks better, if we go this path.

> 
> With these details and change on the property value,
> Is it ok for you to have the 'renesas,h2mode' property
> in the 'renesas,r9a06g032-sysctrl' node ?


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 11:43           ` Krzysztof Kozlowski
@ 2022-11-21 15:59             ` Herve Codina
  2022-11-21 16:33               ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-21 15:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi,

On Mon, 21 Nov 2022 12:43:16 +0100
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:

> On 18/11/2022 11:23, Herve Codina wrote:
> > Hi Krzysztof, Geert,
> > 
> > On Tue, 15 Nov 2022 15:04:17 +0100
> > Herve Codina <herve.codina@bootlin.com> wrote:
> >   
> >> Hi Krzysztof,
> >>
> >> On Tue, 15 Nov 2022 14:07:52 +0100
> >> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >>  
> >>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:    
> >>>> On 14/11/2022 12:15, Herve Codina wrote:      
> >>>>> Add the h2mode property to force the USBs mode ie:
> >>>>>  - 2 hosts
> >>>>> or
> >>>>>  - 1 host and 1 device
> >>>>>
> >>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> >>>>> ---
> >>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
> >>>>>  1 file changed, 10 insertions(+)
> >>>>>
> >>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
> >>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>> @@ -39,6 +39,16 @@ properties:
> >>>>>    '#power-domain-cells':
> >>>>>      const: 0
> >>>>>  
> >>>>> +  renesas,h2mode:
> >>>>> +    description: |
> >>>>> +      Configure the USBs mode.
> >>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
> >>>>> +        - <1> : the USBs are in 2 host mode.
> >>>>> +      If the property is not present, the value used is the one already present
> >>>>> +      in the CFG_USB register (from reset or set by the bootloader).
> >>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>>>> +    enum: [0, 1]      
> >>>>
> >>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
> >>>> and understand? Can be something like "two-hosts" and "one-host". Or
> >>>> anything you find more readable...      
> >>>
> >>> ...but actually you should rather make it a property of your USB
> >>> controller, not clock controller. You have two controllers and we have a
> >>> generic property for them - dr_mode.
> >>>
> >>> Best regards,
> >>> Krzysztof
> >>>     
> >>
> >> IMHO, this property in the USB controllers does not make sense.
> >> Indeed each controller cannot have a different 'mode'.
> >> Some controllers are USB host only (EHCI and OHCI) and the USBF
> >> controller I worked on is device only.
> >> 'h2mode' allows to choose between host or device on one of the USB
> >> but not at the USB controller level.
> >>
> >> This property should be handle outside the USB controller nodes.
> >>
> >> Currently, this node (declared as a clock node) is in fact a sysctrl
> >> node and can do some configuration not related to clocks.
> >>
> >> I agree with you something related to choosing USB Host/Device in
> >> a clock node seems strange.
> >>
> >> Some discussion were already opened related to this property and how
> >> to handle it:
> >>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
> >>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
> >>  
> > 
> > We advanced on this topic.
> > 
> > First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
> > the devicetree/bindings/clock/ directory, this node is really
> > a 'system controller' node:
> > - title: Renesas RZ/N1D (R9A06G032) System Controller
> > - compatible: renesas,r9a06g032-sysctrl
> > 
> > It handles clocks, power domains, some DMA routing, ...
> > 
> > Now, the property 'h2mode' allows to choose between:
> >   - 2 USB hosts
> > or
> >   - 1 USB host and 1 USB device.
> > 
> > This switching is system wide and has no reason to be done in
> > one specific USB controller. It can impact multiple devices and
> > PLL settings.
> > 
> > The 'renesas,r9a06g032-sysctrl' node, as the system control
> > node of our system, is the best candidate to handle the property.  
> 
> Not necessarily. IIUC, you have:
> 
> 1. sysctrl with some register(s) for choosing device mode
> 2. usb device or host at one address
> 3. usb host at separate address
> 

Just to clarify, usb device and host controller are not provided by
the same IP.
We have an USB host at some address range (PCI OHCI/EHCI USB host
below a PCI bridge) and the USB device at some other address range
(below a AHB to someting bridge).
And I am not sure that only USB host or devices are affected by this
property change.

> If so then:
> A. Pretty often we have wrapper nodes for this purpose (USB, phy
> wrappers or glues) which are usually needed to configure something for a
> generic block (like Synopsys etc).
> 
> B. Pretty often the device (so your USB host or device) needs to poke
> something in system controller registers, e.g. for power or some other
> setup.

And we did it for some items (clocks and power).

> 
> Your case looks a lot like (B). We have many, many of such examples
> already. Actually it is exactly like that, except that it affects
> possibility of another device (e.g. choosing USB device blocks having
> host there).
> 
> C. It looks a bit like a multi-serial-protocol interfaces (so
> UART+I2C+SPI). The difference is that such cases have all these nodes
> defined as a children of the protocol-wrapping device. Not here.
> 
> I would propose to go with (B) unless of course it's causes some crazy
> architecture/code choices. Why? Because with exception of (C) we should
> not define properties which represent DT node choices. IOW, Choosing a
> node and compatible (e.g. usb controller as device) is enough to
> describe the hardware. No need for other properties to control some
> register in other block.

The issue with h2mode is that it affects several devices and these
devices should not be in a "running" state when the h2mode is changed.

PCI devices (host controllers) itself are not described in the DT. They
are automatically enumerated.
Changing the property in USB device controller can leads to hang on
other busses. Indeed, changing this property when a device affected
by the property is running can lead to a bus hang.

In order to do that from the USB device controller I need to synchronize
the other devices to wait for this setting before running.
1) probe sysctrl without setting h2mode
2) probe some devices (USB host and probably others)
   Stop at some point and wait for the h2mode property setting.
3) probe usb device -> Set h2mode property
4) allow devices waiting for the property setting to continue.

This synchronization seems pretty tricky and what to do if nobody
set the property (USB device controller not present or status="disabled"
for instance) ?

Setting this property in sysctrl probe avoid the need for all of this
synchronization:
1) probe sysctrl and set h2mode.
2) probe other devices (no need to wait for the setting as it is already done)

The probing of the other devices (or the starting of they running state)
is guaranteed as they all need some clocks and so cannot start without
having the sysctrl node already probed.
This sysctrl node handles the clocks.

So, I think that this property must be set during sysctrl probe call.


From the DT point of view, I can put the property in the USB device
controller node but I have the feeling that, if I do that, I will do
some ugly things at sysctrl probe such as parsing nodes other than the
sysctrl one to find the property and set h2mode accordingly :(

> 
> 
> > 
> > In order to be less cryptic in the property value, what do you
> > think about:
> >   renesas,h2mode:
> >     - one-dev : the USBs are in 1 host and 1 device mode.
> >     - only-hosts : the USBs are in 2 hosts mode.  
> 
> Name looks better, if we go this path.

Ok, I will take care if we go this path.

> 
> > 
> > With these details and change on the property value,
> > Is it ok for you to have the 'renesas,h2mode' property
> > in the 'renesas,r9a06g032-sysctrl' node ?  
> 
> 

Regards,
Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 15:59             ` Herve Codina
@ 2022-11-21 16:33               ` Krzysztof Kozlowski
  2022-11-21 16:36                 ` Geert Uytterhoeven
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-21 16:33 UTC (permalink / raw)
  To: Herve Codina
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 21/11/2022 16:59, Herve Codina wrote:
> Hi,
> 
> On Mon, 21 Nov 2022 12:43:16 +0100
> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> 
>> On 18/11/2022 11:23, Herve Codina wrote:
>>> Hi Krzysztof, Geert,
>>>
>>> On Tue, 15 Nov 2022 15:04:17 +0100
>>> Herve Codina <herve.codina@bootlin.com> wrote:
>>>   
>>>> Hi Krzysztof,
>>>>
>>>> On Tue, 15 Nov 2022 14:07:52 +0100
>>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>>>  
>>>>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:    
>>>>>> On 14/11/2022 12:15, Herve Codina wrote:      
>>>>>>> Add the h2mode property to force the USBs mode ie:
>>>>>>>  - 2 hosts
>>>>>>> or
>>>>>>>  - 1 host and 1 device
>>>>>>>
>>>>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
>>>>>>> ---
>>>>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
>>>>>>>  1 file changed, 10 insertions(+)
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
>>>>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>> @@ -39,6 +39,16 @@ properties:
>>>>>>>    '#power-domain-cells':
>>>>>>>      const: 0
>>>>>>>  
>>>>>>> +  renesas,h2mode:
>>>>>>> +    description: |
>>>>>>> +      Configure the USBs mode.
>>>>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
>>>>>>> +        - <1> : the USBs are in 2 host mode.
>>>>>>> +      If the property is not present, the value used is the one already present
>>>>>>> +      in the CFG_USB register (from reset or set by the bootloader).
>>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>> +    enum: [0, 1]      
>>>>>>
>>>>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
>>>>>> and understand? Can be something like "two-hosts" and "one-host". Or
>>>>>> anything you find more readable...      
>>>>>
>>>>> ...but actually you should rather make it a property of your USB
>>>>> controller, not clock controller. You have two controllers and we have a
>>>>> generic property for them - dr_mode.
>>>>>
>>>>> Best regards,
>>>>> Krzysztof
>>>>>     
>>>>
>>>> IMHO, this property in the USB controllers does not make sense.
>>>> Indeed each controller cannot have a different 'mode'.
>>>> Some controllers are USB host only (EHCI and OHCI) and the USBF
>>>> controller I worked on is device only.
>>>> 'h2mode' allows to choose between host or device on one of the USB
>>>> but not at the USB controller level.
>>>>
>>>> This property should be handle outside the USB controller nodes.
>>>>
>>>> Currently, this node (declared as a clock node) is in fact a sysctrl
>>>> node and can do some configuration not related to clocks.
>>>>
>>>> I agree with you something related to choosing USB Host/Device in
>>>> a clock node seems strange.
>>>>
>>>> Some discussion were already opened related to this property and how
>>>> to handle it:
>>>>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
>>>>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
>>>>  
>>>
>>> We advanced on this topic.
>>>
>>> First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
>>> the devicetree/bindings/clock/ directory, this node is really
>>> a 'system controller' node:
>>> - title: Renesas RZ/N1D (R9A06G032) System Controller
>>> - compatible: renesas,r9a06g032-sysctrl
>>>
>>> It handles clocks, power domains, some DMA routing, ...
>>>
>>> Now, the property 'h2mode' allows to choose between:
>>>   - 2 USB hosts
>>> or
>>>   - 1 USB host and 1 USB device.
>>>
>>> This switching is system wide and has no reason to be done in
>>> one specific USB controller. It can impact multiple devices and
>>> PLL settings.
>>>
>>> The 'renesas,r9a06g032-sysctrl' node, as the system control
>>> node of our system, is the best candidate to handle the property.  
>>
>> Not necessarily. IIUC, you have:
>>
>> 1. sysctrl with some register(s) for choosing device mode
>> 2. usb device or host at one address
>> 3. usb host at separate address
>>
> 
> Just to clarify, usb device and host controller are not provided by
> the same IP.
> We have an USB host at some address range (PCI OHCI/EHCI USB host
> below a PCI bridge) and the USB device at some other address range
> (below a AHB to someting bridge).
> And I am not sure that only USB host or devices are affected by this
> property change.
> 
>> If so then:
>> A. Pretty often we have wrapper nodes for this purpose (USB, phy
>> wrappers or glues) which are usually needed to configure something for a
>> generic block (like Synopsys etc).
>>
>> B. Pretty often the device (so your USB host or device) needs to poke
>> something in system controller registers, e.g. for power or some other
>> setup.
> 
> And we did it for some items (clocks and power).
> 
>>
>> Your case looks a lot like (B). We have many, many of such examples
>> already. Actually it is exactly like that, except that it affects
>> possibility of another device (e.g. choosing USB device blocks having
>> host there).
>>
>> C. It looks a bit like a multi-serial-protocol interfaces (so
>> UART+I2C+SPI). The difference is that such cases have all these nodes
>> defined as a children of the protocol-wrapping device. Not here.
>>
>> I would propose to go with (B) unless of course it's causes some crazy
>> architecture/code choices. Why? Because with exception of (C) we should
>> not define properties which represent DT node choices. IOW, Choosing a
>> node and compatible (e.g. usb controller as device) is enough to
>> describe the hardware. No need for other properties to control some
>> register in other block.
> 
> The issue with h2mode is that it affects several devices and these
> devices should not be in a "running" state when the h2mode is changed.

Why the change should happen when device is running? And why this should
be anyway different than your existing hsmode property - it also will
happen when system and device are running.


> PCI devices (host controllers) itself are not described in the DT. They
> are automatically enumerated.

Aren't we talking about USB controller in a MMIO-based SoC?

> Changing the property in USB device controller can leads to hang on
> other busses. Indeed, changing this property when a device affected
> by the property is running can lead to a bus hang.>
> In order to do that from the USB device controller I need to synchronize
> the other devices to wait for this setting before running.
> 1) probe sysctrl without setting h2mode
> 2) probe some devices (USB host and probably others)
>    Stop at some point and wait for the h2mode property setting.

Why do you need to wait? Which device needs to wait? There are no such
devices... if they are then please bring entire DTS, not some pieces in
this patchset.

> 3) probe usb device -> Set h2mode property
> 4) allow devices waiting for the property setting to continue.

I don't get why do you need such order. Your sysctrl also probes any
time so old solution has exactly the same problem, doesn't it?

> This synchronization seems pretty tricky and what to do if nobody
> set the property (USB device controller not present or status="disabled"
> for instance) ?
> 
> Setting this property in sysctrl probe avoid the need for all of this
> synchronization:
> 1) probe sysctrl and set h2mode.
> 2) probe other devices (no need to wait for the setting as it is already done)

No, because other devices probe before sysctrl. If you bring here any
manual ordering, you are doing it wrong.

> The probing of the other devices (or the starting of they running state)
> is guaranteed as they all need some clocks and so cannot start without
> having the sysctrl node already probed.
> This sysctrl node handles the clocks.

Ah, so sysctrl is a clock controller for these?

Then still there are no other devices depending on your USB. The USB is
the owner of this property (specific bits in register), no one else.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 16:33               ` Krzysztof Kozlowski
@ 2022-11-21 16:36                 ` Geert Uytterhoeven
  2022-11-21 17:11                   ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-21 16:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Mon, Nov 21, 2022 at 5:33 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 21/11/2022 16:59, Herve Codina wrote:
> > On Mon, 21 Nov 2022 12:43:16 +0100
> > Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >> On 18/11/2022 11:23, Herve Codina wrote:
> >>> On Tue, 15 Nov 2022 15:04:17 +0100
> >>> Herve Codina <herve.codina@bootlin.com> wrote:
> >>>> On Tue, 15 Nov 2022 14:07:52 +0100
> >>>>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:
> >>>>>> On 14/11/2022 12:15, Herve Codina wrote:
> >>>>>>> Add the h2mode property to force the USBs mode ie:
> >>>>>>>  - 2 hosts
> >>>>>>> or
> >>>>>>>  - 1 host and 1 device
> >>>>>>>
> >>>>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> >>>>>>> ---
> >>>>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
> >>>>>>>  1 file changed, 10 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
> >>>>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>> @@ -39,6 +39,16 @@ properties:
> >>>>>>>    '#power-domain-cells':
> >>>>>>>      const: 0
> >>>>>>>
> >>>>>>> +  renesas,h2mode:
> >>>>>>> +    description: |
> >>>>>>> +      Configure the USBs mode.
> >>>>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
> >>>>>>> +        - <1> : the USBs are in 2 host mode.
> >>>>>>> +      If the property is not present, the value used is the one already present
> >>>>>>> +      in the CFG_USB register (from reset or set by the bootloader).
> >>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>>> +    enum: [0, 1]
> >>>>>>
> >>>>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
> >>>>>> and understand? Can be something like "two-hosts" and "one-host". Or
> >>>>>> anything you find more readable...
> >>>>>
> >>>>> ...but actually you should rather make it a property of your USB
> >>>>> controller, not clock controller. You have two controllers and we have a
> >>>>> generic property for them - dr_mode.
> >>>>>
> >>>>> Best regards,
> >>>>> Krzysztof
> >>>>>
> >>>>
> >>>> IMHO, this property in the USB controllers does not make sense.
> >>>> Indeed each controller cannot have a different 'mode'.
> >>>> Some controllers are USB host only (EHCI and OHCI) and the USBF
> >>>> controller I worked on is device only.
> >>>> 'h2mode' allows to choose between host or device on one of the USB
> >>>> but not at the USB controller level.
> >>>>
> >>>> This property should be handle outside the USB controller nodes.
> >>>>
> >>>> Currently, this node (declared as a clock node) is in fact a sysctrl
> >>>> node and can do some configuration not related to clocks.
> >>>>
> >>>> I agree with you something related to choosing USB Host/Device in
> >>>> a clock node seems strange.
> >>>>
> >>>> Some discussion were already opened related to this property and how
> >>>> to handle it:
> >>>>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
> >>>>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
> >>>>
> >>>
> >>> We advanced on this topic.
> >>>
> >>> First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
> >>> the devicetree/bindings/clock/ directory, this node is really
> >>> a 'system controller' node:
> >>> - title: Renesas RZ/N1D (R9A06G032) System Controller
> >>> - compatible: renesas,r9a06g032-sysctrl
> >>>
> >>> It handles clocks, power domains, some DMA routing, ...
> >>>
> >>> Now, the property 'h2mode' allows to choose between:
> >>>   - 2 USB hosts
> >>> or
> >>>   - 1 USB host and 1 USB device.
> >>>
> >>> This switching is system wide and has no reason to be done in
> >>> one specific USB controller. It can impact multiple devices and
> >>> PLL settings.
> >>>
> >>> The 'renesas,r9a06g032-sysctrl' node, as the system control
> >>> node of our system, is the best candidate to handle the property.
> >>
> >> Not necessarily. IIUC, you have:
> >>
> >> 1. sysctrl with some register(s) for choosing device mode
> >> 2. usb device or host at one address
> >> 3. usb host at separate address
> >>
> >
> > Just to clarify, usb device and host controller are not provided by
> > the same IP.
> > We have an USB host at some address range (PCI OHCI/EHCI USB host
> > below a PCI bridge) and the USB device at some other address range
> > (below a AHB to someting bridge).
> > And I am not sure that only USB host or devices are affected by this
> > property change.
> >
> >> If so then:
> >> A. Pretty often we have wrapper nodes for this purpose (USB, phy
> >> wrappers or glues) which are usually needed to configure something for a
> >> generic block (like Synopsys etc).
> >>
> >> B. Pretty often the device (so your USB host or device) needs to poke
> >> something in system controller registers, e.g. for power or some other
> >> setup.
> >
> > And we did it for some items (clocks and power).
> >
> >>
> >> Your case looks a lot like (B). We have many, many of such examples
> >> already. Actually it is exactly like that, except that it affects
> >> possibility of another device (e.g. choosing USB device blocks having
> >> host there).
> >>
> >> C. It looks a bit like a multi-serial-protocol interfaces (so
> >> UART+I2C+SPI). The difference is that such cases have all these nodes
> >> defined as a children of the protocol-wrapping device. Not here.
> >>
> >> I would propose to go with (B) unless of course it's causes some crazy
> >> architecture/code choices. Why? Because with exception of (C) we should
> >> not define properties which represent DT node choices. IOW, Choosing a
> >> node and compatible (e.g. usb controller as device) is enough to
> >> describe the hardware. No need for other properties to control some
> >> register in other block.
> >
> > The issue with h2mode is that it affects several devices and these
> > devices should not be in a "running" state when the h2mode is changed.
>
> Why the change should happen when device is running? And why this should
> be anyway different than your existing hsmode property - it also will
> happen when system and device are running.
>
>
> > PCI devices (host controllers) itself are not described in the DT. They
> > are automatically enumerated.
>
> Aren't we talking about USB controller in a MMIO-based SoC?
>
> > Changing the property in USB device controller can leads to hang on
> > other busses. Indeed, changing this property when a device affected
> > by the property is running can lead to a bus hang.>
> > In order to do that from the USB device controller I need to synchronize
> > the other devices to wait for this setting before running.
> > 1) probe sysctrl without setting h2mode
> > 2) probe some devices (USB host and probably others)
> >    Stop at some point and wait for the h2mode property setting.
>
> Why do you need to wait? Which device needs to wait? There are no such
> devices... if they are then please bring entire DTS, not some pieces in
> this patchset.
>
> > 3) probe usb device -> Set h2mode property
> > 4) allow devices waiting for the property setting to continue.
>
> I don't get why do you need such order. Your sysctrl also probes any
> time so old solution has exactly the same problem, doesn't it?
>
> > This synchronization seems pretty tricky and what to do if nobody
> > set the property (USB device controller not present or status="disabled"
> > for instance) ?
> >
> > Setting this property in sysctrl probe avoid the need for all of this
> > synchronization:
> > 1) probe sysctrl and set h2mode.
> > 2) probe other devices (no need to wait for the setting as it is already done)
>
> No, because other devices probe before sysctrl. If you bring here any
> manual ordering, you are doing it wrong.
>
> > The probing of the other devices (or the starting of they running state)
> > is guaranteed as they all need some clocks and so cannot start without
> > having the sysctrl node already probed.
> > This sysctrl node handles the clocks.
>
> Ah, so sysctrl is a clock controller for these?
>
> Then still there are no other devices depending on your USB. The USB is
> the owner of this property (specific bits in register), no one else.

1. There are two USB devices.
2. The USB drivers can be modular, the sysctrl driver cannot, as it is
   the main clock controller.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 16:36                 ` Geert Uytterhoeven
@ 2022-11-21 17:11                   ` Krzysztof Kozlowski
  2022-11-21 20:46                     ` Geert Uytterhoeven
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-21 17:11 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Geert Uytterhoeven, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni, Miquel Raynal

On 21/11/2022 17:36, Geert Uytterhoeven wrote:
> Hi Krzysztof,
> 
> On Mon, Nov 21, 2022 at 5:33 PM Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>> On 21/11/2022 16:59, Herve Codina wrote:
>>> On Mon, 21 Nov 2022 12:43:16 +0100
>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>>> On 18/11/2022 11:23, Herve Codina wrote:
>>>>> On Tue, 15 Nov 2022 15:04:17 +0100
>>>>> Herve Codina <herve.codina@bootlin.com> wrote:
>>>>>> On Tue, 15 Nov 2022 14:07:52 +0100
>>>>>>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:
>>>>>>>> On 14/11/2022 12:15, Herve Codina wrote:
>>>>>>>>> Add the h2mode property to force the USBs mode ie:
>>>>>>>>>  - 2 hosts
>>>>>>>>> or
>>>>>>>>>  - 1 host and 1 device
>>>>>>>>>
>>>>>>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
>>>>>>>>> ---
>>>>>>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
>>>>>>>>>  1 file changed, 10 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
>>>>>>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
>>>>>>>>> @@ -39,6 +39,16 @@ properties:
>>>>>>>>>    '#power-domain-cells':
>>>>>>>>>      const: 0
>>>>>>>>>
>>>>>>>>> +  renesas,h2mode:
>>>>>>>>> +    description: |
>>>>>>>>> +      Configure the USBs mode.
>>>>>>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
>>>>>>>>> +        - <1> : the USBs are in 2 host mode.
>>>>>>>>> +      If the property is not present, the value used is the one already present
>>>>>>>>> +      in the CFG_USB register (from reset or set by the bootloader).
>>>>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>>>> +    enum: [0, 1]
>>>>>>>>
>>>>>>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
>>>>>>>> and understand? Can be something like "two-hosts" and "one-host". Or
>>>>>>>> anything you find more readable...
>>>>>>>
>>>>>>> ...but actually you should rather make it a property of your USB
>>>>>>> controller, not clock controller. You have two controllers and we have a
>>>>>>> generic property for them - dr_mode.
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Krzysztof
>>>>>>>
>>>>>>
>>>>>> IMHO, this property in the USB controllers does not make sense.
>>>>>> Indeed each controller cannot have a different 'mode'.
>>>>>> Some controllers are USB host only (EHCI and OHCI) and the USBF
>>>>>> controller I worked on is device only.
>>>>>> 'h2mode' allows to choose between host or device on one of the USB
>>>>>> but not at the USB controller level.
>>>>>>
>>>>>> This property should be handle outside the USB controller nodes.
>>>>>>
>>>>>> Currently, this node (declared as a clock node) is in fact a sysctrl
>>>>>> node and can do some configuration not related to clocks.
>>>>>>
>>>>>> I agree with you something related to choosing USB Host/Device in
>>>>>> a clock node seems strange.
>>>>>>
>>>>>> Some discussion were already opened related to this property and how
>>>>>> to handle it:
>>>>>>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
>>>>>>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
>>>>>>
>>>>>
>>>>> We advanced on this topic.
>>>>>
>>>>> First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
>>>>> the devicetree/bindings/clock/ directory, this node is really
>>>>> a 'system controller' node:
>>>>> - title: Renesas RZ/N1D (R9A06G032) System Controller
>>>>> - compatible: renesas,r9a06g032-sysctrl
>>>>>
>>>>> It handles clocks, power domains, some DMA routing, ...
>>>>>
>>>>> Now, the property 'h2mode' allows to choose between:
>>>>>   - 2 USB hosts
>>>>> or
>>>>>   - 1 USB host and 1 USB device.
>>>>>
>>>>> This switching is system wide and has no reason to be done in
>>>>> one specific USB controller. It can impact multiple devices and
>>>>> PLL settings.
>>>>>
>>>>> The 'renesas,r9a06g032-sysctrl' node, as the system control
>>>>> node of our system, is the best candidate to handle the property.
>>>>
>>>> Not necessarily. IIUC, you have:
>>>>
>>>> 1. sysctrl with some register(s) for choosing device mode
>>>> 2. usb device or host at one address
>>>> 3. usb host at separate address
>>>>
>>>
>>> Just to clarify, usb device and host controller are not provided by
>>> the same IP.
>>> We have an USB host at some address range (PCI OHCI/EHCI USB host
>>> below a PCI bridge) and the USB device at some other address range
>>> (below a AHB to someting bridge).
>>> And I am not sure that only USB host or devices are affected by this
>>> property change.
>>>
>>>> If so then:
>>>> A. Pretty often we have wrapper nodes for this purpose (USB, phy
>>>> wrappers or glues) which are usually needed to configure something for a
>>>> generic block (like Synopsys etc).
>>>>
>>>> B. Pretty often the device (so your USB host or device) needs to poke
>>>> something in system controller registers, e.g. for power or some other
>>>> setup.
>>>
>>> And we did it for some items (clocks and power).
>>>
>>>>
>>>> Your case looks a lot like (B). We have many, many of such examples
>>>> already. Actually it is exactly like that, except that it affects
>>>> possibility of another device (e.g. choosing USB device blocks having
>>>> host there).
>>>>
>>>> C. It looks a bit like a multi-serial-protocol interfaces (so
>>>> UART+I2C+SPI). The difference is that such cases have all these nodes
>>>> defined as a children of the protocol-wrapping device. Not here.
>>>>
>>>> I would propose to go with (B) unless of course it's causes some crazy
>>>> architecture/code choices. Why? Because with exception of (C) we should
>>>> not define properties which represent DT node choices. IOW, Choosing a
>>>> node and compatible (e.g. usb controller as device) is enough to
>>>> describe the hardware. No need for other properties to control some
>>>> register in other block.
>>>
>>> The issue with h2mode is that it affects several devices and these
>>> devices should not be in a "running" state when the h2mode is changed.
>>
>> Why the change should happen when device is running? And why this should
>> be anyway different than your existing hsmode property - it also will
>> happen when system and device are running.
>>
>>
>>> PCI devices (host controllers) itself are not described in the DT. They
>>> are automatically enumerated.
>>
>> Aren't we talking about USB controller in a MMIO-based SoC?
>>
>>> Changing the property in USB device controller can leads to hang on
>>> other busses. Indeed, changing this property when a device affected
>>> by the property is running can lead to a bus hang.>
>>> In order to do that from the USB device controller I need to synchronize
>>> the other devices to wait for this setting before running.
>>> 1) probe sysctrl without setting h2mode
>>> 2) probe some devices (USB host and probably others)
>>>    Stop at some point and wait for the h2mode property setting.
>>
>> Why do you need to wait? Which device needs to wait? There are no such
>> devices... if they are then please bring entire DTS, not some pieces in
>> this patchset.
>>
>>> 3) probe usb device -> Set h2mode property
>>> 4) allow devices waiting for the property setting to continue.
>>
>> I don't get why do you need such order. Your sysctrl also probes any
>> time so old solution has exactly the same problem, doesn't it?
>>
>>> This synchronization seems pretty tricky and what to do if nobody
>>> set the property (USB device controller not present or status="disabled"
>>> for instance) ?
>>>
>>> Setting this property in sysctrl probe avoid the need for all of this
>>> synchronization:
>>> 1) probe sysctrl and set h2mode.
>>> 2) probe other devices (no need to wait for the setting as it is already done)
>>
>> No, because other devices probe before sysctrl. If you bring here any
>> manual ordering, you are doing it wrong.
>>
>>> The probing of the other devices (or the starting of they running state)
>>> is guaranteed as they all need some clocks and so cannot start without
>>> having the sysctrl node already probed.
>>> This sysctrl node handles the clocks.
>>
>> Ah, so sysctrl is a clock controller for these?
>>
>> Then still there are no other devices depending on your USB. The USB is
>> the owner of this property (specific bits in register), no one else.
> 
> 1. There are two USB devices.
> 2. The USB drivers can be modular, the sysctrl driver cannot, as it is
>    the main clock controller.

This does not change anything. Herve wrote:

> probe some devices (USB host and probably others)

Why some can be probed earlier and some not, if there are no
dependencies? If there are dependencies, it's the same case with sysctrl
touching the register bit and the USB controller touching it (as well
via syscon, but that's obvious, I assume).

Where is the synchronization problem?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 17:11                   ` Krzysztof Kozlowski
@ 2022-11-21 20:46                     ` Geert Uytterhoeven
  2022-11-22  7:45                       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-21 20:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Mon, Nov 21, 2022 at 6:11 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 21/11/2022 17:36, Geert Uytterhoeven wrote:
> > On Mon, Nov 21, 2022 at 5:33 PM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:
> >> On 21/11/2022 16:59, Herve Codina wrote:
> >>> On Mon, 21 Nov 2022 12:43:16 +0100
> >>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >>>> On 18/11/2022 11:23, Herve Codina wrote:
> >>>>> On Tue, 15 Nov 2022 15:04:17 +0100
> >>>>> Herve Codina <herve.codina@bootlin.com> wrote:
> >>>>>> On Tue, 15 Nov 2022 14:07:52 +0100
> >>>>>>> On 15/11/2022 14:05, Krzysztof Kozlowski wrote:
> >>>>>>>> On 14/11/2022 12:15, Herve Codina wrote:
> >>>>>>>>> Add the h2mode property to force the USBs mode ie:
> >>>>>>>>>  - 2 hosts
> >>>>>>>>> or
> >>>>>>>>>  - 1 host and 1 device
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> >>>>>>>>> ---
> >>>>>>>>>  .../bindings/clock/renesas,r9a06g032-sysctrl.yaml      | 10 ++++++++++
> >>>>>>>>>  1 file changed, 10 insertions(+)
> >>>>>>>>>
> >>>>>>>>> diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>>>> index 95bf485c6cec..f9e0a58aa4fb 100644
> >>>>>>>>> --- a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>>>> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.yaml
> >>>>>>>>> @@ -39,6 +39,16 @@ properties:
> >>>>>>>>>    '#power-domain-cells':
> >>>>>>>>>      const: 0
> >>>>>>>>>
> >>>>>>>>> +  renesas,h2mode:
> >>>>>>>>> +    description: |
> >>>>>>>>> +      Configure the USBs mode.
> >>>>>>>>> +        - <0> : the USBs are in 1 host and 1 device mode.
> >>>>>>>>> +        - <1> : the USBs are in 2 host mode.
> >>>>>>>>> +      If the property is not present, the value used is the one already present
> >>>>>>>>> +      in the CFG_USB register (from reset or set by the bootloader).
> >>>>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>>>>>>>> +    enum: [0, 1]
> >>>>>>>>
> >>>>>>>> 0/1 are quite cryptic. Why not making it a string which is easy to read
> >>>>>>>> and understand? Can be something like "two-hosts" and "one-host". Or
> >>>>>>>> anything you find more readable...
> >>>>>>>
> >>>>>>> ...but actually you should rather make it a property of your USB
> >>>>>>> controller, not clock controller. You have two controllers and we have a
> >>>>>>> generic property for them - dr_mode.
> >>>>>>>
> >>>>>>> Best regards,
> >>>>>>> Krzysztof
> >>>>>>>
> >>>>>>
> >>>>>> IMHO, this property in the USB controllers does not make sense.
> >>>>>> Indeed each controller cannot have a different 'mode'.
> >>>>>> Some controllers are USB host only (EHCI and OHCI) and the USBF
> >>>>>> controller I worked on is device only.
> >>>>>> 'h2mode' allows to choose between host or device on one of the USB
> >>>>>> but not at the USB controller level.
> >>>>>>
> >>>>>> This property should be handle outside the USB controller nodes.
> >>>>>>
> >>>>>> Currently, this node (declared as a clock node) is in fact a sysctrl
> >>>>>> node and can do some configuration not related to clocks.
> >>>>>>
> >>>>>> I agree with you something related to choosing USB Host/Device in
> >>>>>> a clock node seems strange.
> >>>>>>
> >>>>>> Some discussion were already opened related to this property and how
> >>>>>> to handle it:
> >>>>>>   https://lore.kernel.org/all/20221107182642.05a09f2f@bootlin.com/
> >>>>>>   https://lore.kernel.org/all/20221107173614.474707d7@bootlin.com/
> >>>>>>
> >>>>>
> >>>>> We advanced on this topic.
> >>>>>
> >>>>> First, even if 'renesas,r9a06g032-sysctrl.yaml' is present in
> >>>>> the devicetree/bindings/clock/ directory, this node is really
> >>>>> a 'system controller' node:
> >>>>> - title: Renesas RZ/N1D (R9A06G032) System Controller
> >>>>> - compatible: renesas,r9a06g032-sysctrl
> >>>>>
> >>>>> It handles clocks, power domains, some DMA routing, ...
> >>>>>
> >>>>> Now, the property 'h2mode' allows to choose between:
> >>>>>   - 2 USB hosts
> >>>>> or
> >>>>>   - 1 USB host and 1 USB device.
> >>>>>
> >>>>> This switching is system wide and has no reason to be done in
> >>>>> one specific USB controller. It can impact multiple devices and
> >>>>> PLL settings.
> >>>>>
> >>>>> The 'renesas,r9a06g032-sysctrl' node, as the system control
> >>>>> node of our system, is the best candidate to handle the property.
> >>>>
> >>>> Not necessarily. IIUC, you have:
> >>>>
> >>>> 1. sysctrl with some register(s) for choosing device mode
> >>>> 2. usb device or host at one address
> >>>> 3. usb host at separate address
> >>>>
> >>>
> >>> Just to clarify, usb device and host controller are not provided by
> >>> the same IP.
> >>> We have an USB host at some address range (PCI OHCI/EHCI USB host
> >>> below a PCI bridge) and the USB device at some other address range
> >>> (below a AHB to someting bridge).
> >>> And I am not sure that only USB host or devices are affected by this
> >>> property change.
> >>>
> >>>> If so then:
> >>>> A. Pretty often we have wrapper nodes for this purpose (USB, phy
> >>>> wrappers or glues) which are usually needed to configure something for a
> >>>> generic block (like Synopsys etc).
> >>>>
> >>>> B. Pretty often the device (so your USB host or device) needs to poke
> >>>> something in system controller registers, e.g. for power or some other
> >>>> setup.
> >>>
> >>> And we did it for some items (clocks and power).
> >>>
> >>>>
> >>>> Your case looks a lot like (B). We have many, many of such examples
> >>>> already. Actually it is exactly like that, except that it affects
> >>>> possibility of another device (e.g. choosing USB device blocks having
> >>>> host there).
> >>>>
> >>>> C. It looks a bit like a multi-serial-protocol interfaces (so
> >>>> UART+I2C+SPI). The difference is that such cases have all these nodes
> >>>> defined as a children of the protocol-wrapping device. Not here.
> >>>>
> >>>> I would propose to go with (B) unless of course it's causes some crazy
> >>>> architecture/code choices. Why? Because with exception of (C) we should
> >>>> not define properties which represent DT node choices. IOW, Choosing a
> >>>> node and compatible (e.g. usb controller as device) is enough to
> >>>> describe the hardware. No need for other properties to control some
> >>>> register in other block.
> >>>
> >>> The issue with h2mode is that it affects several devices and these
> >>> devices should not be in a "running" state when the h2mode is changed.
> >>
> >> Why the change should happen when device is running? And why this should
> >> be anyway different than your existing hsmode property - it also will
> >> happen when system and device are running.
> >>
> >>
> >>> PCI devices (host controllers) itself are not described in the DT. They
> >>> are automatically enumerated.
> >>
> >> Aren't we talking about USB controller in a MMIO-based SoC?
> >>
> >>> Changing the property in USB device controller can leads to hang on
> >>> other busses. Indeed, changing this property when a device affected
> >>> by the property is running can lead to a bus hang.>
> >>> In order to do that from the USB device controller I need to synchronize
> >>> the other devices to wait for this setting before running.
> >>> 1) probe sysctrl without setting h2mode
> >>> 2) probe some devices (USB host and probably others)
> >>>    Stop at some point and wait for the h2mode property setting.
> >>
> >> Why do you need to wait? Which device needs to wait? There are no such
> >> devices... if they are then please bring entire DTS, not some pieces in
> >> this patchset.
> >>
> >>> 3) probe usb device -> Set h2mode property
> >>> 4) allow devices waiting for the property setting to continue.
> >>
> >> I don't get why do you need such order. Your sysctrl also probes any
> >> time so old solution has exactly the same problem, doesn't it?
> >>
> >>> This synchronization seems pretty tricky and what to do if nobody
> >>> set the property (USB device controller not present or status="disabled"
> >>> for instance) ?
> >>>
> >>> Setting this property in sysctrl probe avoid the need for all of this
> >>> synchronization:
> >>> 1) probe sysctrl and set h2mode.
> >>> 2) probe other devices (no need to wait for the setting as it is already done)
> >>
> >> No, because other devices probe before sysctrl. If you bring here any
> >> manual ordering, you are doing it wrong.
> >>
> >>> The probing of the other devices (or the starting of they running state)
> >>> is guaranteed as they all need some clocks and so cannot start without
> >>> having the sysctrl node already probed.
> >>> This sysctrl node handles the clocks.
> >>
> >> Ah, so sysctrl is a clock controller for these?
> >>
> >> Then still there are no other devices depending on your USB. The USB is
> >> the owner of this property (specific bits in register), no one else.
> >
> > 1. There are two USB devices.
> > 2. The USB drivers can be modular, the sysctrl driver cannot, as it is
> >    the main clock controller.
>
> This does not change anything. Herve wrote:
>
> > probe some devices (USB host and probably others)
>
> Why some can be probed earlier and some not, if there are no
> dependencies? If there are dependencies, it's the same case with sysctrl
> touching the register bit and the USB controller touching it (as well
> via syscon, but that's obvious, I assume).
>
> Where is the synchronization problem?

The h2mode bit (and probably a few other controls we haven't figured out
yet) in the sysctrl must be set before any of the USB devices is active.
Hence it's safest for the sysctrl to do this before any of the USB drivers
probes.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-21 20:46                     ` Geert Uytterhoeven
@ 2022-11-22  7:45                       ` Krzysztof Kozlowski
  2022-11-22  8:25                         ` Geert Uytterhoeven
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22  7:45 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 21/11/2022 21:46, Geert Uytterhoeven wrote:
>> This does not change anything. Herve wrote:
>>
>>> probe some devices (USB host and probably others)
>>
>> Why some can be probed earlier and some not, if there are no
>> dependencies? If there are dependencies, it's the same case with sysctrl
>> touching the register bit and the USB controller touching it (as well
>> via syscon, but that's obvious, I assume).
>>
>> Where is the synchronization problem?
> 
> The h2mode bit (and probably a few other controls we haven't figured out
> yet) in the sysctrl must be set before any of the USB devices is active.
> Hence it's safest for the sysctrl to do this before any of the USB drivers
> probes.

Again, this does not differ from many, many of other devices. All of
them must set something in system controller block, before they start
operating (or at specific time). It's exactly the same everywhere.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  7:45                       ` Krzysztof Kozlowski
@ 2022-11-22  8:25                         ` Geert Uytterhoeven
  2022-11-22  8:42                           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-22  8:25 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 21/11/2022 21:46, Geert Uytterhoeven wrote:
> >> This does not change anything. Herve wrote:
> >>
> >>> probe some devices (USB host and probably others)
> >>
> >> Why some can be probed earlier and some not, if there are no
> >> dependencies? If there are dependencies, it's the same case with sysctrl
> >> touching the register bit and the USB controller touching it (as well
> >> via syscon, but that's obvious, I assume).
> >>
> >> Where is the synchronization problem?
> >
> > The h2mode bit (and probably a few other controls we haven't figured out
> > yet) in the sysctrl must be set before any of the USB devices is active.
> > Hence it's safest for the sysctrl to do this before any of the USB drivers
> > probes.
>
> Again, this does not differ from many, many of other devices. All of
> them must set something in system controller block, before they start
> operating (or at specific time). It's exactly the same everywhere.

The issue here is that there are two _different drivers_ (USB host
and device). When both are modular, and the driver that depends on the
sysctrl setting is loaded second, you have a problem: the sysctrl change
must not be done when the first driver is already using the hardware.

Hence the sysctrl driver should take care of it itself during early
initialization (it's the main clock controller, so it's a dependency
for all other I/O device drivers).

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  8:25                         ` Geert Uytterhoeven
@ 2022-11-22  8:42                           ` Krzysztof Kozlowski
  2022-11-22  9:01                             ` Geert Uytterhoeven
  2022-11-22  9:07                             ` Herve Codina
  0 siblings, 2 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22  8:42 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 22/11/2022 09:25, Geert Uytterhoeven wrote:
> Hi Krzysztof,
> 
> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:
>>>> This does not change anything. Herve wrote:
>>>>
>>>>> probe some devices (USB host and probably others)
>>>>
>>>> Why some can be probed earlier and some not, if there are no
>>>> dependencies? If there are dependencies, it's the same case with sysctrl
>>>> touching the register bit and the USB controller touching it (as well
>>>> via syscon, but that's obvious, I assume).
>>>>
>>>> Where is the synchronization problem?
>>>
>>> The h2mode bit (and probably a few other controls we haven't figured out
>>> yet) in the sysctrl must be set before any of the USB devices is active.
>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
>>> probes.
>>
>> Again, this does not differ from many, many of other devices. All of
>> them must set something in system controller block, before they start
>> operating (or at specific time). It's exactly the same everywhere.
> 
> The issue here is that there are two _different drivers_ (USB host
> and device). When both are modular, and the driver that depends on the
> sysctrl setting is loaded second, you have a problem: the sysctrl change
> must not be done when the first driver is already using the hardware.
> 
> Hence the sysctrl driver should take care of it itself during early
> initialization (it's the main clock controller, so it's a dependency
> for all other I/O device drivers).

I assumed you have there bit for the first device (which can switch
between USB host and USB device) to choose appropriate mode. The
bindings also expressed this - "the USBs are". Never said anything about
dependency between these USBs.

Are you saying that the mode for first device cannot be changed once the
second device (which is only host) is started? IOW, the mode setup must
happen before any of these devices are started?

Anyway with sysctrl approach you will have dependency and you cannot
rely on clock provider-consumer relationship to order that dependency.
What if you make all clocks on and do not take any clocks in USB device?
Broken dependency. What if you want to use this in a different SoC,
where the sysctrl does not provide clocks? Broken dependency.

You have here in such case parent-child dependency, not
provider-consumer. Just like for all serial-protocol engines (I2C/UART/SPI).

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  8:42                           ` Krzysztof Kozlowski
@ 2022-11-22  9:01                             ` Geert Uytterhoeven
  2022-11-22 10:23                               ` Krzysztof Kozlowski
  2022-11-22  9:07                             ` Herve Codina
  1 sibling, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-22  9:01 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, Nov 22, 2022 at 9:42 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 22/11/2022 09:25, Geert Uytterhoeven wrote:
> > On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:
> >> On 21/11/2022 21:46, Geert Uytterhoeven wrote:
> >>>> This does not change anything. Herve wrote:
> >>>>
> >>>>> probe some devices (USB host and probably others)
> >>>>
> >>>> Why some can be probed earlier and some not, if there are no
> >>>> dependencies? If there are dependencies, it's the same case with sysctrl
> >>>> touching the register bit and the USB controller touching it (as well
> >>>> via syscon, but that's obvious, I assume).
> >>>>
> >>>> Where is the synchronization problem?
> >>>
> >>> The h2mode bit (and probably a few other controls we haven't figured out
> >>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>> probes.
> >>
> >> Again, this does not differ from many, many of other devices. All of
> >> them must set something in system controller block, before they start
> >> operating (or at specific time). It's exactly the same everywhere.
> >
> > The issue here is that there are two _different drivers_ (USB host
> > and device). When both are modular, and the driver that depends on the
> > sysctrl setting is loaded second, you have a problem: the sysctrl change
> > must not be done when the first driver is already using the hardware.
> >
> > Hence the sysctrl driver should take care of it itself during early
> > initialization (it's the main clock controller, so it's a dependency
> > for all other I/O device drivers).
>
> I assumed you have there bit for the first device (which can switch
> between USB host and USB device) to choose appropriate mode. The
> bindings also expressed this - "the USBs are". Never said anything about
> dependency between these USBs.
>
> Are you saying that the mode for first device cannot be changed once the
> second device (which is only host) is started? IOW, the mode setup must
> happen before any of these devices are started?

Exactly.

> Anyway with sysctrl approach you will have dependency and you cannot
> rely on clock provider-consumer relationship to order that dependency.
> What if you make all clocks on and do not take any clocks in USB device?

Enabling the clocks does not have anything to do with this ordering.
Clock consumers that are part of the clock domain are probed after
clock providers.  If the clock is missing, that would be an incorrect
description in DTS.

> Broken dependency. What if you want to use this in a different SoC,
> where the sysctrl does not provide clocks? Broken dependency.

This is the "renesas,r9a06g032-sysctrl" DT bindings document.
It talks about this SoC implementation specifically.
This is not a random synthesizable IP Core that can appear anywhere.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  8:42                           ` Krzysztof Kozlowski
  2022-11-22  9:01                             ` Geert Uytterhoeven
@ 2022-11-22  9:07                             ` Herve Codina
  2022-11-22 10:30                               ` Krzysztof Kozlowski
  1 sibling, 1 reply; 47+ messages in thread
From: Herve Codina @ 2022-11-22  9:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On Tue, 22 Nov 2022 09:42:48 +0100
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:

> On 22/11/2022 09:25, Geert Uytterhoeven wrote:
> > Hi Krzysztof,
> > 
> > On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:  
> >> On 21/11/2022 21:46, Geert Uytterhoeven wrote:  
> >>>> This does not change anything. Herve wrote:
> >>>>  
> >>>>> probe some devices (USB host and probably others)  
> >>>>
> >>>> Why some can be probed earlier and some not, if there are no
> >>>> dependencies? If there are dependencies, it's the same case with sysctrl
> >>>> touching the register bit and the USB controller touching it (as well
> >>>> via syscon, but that's obvious, I assume).
> >>>>
> >>>> Where is the synchronization problem?  
> >>>
> >>> The h2mode bit (and probably a few other controls we haven't figured out
> >>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>> probes.  
> >>
> >> Again, this does not differ from many, many of other devices. All of
> >> them must set something in system controller block, before they start
> >> operating (or at specific time). It's exactly the same everywhere.  
> > 
> > The issue here is that there are two _different drivers_ (USB host
> > and device). When both are modular, and the driver that depends on the
> > sysctrl setting is loaded second, you have a problem: the sysctrl change
> > must not be done when the first driver is already using the hardware.
> > 
> > Hence the sysctrl driver should take care of it itself during early
> > initialization (it's the main clock controller, so it's a dependency
> > for all other I/O device drivers).  
> 
> I assumed you have there bit for the first device (which can switch
> between USB host and USB device) to choose appropriate mode. The
> bindings also expressed this - "the USBs are". Never said anything about
> dependency between these USBs.
> 
> Are you saying that the mode for first device cannot be changed once the
> second device (which is only host) is started? IOW, the mode setup must
> happen before any of these devices are started?
> 
> Anyway with sysctrl approach you will have dependency and you cannot
> rely on clock provider-consumer relationship to order that dependency.
> What if you make all clocks on and do not take any clocks in USB device?
> Broken dependency. What if you want to use this in a different SoC,
> where the sysctrl does not provide clocks? Broken dependency.

The issue is really related to the Renesas sysctrl itself and not related
to the USB drivers themselves.
From the drivers themselves, the issue is not seen (I mean the driver
takes no specific action related to this issue).
If we change the SOC, the issue will probably not exist anymore.

> 
> You have here in such case parent-child dependency, not
> provider-consumer. Just like for all serial-protocol engines (I2C/UART/SPI).
> 
> Best regards,
> Krzysztof
> 



-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  9:01                             ` Geert Uytterhoeven
@ 2022-11-22 10:23                               ` Krzysztof Kozlowski
  2022-11-22 10:26                                 ` Geert Uytterhoeven
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22 10:23 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 22/11/2022 10:01, Geert Uytterhoeven wrote:
>>>>> The h2mode bit (and probably a few other controls we haven't figured out
>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
>>>>> probes.
>>>>
>>>> Again, this does not differ from many, many of other devices. All of
>>>> them must set something in system controller block, before they start
>>>> operating (or at specific time). It's exactly the same everywhere.
>>>
>>> The issue here is that there are two _different drivers_ (USB host
>>> and device). When both are modular, and the driver that depends on the
>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
>>> must not be done when the first driver is already using the hardware.
>>>
>>> Hence the sysctrl driver should take care of it itself during early
>>> initialization (it's the main clock controller, so it's a dependency
>>> for all other I/O device drivers).
>>
>> I assumed you have there bit for the first device (which can switch
>> between USB host and USB device) to choose appropriate mode. The
>> bindings also expressed this - "the USBs are". Never said anything about
>> dependency between these USBs.
>>
>> Are you saying that the mode for first device cannot be changed once the
>> second device (which is only host) is started? IOW, the mode setup must
>> happen before any of these devices are started?
> 
> Exactly.
> 
>> Anyway with sysctrl approach you will have dependency and you cannot
>> rely on clock provider-consumer relationship to order that dependency.
>> What if you make all clocks on and do not take any clocks in USB device?
> 
> Enabling the clocks does not have anything to do with this ordering.

That was the argument from Herve, that ordering is guaranteed by clocks.

> Clock consumers that are part of the clock domain are probed after
> clock providers.  If the clock is missing, that would be an incorrect
> description in DTS.

If not clocks, what else is guaranteeing the ordering? You did not
express it in DT.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22 10:23                               ` Krzysztof Kozlowski
@ 2022-11-22 10:26                                 ` Geert Uytterhoeven
  2022-11-22 10:34                                   ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-22 10:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, Nov 22, 2022 at 11:23 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 22/11/2022 10:01, Geert Uytterhoeven wrote:
> >>>>> The h2mode bit (and probably a few other controls we haven't figured out
> >>>>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>>>> probes.
> >>>>
> >>>> Again, this does not differ from many, many of other devices. All of
> >>>> them must set something in system controller block, before they start
> >>>> operating (or at specific time). It's exactly the same everywhere.
> >>>
> >>> The issue here is that there are two _different drivers_ (USB host
> >>> and device). When both are modular, and the driver that depends on the
> >>> sysctrl setting is loaded second, you have a problem: the sysctrl change
> >>> must not be done when the first driver is already using the hardware.
> >>>
> >>> Hence the sysctrl driver should take care of it itself during early
> >>> initialization (it's the main clock controller, so it's a dependency
> >>> for all other I/O device drivers).
> >>
> >> I assumed you have there bit for the first device (which can switch
> >> between USB host and USB device) to choose appropriate mode. The
> >> bindings also expressed this - "the USBs are". Never said anything about
> >> dependency between these USBs.
> >>
> >> Are you saying that the mode for first device cannot be changed once the
> >> second device (which is only host) is started? IOW, the mode setup must
> >> happen before any of these devices are started?
> >
> > Exactly.
> >
> >> Anyway with sysctrl approach you will have dependency and you cannot
> >> rely on clock provider-consumer relationship to order that dependency.
> >> What if you make all clocks on and do not take any clocks in USB device?
> >
> > Enabling the clocks does not have anything to do with this ordering.
>
> That was the argument from Herve, that ordering is guaranteed by clocks.
>
> > Clock consumers that are part of the clock domain are probed after
> > clock providers.  If the clock is missing, that would be an incorrect
> > description in DTS.
>
> If not clocks, what else is guaranteeing the ordering? You did not
> express it in DT.

clocks and power-domains

And if not clocks and power-domains... Oops, we didn't express in DT
that the SoC needs to be powered at all ;-)

Can we please stop this pointless discussion?
Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22  9:07                             ` Herve Codina
@ 2022-11-22 10:30                               ` Krzysztof Kozlowski
  2022-11-22 10:47                                 ` Geert Uytterhoeven
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22 10:30 UTC (permalink / raw)
  To: Herve Codina
  Cc: Geert Uytterhoeven, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 22/11/2022 10:07, Herve Codina wrote:
> On Tue, 22 Nov 2022 09:42:48 +0100
> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> 
>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:
>>> Hi Krzysztof,
>>>
>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
>>> <krzysztof.kozlowski@linaro.org> wrote:  
>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:  
>>>>>> This does not change anything. Herve wrote:
>>>>>>  
>>>>>>> probe some devices (USB host and probably others)  
>>>>>>
>>>>>> Why some can be probed earlier and some not, if there are no
>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
>>>>>> touching the register bit and the USB controller touching it (as well
>>>>>> via syscon, but that's obvious, I assume).
>>>>>>
>>>>>> Where is the synchronization problem?  
>>>>>
>>>>> The h2mode bit (and probably a few other controls we haven't figured out
>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
>>>>> probes.  
>>>>
>>>> Again, this does not differ from many, many of other devices. All of
>>>> them must set something in system controller block, before they start
>>>> operating (or at specific time). It's exactly the same everywhere.  
>>>
>>> The issue here is that there are two _different drivers_ (USB host
>>> and device). When both are modular, and the driver that depends on the
>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
>>> must not be done when the first driver is already using the hardware.
>>>
>>> Hence the sysctrl driver should take care of it itself during early
>>> initialization (it's the main clock controller, so it's a dependency
>>> for all other I/O device drivers).  
>>
>> I assumed you have there bit for the first device (which can switch
>> between USB host and USB device) to choose appropriate mode. The
>> bindings also expressed this - "the USBs are". Never said anything about
>> dependency between these USBs.
>>
>> Are you saying that the mode for first device cannot be changed once the
>> second device (which is only host) is started? IOW, the mode setup must
>> happen before any of these devices are started?
>>
>> Anyway with sysctrl approach you will have dependency and you cannot
>> rely on clock provider-consumer relationship to order that dependency.
>> What if you make all clocks on and do not take any clocks in USB device?
>> Broken dependency. What if you want to use this in a different SoC,
>> where the sysctrl does not provide clocks? Broken dependency.
> 
> The issue is really related to the Renesas sysctrl itself and not related
> to the USB drivers themselves.
> From the drivers themselves, the issue is not seen (I mean the driver
> takes no specific action related to this issue).
> If we change the SOC, the issue will probably not exist anymore.
>

Yeah, and in the next SoC you will bring 10 of such properties to
sysctrl arguing that if one was approved, 10 is also fine. Somehow
people on the lists like to use that argument - I saw it somewhere, so I
am allowed to do here the same.

I understand that the registers responsible for configuration are in
sysctrl block, but it does not mean that it should be described as part
of sysctrl Devicetree node. If there was no synchronization problem,
this would be regular example of register in syscon which is handled
(toggled) by the device (so USB device/host controller). Since there is
synchronization problem, you argue that it is correct representation of
hardware. No, it is not, because logically in DT you do not describe
mode or existence of other devices in some other node and it still does
not describe this ordering.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22 10:26                                 ` Geert Uytterhoeven
@ 2022-11-22 10:34                                   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-22 10:34 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 22/11/2022 11:26, Geert Uytterhoeven wrote:
>>
>> If not clocks, what else is guaranteeing the ordering? You did not
>> express it in DT.
> 
> clocks and power-domains
> 
> And if not clocks and power-domains... Oops, we didn't express in DT
> that the SoC needs to be powered at all ;-)

The SoC is a parent of that device, so you have an expressed dependency...

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22 10:30                               ` Krzysztof Kozlowski
@ 2022-11-22 10:47                                 ` Geert Uytterhoeven
  2022-11-23  9:39                                   ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Geert Uytterhoeven @ 2022-11-22 10:47 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

Hi Krzysztof,

On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> On 22/11/2022 10:07, Herve Codina wrote:
> > On Tue, 22 Nov 2022 09:42:48 +0100
> > Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >
> >> On 22/11/2022 09:25, Geert Uytterhoeven wrote:
> >>> Hi Krzysztof,
> >>>
> >>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> >>> <krzysztof.kozlowski@linaro.org> wrote:
> >>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:
> >>>>>> This does not change anything. Herve wrote:
> >>>>>>
> >>>>>>> probe some devices (USB host and probably others)
> >>>>>>
> >>>>>> Why some can be probed earlier and some not, if there are no
> >>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
> >>>>>> touching the register bit and the USB controller touching it (as well
> >>>>>> via syscon, but that's obvious, I assume).
> >>>>>>
> >>>>>> Where is the synchronization problem?
> >>>>>
> >>>>> The h2mode bit (and probably a few other controls we haven't figured out
> >>>>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>>>> probes.
> >>>>
> >>>> Again, this does not differ from many, many of other devices. All of
> >>>> them must set something in system controller block, before they start
> >>>> operating (or at specific time). It's exactly the same everywhere.
> >>>
> >>> The issue here is that there are two _different drivers_ (USB host
> >>> and device). When both are modular, and the driver that depends on the
> >>> sysctrl setting is loaded second, you have a problem: the sysctrl change
> >>> must not be done when the first driver is already using the hardware.
> >>>
> >>> Hence the sysctrl driver should take care of it itself during early
> >>> initialization (it's the main clock controller, so it's a dependency
> >>> for all other I/O device drivers).
> >>
> >> I assumed you have there bit for the first device (which can switch
> >> between USB host and USB device) to choose appropriate mode. The
> >> bindings also expressed this - "the USBs are". Never said anything about
> >> dependency between these USBs.
> >>
> >> Are you saying that the mode for first device cannot be changed once the
> >> second device (which is only host) is started? IOW, the mode setup must
> >> happen before any of these devices are started?
> >>
> >> Anyway with sysctrl approach you will have dependency and you cannot
> >> rely on clock provider-consumer relationship to order that dependency.
> >> What if you make all clocks on and do not take any clocks in USB device?
> >> Broken dependency. What if you want to use this in a different SoC,
> >> where the sysctrl does not provide clocks? Broken dependency.
> >
> > The issue is really related to the Renesas sysctrl itself and not related
> > to the USB drivers themselves.
> > From the drivers themselves, the issue is not seen (I mean the driver
> > takes no specific action related to this issue).
> > If we change the SOC, the issue will probably not exist anymore.
>
> Yeah, and in the next SoC you will bring 10 of such properties to
> sysctrl arguing that if one was approved, 10 is also fine. Somehow
> people on the lists like to use that argument - I saw it somewhere, so I
> am allowed to do here the same.

Like pin control properties? ;-)
This property represents a wiring on the board...
I.e. a system integration issue.

> I understand that the registers responsible for configuration are in
> sysctrl block, but it does not mean that it should be described as part
> of sysctrl Devicetree node. If there was no synchronization problem,
> this would be regular example of register in syscon which is handled
> (toggled) by the device (so USB device/host controller). Since there is
> synchronization problem, you argue that it is correct representation of
> hardware. No, it is not, because logically in DT you do not describe
> mode or existence of other devices in some other node and it still does
> not describe this ordering.

So we have to drop the property, and let the sysctrl block look
for <name>@<reg> nodes, and check which ones are enabled?

Running out of ideas...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-22 10:47                                 ` Geert Uytterhoeven
@ 2022-11-23  9:39                                   ` Krzysztof Kozlowski
  2022-11-24  9:36                                     ` Miquel Raynal
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-23  9:39 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Herve Codina, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Greg Kroah-Hartman, Magnus Damm,
	Gareth Williams, linux-renesas-soc, linux-clk, devicetree,
	linux-kernel, linux-usb, Thomas Petazzoni, Miquel Raynal

On 22/11/2022 11:47, Geert Uytterhoeven wrote:
> Hi Krzysztof,
> 
> On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>> On 22/11/2022 10:07, Herve Codina wrote:
>>> On Tue, 22 Nov 2022 09:42:48 +0100
>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>>
>>>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:
>>>>> Hi Krzysztof,
>>>>>
>>>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
>>>>> <krzysztof.kozlowski@linaro.org> wrote:
>>>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:
>>>>>>>> This does not change anything. Herve wrote:
>>>>>>>>
>>>>>>>>> probe some devices (USB host and probably others)
>>>>>>>>
>>>>>>>> Why some can be probed earlier and some not, if there are no
>>>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
>>>>>>>> touching the register bit and the USB controller touching it (as well
>>>>>>>> via syscon, but that's obvious, I assume).
>>>>>>>>
>>>>>>>> Where is the synchronization problem?
>>>>>>>
>>>>>>> The h2mode bit (and probably a few other controls we haven't figured out
>>>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
>>>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
>>>>>>> probes.
>>>>>>
>>>>>> Again, this does not differ from many, many of other devices. All of
>>>>>> them must set something in system controller block, before they start
>>>>>> operating (or at specific time). It's exactly the same everywhere.
>>>>>
>>>>> The issue here is that there are two _different drivers_ (USB host
>>>>> and device). When both are modular, and the driver that depends on the
>>>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
>>>>> must not be done when the first driver is already using the hardware.
>>>>>
>>>>> Hence the sysctrl driver should take care of it itself during early
>>>>> initialization (it's the main clock controller, so it's a dependency
>>>>> for all other I/O device drivers).
>>>>
>>>> I assumed you have there bit for the first device (which can switch
>>>> between USB host and USB device) to choose appropriate mode. The
>>>> bindings also expressed this - "the USBs are". Never said anything about
>>>> dependency between these USBs.
>>>>
>>>> Are you saying that the mode for first device cannot be changed once the
>>>> second device (which is only host) is started? IOW, the mode setup must
>>>> happen before any of these devices are started?
>>>>
>>>> Anyway with sysctrl approach you will have dependency and you cannot
>>>> rely on clock provider-consumer relationship to order that dependency.
>>>> What if you make all clocks on and do not take any clocks in USB device?
>>>> Broken dependency. What if you want to use this in a different SoC,
>>>> where the sysctrl does not provide clocks? Broken dependency.
>>>
>>> The issue is really related to the Renesas sysctrl itself and not related
>>> to the USB drivers themselves.
>>> From the drivers themselves, the issue is not seen (I mean the driver
>>> takes no specific action related to this issue).
>>> If we change the SOC, the issue will probably not exist anymore.
>>
>> Yeah, and in the next SoC you will bring 10 of such properties to
>> sysctrl arguing that if one was approved, 10 is also fine. Somehow
>> people on the lists like to use that argument - I saw it somewhere, so I
>> am allowed to do here the same.
> 
> Like pin control properties? ;-)
> This property represents a wiring on the board...
> I.e. a system integration issue.
> 
>> I understand that the registers responsible for configuration are in
>> sysctrl block, but it does not mean that it should be described as part
>> of sysctrl Devicetree node. If there was no synchronization problem,
>> this would be regular example of register in syscon which is handled
>> (toggled) by the device (so USB device/host controller). Since there is
>> synchronization problem, you argue that it is correct representation of
>> hardware. No, it is not, because logically in DT you do not describe
>> mode or existence of other devices in some other node and it still does
>> not describe this ordering.
> 
> So we have to drop the property, and let the sysctrl block look
> for <name>@<reg> nodes, and check which ones are enabled?
> 
> Running out of ideas...

One solution could be making USB nodes children of the sysctrl block which:
1. Gives proper ordering (children cannot start before parent)
regardless of any other shared resources,
2. Allows to drop this mode property and instead check what type of
children you have and configure mode depending on them.

However this also might not be correct representation of hardware
(dunno...), so I am also running out of ideas.

Anyway, I appreciate your explanations. I don't oppose this and I defer
the decision to Rob (for this or for v3 patch with descriptive strings).

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-23  9:39                                   ` Krzysztof Kozlowski
@ 2022-11-24  9:36                                     ` Miquel Raynal
  2022-11-24  9:46                                       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 47+ messages in thread
From: Miquel Raynal @ 2022-11-24  9:36 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Herve Codina, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni

Hi Krzysztof,

krzysztof.kozlowski@linaro.org wrote on Wed, 23 Nov 2022 10:39:41 +0100:

> On 22/11/2022 11:47, Geert Uytterhoeven wrote:
> > Hi Krzysztof,
> > 
> > On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:  
> >> On 22/11/2022 10:07, Herve Codina wrote:  
> >>> On Tue, 22 Nov 2022 09:42:48 +0100
> >>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >>>  
> >>>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:  
> >>>>> Hi Krzysztof,
> >>>>>
> >>>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> >>>>> <krzysztof.kozlowski@linaro.org> wrote:  
> >>>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:  
> >>>>>>>> This does not change anything. Herve wrote:
> >>>>>>>>  
> >>>>>>>>> probe some devices (USB host and probably others)  
> >>>>>>>>
> >>>>>>>> Why some can be probed earlier and some not, if there are no
> >>>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
> >>>>>>>> touching the register bit and the USB controller touching it (as well
> >>>>>>>> via syscon, but that's obvious, I assume).
> >>>>>>>>
> >>>>>>>> Where is the synchronization problem?  
> >>>>>>>
> >>>>>>> The h2mode bit (and probably a few other controls we haven't figured out
> >>>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>>>>>> probes.  
> >>>>>>
> >>>>>> Again, this does not differ from many, many of other devices. All of
> >>>>>> them must set something in system controller block, before they start
> >>>>>> operating (or at specific time). It's exactly the same everywhere.  
> >>>>>
> >>>>> The issue here is that there are two _different drivers_ (USB host
> >>>>> and device). When both are modular, and the driver that depends on the
> >>>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
> >>>>> must not be done when the first driver is already using the hardware.
> >>>>>
> >>>>> Hence the sysctrl driver should take care of it itself during early
> >>>>> initialization (it's the main clock controller, so it's a dependency
> >>>>> for all other I/O device drivers).  
> >>>>
> >>>> I assumed you have there bit for the first device (which can switch
> >>>> between USB host and USB device) to choose appropriate mode. The
> >>>> bindings also expressed this - "the USBs are". Never said anything about
> >>>> dependency between these USBs.
> >>>>
> >>>> Are you saying that the mode for first device cannot be changed once the
> >>>> second device (which is only host) is started? IOW, the mode setup must
> >>>> happen before any of these devices are started?
> >>>>
> >>>> Anyway with sysctrl approach you will have dependency and you cannot
> >>>> rely on clock provider-consumer relationship to order that dependency.
> >>>> What if you make all clocks on and do not take any clocks in USB device?
> >>>> Broken dependency. What if you want to use this in a different SoC,
> >>>> where the sysctrl does not provide clocks? Broken dependency.  
> >>>
> >>> The issue is really related to the Renesas sysctrl itself and not related
> >>> to the USB drivers themselves.
> >>> From the drivers themselves, the issue is not seen (I mean the driver
> >>> takes no specific action related to this issue).
> >>> If we change the SOC, the issue will probably not exist anymore.  
> >>
> >> Yeah, and in the next SoC you will bring 10 of such properties to
> >> sysctrl arguing that if one was approved, 10 is also fine. Somehow
> >> people on the lists like to use that argument - I saw it somewhere, so I
> >> am allowed to do here the same.  
> > 
> > Like pin control properties? ;-)
> > This property represents a wiring on the board...
> > I.e. a system integration issue.
> >   
> >> I understand that the registers responsible for configuration are in
> >> sysctrl block, but it does not mean that it should be described as part
> >> of sysctrl Devicetree node. If there was no synchronization problem,
> >> this would be regular example of register in syscon which is handled
> >> (toggled) by the device (so USB device/host controller). Since there is
> >> synchronization problem, you argue that it is correct representation of
> >> hardware. No, it is not, because logically in DT you do not describe
> >> mode or existence of other devices in some other node and it still does
> >> not describe this ordering.  
> > 
> > So we have to drop the property, and let the sysctrl block look
> > for <name>@<reg> nodes, and check which ones are enabled?
> > 
> > Running out of ideas...  

I'm stepping in, hopefully I won't just be bikeshedding on something
that has already been discussed but here is my grain of salt.

> One solution could be making USB nodes children of the sysctrl block which:
> 1. Gives proper ordering (children cannot start before parent)
> regardless of any other shared resources,
> 2. Allows to drop this mode property and instead check what type of
> children you have and configure mode depending on them.
> 
> However this also might not be correct representation of hardware
> (dunno...), so I am also running out of ideas.

I see what you mean here, but AFAICS that is clearly a wrong
representation of the hardware. Sorting nodes by bus seems the aim of
device tree because there is a physical relationship, that's why we
have (i2c as an example):

	ahb {
		foo-controller@xxx {
			reg = <xxx>;
		};
	};

But what you are describing now is conceptually closer to:

	clk-controller {
		foo-controller {
			reg = ?
		};
	};

Not mentioning that this only works once, because foo-controller might
also need other blocks to be ready before probing and those might
be different blocks (they are the same in the rzn1 case, but
more generally, they are not). So in the end I am not in favor of this
solution.

If we compare the dependency between the USB device controller and the
sysctrl block which contains the h2mode register to existing
dependencies, they are all treated with properties. These properties,
eg:

	foo-controller {
		clocks = <&provider [index]>;
	};

were initially used to just tell the consumer which resource it should
grab/enable. If the device was not yet ready, we would rely on the
probe deferral mechanism to try again later. Not optimal, but not
bad either as it made things work. Since v5.11 and the addition of
automatic device links, the probe order is explicitly ordered.
<provider> could always get probed before <foo-controller>. So, isn't
what we need here? What about the following:

	sysctrl {
		h2mode = "something";
	};

	usb-device {
		h2mode-provider = <&sysctrl>;
	};

We can initially just make this work with some additional logic on both
sides. The USB device controller would manually check whether sysctrl
has been probed or not (in practice, because of the clocks and power
domains being described this will always be a yes, but IIUC we want to
avoid relying on it) and otherwise, defer its probe. On the sysctrl side
it is just a matter of checking (like we already do):

	if (!sysctrl_priv)
		return -EPROBE_DEFER;

To be honest I would love to see the device link mechanism extended to
"custom" phandle properties like that, it would avoid the burden of
checking for deferrals manually, aside with boot time improvements. If
we go this way, we shall decide whether we want to:
* extend the list of properties that will lead to a dependency creation [1]
* or maybe settle on a common suffix that could always be used,
  especially for specific cases like this one where there is an
  explicit provider-consumer dependency that must be fulfilled:

	DEFINE_SUFFIX_PROP(provider, "-provider", "#provider-cells")

* or perhaps extend struct of_device_id to contain the name of the
  properties pointing to phandles that describe probe dependencies with:

	char *provider_prop_name;
	char *provider_cells_prop_name;

  and use them from of/property.c to generate the links when relevant.

[1] https://elixir.bootlin.com/linux/v6.0/source/drivers/of/property.c#L1298


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-24  9:36                                     ` Miquel Raynal
@ 2022-11-24  9:46                                       ` Krzysztof Kozlowski
  2022-11-24 10:27                                         ` Miquel Raynal
  0 siblings, 1 reply; 47+ messages in thread
From: Krzysztof Kozlowski @ 2022-11-24  9:46 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Geert Uytterhoeven, Herve Codina, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni

On 24/11/2022 10:36, Miquel Raynal wrote:
> Hi Krzysztof,
> 
> krzysztof.kozlowski@linaro.org wrote on Wed, 23 Nov 2022 10:39:41 +0100:
> 
>> On 22/11/2022 11:47, Geert Uytterhoeven wrote:
>>> Hi Krzysztof,
>>>
>>> On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
>>> <krzysztof.kozlowski@linaro.org> wrote:  
>>>> On 22/11/2022 10:07, Herve Codina wrote:  
>>>>> On Tue, 22 Nov 2022 09:42:48 +0100
>>>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
>>>>>  
>>>>>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:  
>>>>>>> Hi Krzysztof,
>>>>>>>
>>>>>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
>>>>>>> <krzysztof.kozlowski@linaro.org> wrote:  
>>>>>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:  
>>>>>>>>>> This does not change anything. Herve wrote:
>>>>>>>>>>  
>>>>>>>>>>> probe some devices (USB host and probably others)  
>>>>>>>>>>
>>>>>>>>>> Why some can be probed earlier and some not, if there are no
>>>>>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
>>>>>>>>>> touching the register bit and the USB controller touching it (as well
>>>>>>>>>> via syscon, but that's obvious, I assume).
>>>>>>>>>>
>>>>>>>>>> Where is the synchronization problem?  
>>>>>>>>>
>>>>>>>>> The h2mode bit (and probably a few other controls we haven't figured out
>>>>>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
>>>>>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
>>>>>>>>> probes.  
>>>>>>>>
>>>>>>>> Again, this does not differ from many, many of other devices. All of
>>>>>>>> them must set something in system controller block, before they start
>>>>>>>> operating (or at specific time). It's exactly the same everywhere.  
>>>>>>>
>>>>>>> The issue here is that there are two _different drivers_ (USB host
>>>>>>> and device). When both are modular, and the driver that depends on the
>>>>>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
>>>>>>> must not be done when the first driver is already using the hardware.
>>>>>>>
>>>>>>> Hence the sysctrl driver should take care of it itself during early
>>>>>>> initialization (it's the main clock controller, so it's a dependency
>>>>>>> for all other I/O device drivers).  
>>>>>>
>>>>>> I assumed you have there bit for the first device (which can switch
>>>>>> between USB host and USB device) to choose appropriate mode. The
>>>>>> bindings also expressed this - "the USBs are". Never said anything about
>>>>>> dependency between these USBs.
>>>>>>
>>>>>> Are you saying that the mode for first device cannot be changed once the
>>>>>> second device (which is only host) is started? IOW, the mode setup must
>>>>>> happen before any of these devices are started?
>>>>>>
>>>>>> Anyway with sysctrl approach you will have dependency and you cannot
>>>>>> rely on clock provider-consumer relationship to order that dependency.
>>>>>> What if you make all clocks on and do not take any clocks in USB device?
>>>>>> Broken dependency. What if you want to use this in a different SoC,
>>>>>> where the sysctrl does not provide clocks? Broken dependency.  
>>>>>
>>>>> The issue is really related to the Renesas sysctrl itself and not related
>>>>> to the USB drivers themselves.
>>>>> From the drivers themselves, the issue is not seen (I mean the driver
>>>>> takes no specific action related to this issue).
>>>>> If we change the SOC, the issue will probably not exist anymore.  
>>>>
>>>> Yeah, and in the next SoC you will bring 10 of such properties to
>>>> sysctrl arguing that if one was approved, 10 is also fine. Somehow
>>>> people on the lists like to use that argument - I saw it somewhere, so I
>>>> am allowed to do here the same.  
>>>
>>> Like pin control properties? ;-)
>>> This property represents a wiring on the board...
>>> I.e. a system integration issue.
>>>   
>>>> I understand that the registers responsible for configuration are in
>>>> sysctrl block, but it does not mean that it should be described as part
>>>> of sysctrl Devicetree node. If there was no synchronization problem,
>>>> this would be regular example of register in syscon which is handled
>>>> (toggled) by the device (so USB device/host controller). Since there is
>>>> synchronization problem, you argue that it is correct representation of
>>>> hardware. No, it is not, because logically in DT you do not describe
>>>> mode or existence of other devices in some other node and it still does
>>>> not describe this ordering.  
>>>
>>> So we have to drop the property, and let the sysctrl block look
>>> for <name>@<reg> nodes, and check which ones are enabled?
>>>
>>> Running out of ideas...  
> 
> I'm stepping in, hopefully I won't just be bikeshedding on something
> that has already been discussed but here is my grain of salt.
> 
>> One solution could be making USB nodes children of the sysctrl block which:
>> 1. Gives proper ordering (children cannot start before parent)
>> regardless of any other shared resources,
>> 2. Allows to drop this mode property and instead check what type of
>> children you have and configure mode depending on them.
>>
>> However this also might not be correct representation of hardware
>> (dunno...), so I am also running out of ideas.
> 
> I see what you mean here, but AFAICS that is clearly a wrong
> representation of the hardware. Sorting nodes by bus seems the aim of
> device tree because there is a physical relationship, that's why we
> have (i2c as an example):
> 
> 	ahb {
> 		foo-controller@xxx {
> 			reg = <xxx>;
> 		};
> 	};
> 
> But what you are describing now is conceptually closer to:
> 
> 	clk-controller {
> 		foo-controller {
> 			reg = ?
> 		};
> 	};

Which is not a problem. reg can be anything - offset from sysctrl node
or absolute offset. We have it in many places already. What's the issue
here?

> 
> Not mentioning that this only works once, because foo-controller might
> also need other blocks to be ready before probing and those might
> be different blocks (they are the same in the rzn1 case, but
> more generally, they are not).

But what is the problem of needing other blocks? All devices need
something and we solve it...

> So in the end I am not in favor of this
> solution.
> 
> If we compare the dependency between the USB device controller and the
> sysctrl block which contains the h2mode register to existing
> dependencies, they are all treated with properties. These properties,
> eg:
> 
> 	foo-controller {
> 		clocks = <&provider [index]>;
> 	};
> 
> were initially used to just tell the consumer which resource it should
> grab/enable. If the device was not yet ready, we would rely on the
> probe deferral mechanism to try again later. Not optimal, but not
> bad either as it made things work. Since v5.11 and the addition of
> automatic device links, the probe order is explicitly ordered.
> <provider> could always get probed before <foo-controller>. So, isn't
> what we need here? What about the following:
> 
> 	sysctrl {
> 		h2mode = "something";
> 	};
> 
> 	usb-device {
> 		h2mode-provider = <&sysctrl>;
> 	};

No, because next time one will add 10 of such properties:
sysctrl {
	h2mode = ""
	g2mode = ""
	i2mode = ""
	....
}

and keep arguing that because these registers are in sysctrl, so they
should have their own property in sysctrl mode.

That's not correct representation of hardware.
> 
> We can initially just make this work with some additional logic on both
> sides. The USB device controller would manually check whether sysctrl
> has been probed or not (in practice, because of the clocks and power
> domains being described this will always be a yes, but IIUC we want to
> avoid relying on it) and otherwise, defer its probe. On the sysctrl side
> it is just a matter of checking (like we already do):
> 
> 	if (!sysctrl_priv)
> 		return -EPROBE_DEFER;
> 
> To be honest I would love to see the device link mechanism extended to
> "custom" phandle properties like that, it would avoid the burden of
> checking for deferrals manually, aside with boot time improvements. If
> we go this way, we shall decide whether we want to:
> * extend the list of properties that will lead to a dependency creation [1]
> * or maybe settle on a common suffix that could always be used,
>   especially for specific cases like this one where there is an
>   explicit provider-consumer dependency that must be fulfilled:
> 
> 	DEFINE_SUFFIX_PROP(provider, "-provider", "#provider-cells")
> 
> * or perhaps extend struct of_device_id to contain the name of the
>   properties pointing to phandles that describe probe dependencies with:
> 
> 	char *provider_prop_name;
> 	char *provider_cells_prop_name;
> 
>   and use them from of/property.c to generate the links when relevant.
> 
> [1] https://elixir.bootlin.com/linux/v6.0/source/drivers/of/property.c#L1298
> 
> 
> Thanks,
> Miquèl

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-24  9:46                                       ` Krzysztof Kozlowski
@ 2022-11-24 10:27                                         ` Miquel Raynal
  2022-11-24 10:44                                           ` Miquel Raynal
  0 siblings, 1 reply; 47+ messages in thread
From: Miquel Raynal @ 2022-11-24 10:27 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Herve Codina, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni

Hi Krzysztof,

krzysztof.kozlowski@linaro.org wrote on Thu, 24 Nov 2022 10:46:14 +0100:

> On 24/11/2022 10:36, Miquel Raynal wrote:
> > Hi Krzysztof,
> > 
> > krzysztof.kozlowski@linaro.org wrote on Wed, 23 Nov 2022 10:39:41 +0100:
> >   
> >> On 22/11/2022 11:47, Geert Uytterhoeven wrote:  
> >>> Hi Krzysztof,
> >>>
> >>> On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
> >>> <krzysztof.kozlowski@linaro.org> wrote:    
> >>>> On 22/11/2022 10:07, Herve Codina wrote:    
> >>>>> On Tue, 22 Nov 2022 09:42:48 +0100
> >>>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> >>>>>    
> >>>>>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:    
> >>>>>>> Hi Krzysztof,
> >>>>>>>
> >>>>>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> >>>>>>> <krzysztof.kozlowski@linaro.org> wrote:    
> >>>>>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:    
> >>>>>>>>>> This does not change anything. Herve wrote:
> >>>>>>>>>>    
> >>>>>>>>>>> probe some devices (USB host and probably others)    
> >>>>>>>>>>
> >>>>>>>>>> Why some can be probed earlier and some not, if there are no
> >>>>>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
> >>>>>>>>>> touching the register bit and the USB controller touching it (as well
> >>>>>>>>>> via syscon, but that's obvious, I assume).
> >>>>>>>>>>
> >>>>>>>>>> Where is the synchronization problem?    
> >>>>>>>>>
> >>>>>>>>> The h2mode bit (and probably a few other controls we haven't figured out
> >>>>>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
> >>>>>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> >>>>>>>>> probes.    
> >>>>>>>>
> >>>>>>>> Again, this does not differ from many, many of other devices. All of
> >>>>>>>> them must set something in system controller block, before they start
> >>>>>>>> operating (or at specific time). It's exactly the same everywhere.    
> >>>>>>>
> >>>>>>> The issue here is that there are two _different drivers_ (USB host
> >>>>>>> and device). When both are modular, and the driver that depends on the
> >>>>>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
> >>>>>>> must not be done when the first driver is already using the hardware.
> >>>>>>>
> >>>>>>> Hence the sysctrl driver should take care of it itself during early
> >>>>>>> initialization (it's the main clock controller, so it's a dependency
> >>>>>>> for all other I/O device drivers).    
> >>>>>>
> >>>>>> I assumed you have there bit for the first device (which can switch
> >>>>>> between USB host and USB device) to choose appropriate mode. The
> >>>>>> bindings also expressed this - "the USBs are". Never said anything about
> >>>>>> dependency between these USBs.
> >>>>>>
> >>>>>> Are you saying that the mode for first device cannot be changed once the
> >>>>>> second device (which is only host) is started? IOW, the mode setup must
> >>>>>> happen before any of these devices are started?
> >>>>>>
> >>>>>> Anyway with sysctrl approach you will have dependency and you cannot
> >>>>>> rely on clock provider-consumer relationship to order that dependency.
> >>>>>> What if you make all clocks on and do not take any clocks in USB device?
> >>>>>> Broken dependency. What if you want to use this in a different SoC,
> >>>>>> where the sysctrl does not provide clocks? Broken dependency.    
> >>>>>
> >>>>> The issue is really related to the Renesas sysctrl itself and not related
> >>>>> to the USB drivers themselves.
> >>>>> From the drivers themselves, the issue is not seen (I mean the driver
> >>>>> takes no specific action related to this issue).
> >>>>> If we change the SOC, the issue will probably not exist anymore.    
> >>>>
> >>>> Yeah, and in the next SoC you will bring 10 of such properties to
> >>>> sysctrl arguing that if one was approved, 10 is also fine. Somehow
> >>>> people on the lists like to use that argument - I saw it somewhere, so I
> >>>> am allowed to do here the same.    
> >>>
> >>> Like pin control properties? ;-)
> >>> This property represents a wiring on the board...
> >>> I.e. a system integration issue.
> >>>     
> >>>> I understand that the registers responsible for configuration are in
> >>>> sysctrl block, but it does not mean that it should be described as part
> >>>> of sysctrl Devicetree node. If there was no synchronization problem,
> >>>> this would be regular example of register in syscon which is handled
> >>>> (toggled) by the device (so USB device/host controller). Since there is
> >>>> synchronization problem, you argue that it is correct representation of
> >>>> hardware. No, it is not, because logically in DT you do not describe
> >>>> mode or existence of other devices in some other node and it still does
> >>>> not describe this ordering.    
> >>>
> >>> So we have to drop the property, and let the sysctrl block look
> >>> for <name>@<reg> nodes, and check which ones are enabled?
> >>>
> >>> Running out of ideas...    
> > 
> > I'm stepping in, hopefully I won't just be bikeshedding on something
> > that has already been discussed but here is my grain of salt.
> >   
> >> One solution could be making USB nodes children of the sysctrl block which:
> >> 1. Gives proper ordering (children cannot start before parent)
> >> regardless of any other shared resources,
> >> 2. Allows to drop this mode property and instead check what type of
> >> children you have and configure mode depending on them.
> >>
> >> However this also might not be correct representation of hardware
> >> (dunno...), so I am also running out of ideas.  
> > 
> > I see what you mean here, but AFAICS that is clearly a wrong
> > representation of the hardware. Sorting nodes by bus seems the aim of
> > device tree because there is a physical relationship, that's why we
> > have (i2c as an example):
> > 
> > 	ahb {
> > 		foo-controller@xxx {
> > 			reg = <xxx>;
> > 		};
> > 	};
> > 
> > But what you are describing now is conceptually closer to:
> > 
> > 	clk-controller {
> > 		foo-controller {
> > 			reg = ?
> > 		};
> > 	};  
> 
> Which is not a problem. reg can be anything - offset from sysctrl node
> or absolute offset. We have it in many places already. What's the issue
> here?
>
> > Not mentioning that this only works once, because foo-controller might
> > also need other blocks to be ready before probing and those might
> > be different blocks (they are the same in the rzn1 case, but
> > more generally, they are not).  
> 
> But what is the problem of needing other blocks? All devices need
> something and we solve it...

What I am saying is that parenting only works once. All the other
dependencies must be described by properties.

The h2mode register, no matter its content, should be set early in the
boot process, at least before any of the concerned controllers, which
are totally independent hardware blocks, probe. If one of them has
started, a change to the h2mode property could just stall the system.
The USB controllers do not *need* this property nor want to change it
(see below).

The fact that the USB controllers are totally independent hardware
blocks make me thing that they should *not* be children of the sysctrl.
In our case one of them even is a PCI device! Would you represent a PCI
device within the sysctrl node? The other is somehow memory mapped
behind a bridge. Again, this has to be described somewhere, and
parenting usually is the right fit for that.

Hence, the only real thing that remains to be described, as you
rightly pointed out in your earlier reviews, is the probe order which
is nothing related to any kind of parenting in this case.

> > So in the end I am not in favor of this
> > solution.
> > 
> > If we compare the dependency between the USB device controller and the
> > sysctrl block which contains the h2mode register to existing
> > dependencies, they are all treated with properties. These properties,
> > eg:
> > 
> > 	foo-controller {
> > 		clocks = <&provider [index]>;
> > 	};
> > 
> > were initially used to just tell the consumer which resource it should
> > grab/enable. If the device was not yet ready, we would rely on the
> > probe deferral mechanism to try again later. Not optimal, but not
> > bad either as it made things work. Since v5.11 and the addition of
> > automatic device links, the probe order is explicitly ordered.
> > <provider> could always get probed before <foo-controller>. So, isn't
> > what we need here? What about the following:
> > 
> > 	sysctrl {
> > 		h2mode = "something";
> > 	};
> > 
> > 	usb-device {
> > 		h2mode-provider = <&sysctrl>;
> > 	};  
> 
> No, because next time one will add 10 of such properties:
> sysctrl {
> 	h2mode = ""
> 	g2mode = ""
> 	i2mode = ""
> 	....
> }
> 
> and keep arguing that because these registers are in sysctrl, so they
> should have their own property in sysctrl mode.
> 
> That's not correct representation of hardware.

Actually my main focus here was more on the "sysctrl-provider" logic.
We need a probe dependency so we have two choices:
- pointing
- parenting
For the reasons above, I bet the former is the most accurate approach.

If the h2mode property bothers you, it's fine, we can just drop it. The
USB device controller can do without it:
- either it just probes without knowing the mode, its bus will remain
  empty so the device is useless, but nothing will break.
- or (this is my favorite) we add another sysctrl helper that exposes
  the h2mode, very much like we've done with the dmamux [2] and we just
  avoid probing if the mode that we receive does not ask for a USB
  device controller. Speeds-up the boot process.

[2] https://lore.kernel.org/all/20220427095653.91804-5-miquel.raynal@bootlin.com/

Either ways, we would still need the probe order to be enforced,
which might be achieved on Linux side with the below explanations.

> > We can initially just make this work with some additional logic on both
> > sides. The USB device controller would manually check whether sysctrl
> > has been probed or not (in practice, because of the clocks and power
> > domains being described this will always be a yes, but IIUC we want to
> > avoid relying on it) and otherwise, defer its probe. On the sysctrl side
> > it is just a matter of checking (like we already do):
> > 
> > 	if (!sysctrl_priv)
> > 		return -EPROBE_DEFER;
> > 
> > To be honest I would love to see the device link mechanism extended to
> > "custom" phandle properties like that, it would avoid the burden of
> > checking for deferrals manually, aside with boot time improvements. If
> > we go this way, we shall decide whether we want to:
> > * extend the list of properties that will lead to a dependency creation [1]
> > * or maybe settle on a common suffix that could always be used,
> >   especially for specific cases like this one where there is an
> >   explicit provider-consumer dependency that must be fulfilled:
> > 
> > 	DEFINE_SUFFIX_PROP(provider, "-provider", "#provider-cells")
> > 
> > * or perhaps extend struct of_device_id to contain the name of the
> >   properties pointing to phandles that describe probe dependencies with:
> > 
> > 	char *provider_prop_name;
> > 	char *provider_cells_prop_name;
> > 
> >   and use them from of/property.c to generate the links when relevant.
> > 
> > [1] https://elixir.bootlin.com/linux/v6.0/source/drivers/of/property.c#L1298
> > 
> > 
> > Thanks,
> > Miquèl  
> 
> Best regards,
> Krzysztof
> 

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property
  2022-11-24 10:27                                         ` Miquel Raynal
@ 2022-11-24 10:44                                           ` Miquel Raynal
  0 siblings, 0 replies; 47+ messages in thread
From: Miquel Raynal @ 2022-11-24 10:44 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Herve Codina, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Magnus Damm, Gareth Williams,
	linux-renesas-soc, linux-clk, devicetree, linux-kernel,
	linux-usb, Thomas Petazzoni

Hi Krzysztof,

miquel.raynal@bootlin.com wrote on Thu, 24 Nov 2022 11:27:57 +0100:

> Hi Krzysztof,
> 
> krzysztof.kozlowski@linaro.org wrote on Thu, 24 Nov 2022 10:46:14 +0100:
> 
> > On 24/11/2022 10:36, Miquel Raynal wrote:
> > > Hi Krzysztof,
> > > 
> > > krzysztof.kozlowski@linaro.org wrote on Wed, 23 Nov 2022 10:39:41 +0100:
> > >   
> > >> On 22/11/2022 11:47, Geert Uytterhoeven wrote:  
> > >>> Hi Krzysztof,
> > >>>
> > >>> On Tue, Nov 22, 2022 at 11:30 AM Krzysztof Kozlowski
> > >>> <krzysztof.kozlowski@linaro.org> wrote:    
> > >>>> On 22/11/2022 10:07, Herve Codina wrote:    
> > >>>>> On Tue, 22 Nov 2022 09:42:48 +0100
> > >>>>> Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> wrote:
> > >>>>>    
> > >>>>>> On 22/11/2022 09:25, Geert Uytterhoeven wrote:    
> > >>>>>>> Hi Krzysztof,
> > >>>>>>>
> > >>>>>>> On Tue, Nov 22, 2022 at 8:45 AM Krzysztof Kozlowski
> > >>>>>>> <krzysztof.kozlowski@linaro.org> wrote:    
> > >>>>>>>> On 21/11/2022 21:46, Geert Uytterhoeven wrote:    
> > >>>>>>>>>> This does not change anything. Herve wrote:
> > >>>>>>>>>>    
> > >>>>>>>>>>> probe some devices (USB host and probably others)    
> > >>>>>>>>>>
> > >>>>>>>>>> Why some can be probed earlier and some not, if there are no
> > >>>>>>>>>> dependencies? If there are dependencies, it's the same case with sysctrl
> > >>>>>>>>>> touching the register bit and the USB controller touching it (as well
> > >>>>>>>>>> via syscon, but that's obvious, I assume).
> > >>>>>>>>>>
> > >>>>>>>>>> Where is the synchronization problem?    
> > >>>>>>>>>
> > >>>>>>>>> The h2mode bit (and probably a few other controls we haven't figured out
> > >>>>>>>>> yet) in the sysctrl must be set before any of the USB devices is active.
> > >>>>>>>>> Hence it's safest for the sysctrl to do this before any of the USB drivers
> > >>>>>>>>> probes.    
> > >>>>>>>>
> > >>>>>>>> Again, this does not differ from many, many of other devices. All of
> > >>>>>>>> them must set something in system controller block, before they start
> > >>>>>>>> operating (or at specific time). It's exactly the same everywhere.    
> > >>>>>>>
> > >>>>>>> The issue here is that there are two _different drivers_ (USB host
> > >>>>>>> and device). When both are modular, and the driver that depends on the
> > >>>>>>> sysctrl setting is loaded second, you have a problem: the sysctrl change
> > >>>>>>> must not be done when the first driver is already using the hardware.
> > >>>>>>>
> > >>>>>>> Hence the sysctrl driver should take care of it itself during early
> > >>>>>>> initialization (it's the main clock controller, so it's a dependency
> > >>>>>>> for all other I/O device drivers).    
> > >>>>>>
> > >>>>>> I assumed you have there bit for the first device (which can switch
> > >>>>>> between USB host and USB device) to choose appropriate mode. The
> > >>>>>> bindings also expressed this - "the USBs are". Never said anything about
> > >>>>>> dependency between these USBs.
> > >>>>>>
> > >>>>>> Are you saying that the mode for first device cannot be changed once the
> > >>>>>> second device (which is only host) is started? IOW, the mode setup must
> > >>>>>> happen before any of these devices are started?
> > >>>>>>
> > >>>>>> Anyway with sysctrl approach you will have dependency and you cannot
> > >>>>>> rely on clock provider-consumer relationship to order that dependency.
> > >>>>>> What if you make all clocks on and do not take any clocks in USB device?
> > >>>>>> Broken dependency. What if you want to use this in a different SoC,
> > >>>>>> where the sysctrl does not provide clocks? Broken dependency.    
> > >>>>>
> > >>>>> The issue is really related to the Renesas sysctrl itself and not related
> > >>>>> to the USB drivers themselves.
> > >>>>> From the drivers themselves, the issue is not seen (I mean the driver
> > >>>>> takes no specific action related to this issue).
> > >>>>> If we change the SOC, the issue will probably not exist anymore.    
> > >>>>
> > >>>> Yeah, and in the next SoC you will bring 10 of such properties to
> > >>>> sysctrl arguing that if one was approved, 10 is also fine. Somehow
> > >>>> people on the lists like to use that argument - I saw it somewhere, so I
> > >>>> am allowed to do here the same.    
> > >>>
> > >>> Like pin control properties? ;-)
> > >>> This property represents a wiring on the board...
> > >>> I.e. a system integration issue.
> > >>>     
> > >>>> I understand that the registers responsible for configuration are in
> > >>>> sysctrl block, but it does not mean that it should be described as part
> > >>>> of sysctrl Devicetree node. If there was no synchronization problem,
> > >>>> this would be regular example of register in syscon which is handled
> > >>>> (toggled) by the device (so USB device/host controller). Since there is
> > >>>> synchronization problem, you argue that it is correct representation of
> > >>>> hardware. No, it is not, because logically in DT you do not describe
> > >>>> mode or existence of other devices in some other node and it still does
> > >>>> not describe this ordering.    
> > >>>
> > >>> So we have to drop the property, and let the sysctrl block look
> > >>> for <name>@<reg> nodes, and check which ones are enabled?
> > >>>
> > >>> Running out of ideas...    
> > > 
> > > I'm stepping in, hopefully I won't just be bikeshedding on something
> > > that has already been discussed but here is my grain of salt.
> > >   
> > >> One solution could be making USB nodes children of the sysctrl block which:
> > >> 1. Gives proper ordering (children cannot start before parent)
> > >> regardless of any other shared resources,
> > >> 2. Allows to drop this mode property and instead check what type of
> > >> children you have and configure mode depending on them.
> > >>
> > >> However this also might not be correct representation of hardware
> > >> (dunno...), so I am also running out of ideas.  
> > > 
> > > I see what you mean here, but AFAICS that is clearly a wrong
> > > representation of the hardware. Sorting nodes by bus seems the aim of
> > > device tree because there is a physical relationship, that's why we
> > > have (i2c as an example):
> > > 
> > > 	ahb {
> > > 		foo-controller@xxx {
> > > 			reg = <xxx>;
> > > 		};
> > > 	};
> > > 
> > > But what you are describing now is conceptually closer to:
> > > 
> > > 	clk-controller {
> > > 		foo-controller {
> > > 			reg = ?
> > > 		};
> > > 	};  
> > 
> > Which is not a problem. reg can be anything - offset from sysctrl node
> > or absolute offset. We have it in many places already. What's the issue
> > here?
> >
> > > Not mentioning that this only works once, because foo-controller might
> > > also need other blocks to be ready before probing and those might
> > > be different blocks (they are the same in the rzn1 case, but
> > > more generally, they are not).  
> > 
> > But what is the problem of needing other blocks? All devices need
> > something and we solve it...
> 
> What I am saying is that parenting only works once. All the other
> dependencies must be described by properties.
> 
> The h2mode register, no matter its content, should be set early in the
> boot process, at least before any of the concerned controllers, which
> are totally independent hardware blocks, probe. If one of them has
> started, a change to the h2mode property could just stall the system.
> The USB controllers do not *need* this property nor want to change it
> (see below).
> 
> The fact that the USB controllers are totally independent hardware
> blocks make me thing that they should *not* be children of the sysctrl.
> In our case one of them even is a PCI device! Would you represent a PCI
> device within the sysctrl node? The other is somehow memory mapped
> behind a bridge. Again, this has to be described somewhere, and
> parenting usually is the right fit for that.
> 
> Hence, the only real thing that remains to be described, as you
> rightly pointed out in your earlier reviews, is the probe order which
> is nothing related to any kind of parenting in this case.
> 
> > > So in the end I am not in favor of this
> > > solution.
> > > 
> > > If we compare the dependency between the USB device controller and the
> > > sysctrl block which contains the h2mode register to existing
> > > dependencies, they are all treated with properties. These properties,
> > > eg:
> > > 
> > > 	foo-controller {
> > > 		clocks = <&provider [index]>;
> > > 	};
> > > 
> > > were initially used to just tell the consumer which resource it should
> > > grab/enable. If the device was not yet ready, we would rely on the
> > > probe deferral mechanism to try again later. Not optimal, but not
> > > bad either as it made things work. Since v5.11 and the addition of
> > > automatic device links, the probe order is explicitly ordered.
> > > <provider> could always get probed before <foo-controller>. So, isn't
> > > what we need here? What about the following:
> > > 
> > > 	sysctrl {
> > > 		h2mode = "something";
> > > 	};
> > > 
> > > 	usb-device {
> > > 		h2mode-provider = <&sysctrl>;
> > > 	};  
> > 
> > No, because next time one will add 10 of such properties:
> > sysctrl {
> > 	h2mode = ""
> > 	g2mode = ""
> > 	i2mode = ""
> > 	....
> > }
> > 
> > and keep arguing that because these registers are in sysctrl, so they
> > should have their own property in sysctrl mode.
> > 
> > That's not correct representation of hardware.
> 
> Actually my main focus here was more on the "sysctrl-provider" logic.
> We need a probe dependency so we have two choices:
> - pointing
> - parenting
> For the reasons above, I bet the former is the most accurate approach.
> 
> If the h2mode property bothers you, it's fine, we can just drop it. The
> USB device controller can do without it:

I'm partially wrong here. I forgot that we somehow need to know whether
the second USB controller is host or device, and decide this before the
USB controllers probe. It is still possible to do it without the
property by looking up the tree against the USB controller
compatible or node name. We would do this in the sysctrl probe and set
the right mode depending on its presence.

I would definitely go for a property instead, but if this is a no-go, I
guess that's the last resort.

> - either it just probes without knowing the mode, its bus will remain
>   empty so the device is useless, but nothing will break.
> - or (this is my favorite) we add another sysctrl helper that exposes
>   the h2mode, very much like we've done with the dmamux [2] and we just
>   avoid probing if the mode that we receive does not ask for a USB
>   device controller. Speeds-up the boot process.
> 
> [2] https://lore.kernel.org/all/20220427095653.91804-5-miquel.raynal@bootlin.com/
> 
> Either ways, we would still need the probe order to be enforced,
> which might be achieved on Linux side with the below explanations.
> 
> > > We can initially just make this work with some additional logic on both
> > > sides. The USB device controller would manually check whether sysctrl
> > > has been probed or not (in practice, because of the clocks and power
> > > domains being described this will always be a yes, but IIUC we want to
> > > avoid relying on it) and otherwise, defer its probe. On the sysctrl side
> > > it is just a matter of checking (like we already do):
> > > 
> > > 	if (!sysctrl_priv)
> > > 		return -EPROBE_DEFER;
> > > 
> > > To be honest I would love to see the device link mechanism extended to
> > > "custom" phandle properties like that, it would avoid the burden of
> > > checking for deferrals manually, aside with boot time improvements. If
> > > we go this way, we shall decide whether we want to:
> > > * extend the list of properties that will lead to a dependency creation [1]
> > > * or maybe settle on a common suffix that could always be used,
> > >   especially for specific cases like this one where there is an
> > >   explicit provider-consumer dependency that must be fulfilled:
> > > 
> > > 	DEFINE_SUFFIX_PROP(provider, "-provider", "#provider-cells")
> > > 
> > > * or perhaps extend struct of_device_id to contain the name of the
> > >   properties pointing to phandles that describe probe dependencies with:
> > > 
> > > 	char *provider_prop_name;
> > > 	char *provider_cells_prop_name;
> > > 
> > >   and use them from of/property.c to generate the links when relevant.
> > > 
> > > [1] https://elixir.bootlin.com/linux/v6.0/source/drivers/of/property.c#L1298
> > > 
> > > 
> > > Thanks,
> > > Miquèl  
> > 
> > Best regards,
> > Krzysztof
> > 
> 
> Thanks,
> Miquèl


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2022-11-24 10:44 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-14 11:15 [PATCH v2 0/7] Add the Renesas USBF controller support Herve Codina
2022-11-14 11:15 ` [PATCH v2 1/7] soc: renesas: r9a06g032-sysctrl: Export function to get the usb role Herve Codina
2022-11-14 13:33   ` Geert Uytterhoeven
2022-11-14 11:15 ` [PATCH v2 2/7] dt-bindings: clock: renesas,r9a06g032-sysctrl: Add h2mode property Herve Codina
2022-11-14 13:33   ` Geert Uytterhoeven
2022-11-15 13:05   ` Krzysztof Kozlowski
2022-11-15 13:07     ` Krzysztof Kozlowski
2022-11-15 14:04       ` Herve Codina
2022-11-18 10:23         ` Herve Codina
2022-11-21 11:43           ` Krzysztof Kozlowski
2022-11-21 15:59             ` Herve Codina
2022-11-21 16:33               ` Krzysztof Kozlowski
2022-11-21 16:36                 ` Geert Uytterhoeven
2022-11-21 17:11                   ` Krzysztof Kozlowski
2022-11-21 20:46                     ` Geert Uytterhoeven
2022-11-22  7:45                       ` Krzysztof Kozlowski
2022-11-22  8:25                         ` Geert Uytterhoeven
2022-11-22  8:42                           ` Krzysztof Kozlowski
2022-11-22  9:01                             ` Geert Uytterhoeven
2022-11-22 10:23                               ` Krzysztof Kozlowski
2022-11-22 10:26                                 ` Geert Uytterhoeven
2022-11-22 10:34                                   ` Krzysztof Kozlowski
2022-11-22  9:07                             ` Herve Codina
2022-11-22 10:30                               ` Krzysztof Kozlowski
2022-11-22 10:47                                 ` Geert Uytterhoeven
2022-11-23  9:39                                   ` Krzysztof Kozlowski
2022-11-24  9:36                                     ` Miquel Raynal
2022-11-24  9:46                                       ` Krzysztof Kozlowski
2022-11-24 10:27                                         ` Miquel Raynal
2022-11-24 10:44                                           ` Miquel Raynal
2022-11-14 11:15 ` [PATCH v2 3/7] soc: renesas: r9a06g032-sysctrl: Handle h2mode device-tree property Herve Codina
2022-11-14 13:32   ` Geert Uytterhoeven
2022-11-14 11:15 ` [PATCH v2 4/7] dt-bindings: usb: add the Renesas RZ/N1 USBF controller binding Herve Codina
2022-11-15 13:13   ` Krzysztof Kozlowski
2022-11-15 13:29     ` Herve Codina
2022-11-14 11:15 ` [PATCH v2 5/7] usb: gadget: udc: add Renesas RZ/N1 USBF controller support Herve Codina
2022-11-14 11:15 ` [PATCH v2 6/7] ARM: dts: r9a06g032: Add the USBF controller node Herve Codina
2022-11-15 13:16   ` Krzysztof Kozlowski
2022-11-15 13:27     ` Herve Codina
2022-11-15 15:09       ` Herve Codina
2022-11-15 16:30         ` Krzysztof Kozlowski
2022-11-15 14:11     ` Geert Uytterhoeven
2022-11-15 14:58       ` Krzysztof Kozlowski
2022-11-16  8:51   ` Geert Uytterhoeven
2022-11-14 11:15 ` [PATCH v2 7/7] MAINTAINERS: add the Renesas RZ/N1 USBF controller entry Herve Codina
2022-11-15 12:20   ` kernel test robot
2022-11-15 13:24     ` Herve Codina

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.